Prinzipien

Volltext-Suche: Datenmodell
Voll­text-Suche: Daten­mo­dell

Volltext-Suche: Relationales Datenbankschema
Voll­text-Suche: Rela­tio­na­les Daten­bank­sche­ma

Beach­ten Sie, dass der For­eign Key w_id in der Tabel­le volltextindex nicht auf den Pri­mär­schlüs­sel word der Tabel­le woerterbuch ver­weist, son­dern auf das Nicht-PK-Attri­but w_id. Der Grund ist, dass ver­schie­de­ne Wör­ter durch­aus die­sel­be ID haben kön­nen, wenn es sich um Syn­ony­me han­delt, wie z.B. „Cou­sin“ und „Vet­ter“. Daher kannw_id gar nicht Pri­ma­ry Key sein. Ande­rer­seit kommt jedes Wort höchs­tens ein­mal im Wör­ter­buch­vor.

Die­se Art von For­eign Keys wird von SQL nicht unter­stützt, daher ist der ent­spre­chen­de Pfeil auch nur gestri­chelt mar­kiert wor­den. (Man könn­te die­se Art von For­eign Key aller­dings mit einem Cons­traint-Trig­ger rea­li­sie­ren. Im Bei­spiel wur­de dies jedoch bis­lang nicht gemacht.)

Prin­zi­pi­ell funk­tio­niert eine Voll­text­su­che fol­gen­der­ma­ßen:

  1. Der Benut­zer gibt ein oder meh­re­re Wör­ter an, nach denen gesucht wer­den soll.
  2. Im Voll­text­in­dex wer­den die IDs der zu suchen­den Wör­ter ermit­telt. Das geht sehr schnell, da der Pri­ma­ry Index für die Wör­ter selbst (und nicht für die zuge­hö­ri­gen IDs) defi­niert wur­de.
  3. Wenn der Benut­zer die Suche auf bestimm­te Attri­bu­te ein­schrän­ken möch­te, kann er auch noch die gewünsch­ten Attri­but­na­men ange­ben. Für die­se wer­den in der Tabel­le attribut eben­falls die zuge­hö­ri­gen IDs ermit­telt. (Hier sind kei­ne For­eign-Key-Trick­se­rei­en not­wen­dig, da es sicher nicht mehr als ein paar Dut­zend Doku­ment-Attri­bu­te geben wird, so dass die­se Fra­ge immer schnell beant­wor­tet wer­den kann.)
  4. Die so ermit­tel­ten Wort-IDs wer­den gemein­sam mit den Attri­but-IDs (sofern wel­che für die Suche ange­ge­ben wur­den) im Voll­text­in­dex gesucht. Damit dies per­for­mant geschieht, ist es ganz wich­tig, die Pri­mär­schlüs­selat­tri­bu­te in der rich­ti­gen Rei­hen­fol­ge anzu­ge­ben:
    PRIMARY KEY (wid, aid, pos, did)
  5. Die so gefun­de­nen Doku­ment-IDs füh­ren schließ­lich zu den Doku­men­ten, die die gewünsch­ten Wör­ter ent­hal­ten.

Anmer­kung: Das Posi­ti­ons­at­tri­but pos bezeich­net die Posi­ti­on eines Wor­tes in einem Doku­ment. Damit lässt sich eine soge­nann­te Phra­sen­su­che rea­li­sie­ren, bei der die rela­ti­ve Posi­ti­on der Such­wor­te zuein­an­der berück­sich­tigt wird. Außer­dem könn­te damit die Rele­vanz von Wör­tern in einem Text  defi­niert wer­den (Wei­ter vor­ne im Text = höhe­re Rele­vanz; häu­fi­ge­res Auf­tre­ten im Text = höhe­re Rele­vanz; häu­fi­ges Auf­tre­ten in vie­len Tex­ten = gerin­ge Relevanz/​Stopwort).

Die Attri­but-Tabel­le ent­hält nur ein paar weni­ge Tupel. Das Wör­ter­buch kann sehr groß wer­den (evtl. sogar eine sie­ben­stel­li­ge Anzahl). Am größ­ten wird jedoch der Voll­text­in­dex. Wenn ein Doku­ment im Durch­schnitt aus n Wör­ten besteht, ent­hält der Index n mal sovie­le Tupel, wie Doku­men­te in der Daten­bank ent­hal­ten sind. Die grö­ße des Wör­ter­buchs hängt dage­gen von der Anzahl der unter­schied­li­chen Wör­ter ab, die in den Doku­men­ten ent­hal­ten sind.

Fazit: So ein Voll­text­in­dex wird sehr schnell sehr groß.

fulltext-create.sql(Erzeu­gung der Daten­bank)
fulltext-query.sql(Bei­spielsan­fra­gen)

Volltextsuche in Postgres

Post­gres bie­tet eine eige­ne, pro­prie­tä­re Voll­text­su­che an (sie ist also nicht SQL-stan­dard­kon­form). Vom obi­gen Modell wird nur die Tabel­le document benö­tigt. In die­se Tabel­le kön­nen zusätz­li­che Attri­bu­te ein­ge­fügt wer­den, die den Voll­text des jewei­li­gen Modells auf die ein oder ande­re Wei­se ent­hal­ten. Für die­se Attri­bu­te kön­nen mit Hil­fe des SQL-Befehls CREATE INDEX pas­sen­de Voll­text­in­de­xe erstellt wer­den.

Ein der­ar­ti­ger Index ent­hält im Prin­zip die­sel­ben Daten, wie sie im obi­gen Bei­spiel in SQL-Tabel­len abge­spei­chert wur­den. Die wesent­li­che Unter­schie­de zum obi­gen Bei­spiel sind: Ers­tens kann der Benut­zer nicht direkt auf die Index­daten zugrei­fen; zwei­tens for­mu­liert er sei­ne Anfra­gen nicht in SQL, son­dern in einer post­gres-spe­zi­fi­schen Voll­text-Que­ry-Syn­tax.

fulltext-create.sql(Erzeu­gung der Daten­bank)
postgres.sql(Erwei­te­rung der Tabel­le dokument und Bei­spielsan­fra­gen)

Fehlertolerante phonetische Suche

fulltext-create.sql(Erzeu­gung der Daten­bank)
phonet.sql(Erwei­te­rung der Tabel­le dokument und Bei­spielsan­fra­gen)