Bietet Rezepte, Lösungen und ausführliche Beispiele rund um gesundes SQL und zufriedene Datenbanken.
Von diversen Textverarbeitungen kennt man ja Wortsynonyme als Auswahlliste. Wie könnte das benötigte Datendesign dazu aussehen?
* IBM DB2 9.1
* MySQL 5.1.30
Die Datenbank-Tabellen hierfür sehen wie folgt aus:
/**
* Worte
*/
CREATE TABLE wort (
wort_id INT NOT NULL,
wort VARCHAR(50),
PRIMARY KEY (wort_id)
);
/**
* Wortsynonyme / Thesaurus
*/
CREATE TABLE wort_synonym (
wort_synonym_id INT NOT NULL,
wort_synonym_gruppe INT NOT NULL,
wort_id INT NOT NULL,
PRIMARY KEY (wort_synonym_id),
CONSTRAINT fk_wort_01
FOREIGN KEY (wort_id)
REFERENCES wort (wort_id)
);
Damit die SQL-Abfragen auch bei einer größeren Datenmenge schnell und performant von der Datenbank abgearbeitet werden können, benötigen wir noch diese Indices.
/**
* Indices
*/
CREATE INDEX sx_wort_01 ON wort (wort, wort_id);
CREATE INDEX sx_wort_synonym_01 ON wort_synonym (wort_synonym_gruppe,wort_id);
Nun die Wortlisten und die Synonym-Gruppen, um die SQL-Abfrage des Thesaurus zu testen. Es gibt zwei Gruppen computer und bildschirm mit jeweils fünf Wörtern.
/**
* Worte einfügen
*/
INSERT INTO wort VALUES
( 1, 'computer'),
( 2, 'blechidiot'),
( 3, 'datenverarbeitungsanlage'),
( 4, 'elektronengehirn'),
( 5, 'rechner'),
( 6, 'bildschirm'),
( 7, 'anzeigegerät'),
( 8, 'display'),
( 9, 'monitor'),
(10, 'schirm');
/**
* Thesaurus-Gruppen
*/
INSERT INTO wort_synonym VALUES
( 1, 1, 1),
( 2, 1, 2),
( 3, 1, 3),
( 4, 1, 4),
( 5, 1, 5),
( 6, 2, 6),
( 7, 2, 7),
( 8, 2, 8),
( 9, 2, 9),
(10, 2,10);
Hier nun die SQL-Abfrage, die zu einem bestimmen Wort (z.B. blechidiot) alle alternativen Worte aus dieser Synonymgruppe herausfindet. Ein Problem dabei ist, dass das Suchwort sich nicht auch in der Ergebnismenge befindet. Das Suchwort soll sich nicht selbst finden.
/**
* Synonyme finden
*/
SELECT w2.wort AS synonym
FROM wort w
JOIN wort_synonym ws
ON ws.wort_id = w.wort_id
JOIN wort_synonym ws2
ON ws2.wort_synonym_gruppe = ws.wort_synonym_gruppe
AND ws2.wort_id <> ws.wort_id
JOIN wort w2
ON w2.wort_id = ws2.wort_id
WHERE w.wort = 'blechidiot'
ORDER BY w2.wort;
Diese SQL-Abfrage liefert jetzt alle alternativen Worte zu blechidiot entsprechen der hinterlegten Wortgruppe (siehe Spalte wort_synonym_gruppe).
+--------------------------+
| synonym |
+--------------------------+
| computer |
| datenverarbeitungsanlage |
| elektronengehirn |
| rechner |
+--------------------------+
4 rows in set (0.01 sec)
Die SQL-Abfrage (siehe Listing 4:) ist bewußt einfach gehalten. Auf die Problematiken der Groß- und Kleinschreibung bin ich diesmal nicht eingegangen.