7 Stimmen

Benötige Muster für die dynamische Suche in mehreren Sql-Tabellen

Ich bin auf der Suche nach einem Muster für die Durchführung einer dynamischen Suche in mehreren Tabellen.

Ich habe keine Kontrolle über die veraltete (und schlecht konzipierte) Tabellenstruktur der Datenbank.

Stellen Sie sich ein ähnliches Szenario wie bei einer Lebenslaufsuche vor, bei der ein Benutzer eine Suche nach beliebigen Daten im Lebenslauf durchführen und eine Liste von Lebensläufen zurückerhalten möchte, die seinen Suchkriterien entsprechen. Jedes Feld kann jederzeit und in Kombination mit einem oder mehreren anderen Feldern durchsucht werden.

Die eigentliche Sql-Abfrage wird dynamisch erstellt, je nachdem, welche Felder durchsucht werden. Die meisten Lösungen, die ich gefunden habe, beinhalten komplizierte if-Blöcke, aber ich kann nicht helfen, aber ich denke, es muss eine elegantere Lösung sein, da dies ein gelöstes Problem jetzt sein muss.


Ja, so habe ich den Weg der dynamischen Erstellung der Sql im Code begonnen. Scheint grässlich. Wenn ich wirklich versuche, die angeforderte Fähigkeit zu unterstützen, jede Kombination von jedem Feld in jeder Tabelle abzufragen, wird dies eine MASSIVE Reihe von if-Anweisungen sein. Zittern


Ich glaube, ich habe gelesen, dass COALESCE nur funktioniert, wenn Ihre Daten keine NULLs enthalten. Ist das richtig? Wenn ja, geht es nicht, da ich überall NULL-Werte habe.

5voto

Soweit ich weiß (und ich bin auch jemand, der gegen eine schreckliche Legacy-Datenbank geschrieben hat), gibt es so etwas wie dynamische WHERE-Klauseln nicht. Das Problem wurde NICHT gelöst.

Ich persönlich ziehe es vor, meine dynamischen Suchvorgänge im Code zu erstellen. Das macht das Testen einfacher. Wenn Sie Ihre SQL-Abfragen im Code erstellen, sollten Sie keine Benutzereingaben einfügen. Verwenden Sie Ihre @Variablen!

Die einzige Alternative ist die Verwendung des COALESCE-Operators. Nehmen wir an, Sie haben die folgende Tabelle:

Users
-----------
Name nvarchar(20)
Nickname nvarchar(10)

und Sie wollen wahlweise nach Namen oder Spitznamen suchen. Die folgende Abfrage wird dies tun:

SELECT Name, Nickname
FROM Users
WHERE
    Name = COALESCE(@name, Name) AND
    Nickname =  COALESCE(@nick, Nickname)

Wenn Sie nicht nach etwas suchen wollen, geben Sie einfach eine Null ein. Wenn Sie zum Beispiel "brian" für @name und null für @nick eingeben, wird die folgende Abfrage ausgewertet:

SELECT Name, Nickname
FROM Users
WHERE
    Name = 'brian' AND
    Nickname =  Nickname

Der Koaleszenzoperator verwandelt die Null in eine Identitätsauswertung, die immer wahr ist und die Where-Klausel nicht beeinflusst.

1voto

DevelopingChris Punkte 38437

Suche und Normalisierung können im Widerspruch zueinander stehen. So wahrscheinlich erste Sache wäre, um eine Art von "Ansicht", die alle Felder, die als eine einzige Zeile mit einem einzigen Schlüssel immer Sie den Lebenslauf durchsucht werden kann, zeigt zu bekommen. dann können Sie etwas wie Lucene davor, um Ihnen einen Volltextindex dieser Zeilen zu geben. Das funktioniert so, dass Sie nach "x" in dieser Ansicht fragen und der Schlüssel zurückgegeben wird. Seine eine große Lösung und kommen von Joel selbst auf dem Podcast innerhalb der ersten 2 Monate IIRC empfohlen.

1voto

elviejo79 Punkte 4572

Was Sie brauchen, ist etwas wie SphinxSuche (für MySQL) oder Apache Lucene .

Wie Sie in Ihrem Beispiel sagten, stellen wir uns einen Lebenslauf vor, der aus mehreren Feldern besteht:

  • Posten auflisten
  • Name,
  • Adreess,
  • Bildung (dies könnte eine eigenständige Tabelle sein) oder
  • Berufserfahrung (dies könnte eine eigene Tabelle werden, in der jede Zeile eine frühere Tätigkeit darstellt)

So wird die Suche nach einem Wort in all diesen Feldern mit WHERE schnell zu einer sehr langen Abfrage mit mehreren JOINS.

Stattdessen könnten Sie Ihren Bezugsrahmen ändern und den gesamten Lebenslauf als ein einziges Dokument betrachten, das Sie lediglich durchsuchen möchten.

Dies ist, wo Werkzeuge wie Sphinx Search tun. Sie erstellen einen VOLLTEXT-Index Ihres "Dokuments" und dann können Sie Sphinx abfragen und es gibt Ihnen zurück, wo in der Datenbank dieser Datensatz gefunden wurde.

Wirklich gute Suchergebnisse.

Machen Sie sich keine Sorgen darüber, dass diese Tools nicht Teil Ihres RDBMS sind. Es wird Ihnen viel Kopfzerbrechen ersparen, wenn Sie das richtige Modell "Dokumente" gegenüber dem falschen Modell "TABLES" für diese Anwendung verwenden.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X