Zur Navigation

Doppelte Einträge in normalisierte Datenbanktabellen vermeiden

1 Ranma (Gast)

Hallo. Ich habe mir den XML-Dump vom Wiktionary geholt. Der ist fast 850 MByte groß. Außerdem habe ich drei neue MySQL-Tabellen angelegt, um sie mit den Daten aus dem XML-Dump zu füllen und so einen Versuch, ein Wörterbuch zu bauen, zu unternehmen. Dieses Mal sind die Tabellen gleich von Anfang an in Normalform (also eine Tabelle für das eigentliche Wort, eine für zusätzliche Informationen zum Wort und eine für die Kombinationen zur Übersetzung). Dazu habe ich noch ein PHP-Skript, das den XML-Dump in Blöcken von <page> bis </page> auswertet, die relevanten Elemente in einen String packt und den an eine Stored Procedure sendet. So soll es jedenfalls funktioneren. An der Stored Procedure fehlt auch nur noch eine Sache. Die Stored Procedure nimmt den String (besser wäre natürlich ein assoziatives Array, aber das geht nunmal nicht mit SQL) wieder auseinander und verteilt die Elemente dann auf die Datenbanktabellen.

Die Sache, die noch fehlt, ist das Vermeiden doppelter Einträge. Bei einer nichtnormalisierten, einzelnen Datenbanktabelle hätte ein einfaches SELECT Klarheit geschaffen. Mit normalisierten Tabellen ist das komplizierter. Wahrscheinlich hat Wiktionary nur eine Seite pro Wort. Deswegen darf sich die Fallunterscheidung auf die möglichen Übersetzungen beschränken. Die werden im XML-Dump gegebenenfalls wiederholt und nicht referenziert.

Ich vermute, daß es eine Abfrage mit JOIN erfordert, ähnlich wie wenn das fertige Wörterbuch abgefragt würde. Aber Letzteres ist leichter, weil dann einfach nur alles ausgegeben werden muß, was vorhanden ist. Vor dem Eintragen muß ich unterscheiden zwischen noch nicht vorhanden, exakt so vorhanden, Homonym. Beim Homonym ist der Eintrag zwar vorhanden, aber es ist trotzdem nicht das gleiche Wort. Das läßt sich nur an den Zusatzeinträgen in der Tabelle für die Zusätze erkennen. Da ist aber wiederum jeder einzelne Eintrag optional. Es könnte sogar sein, daß das gleiche Wort mal in der XML-Datei eine Anmerkung mit sich führt und in einem anderem Fall nicht. Je nach dem Ersteller der entsprechenden Wiktionary-Seite. Es wäre schade auf solche Anmerkungen zu verzichten. Das macht die Abfrage schwierig, weil bei vielen AND im WHERE-Teil wird ein Eintrag mit zu wenigen optionalen Einträgen wahrscheinlich nicht gefunden. Mehrere Zusätze aus der selben Tabelle wären natürlich auch abzufragen, was mich vor ein weiteres Rätsel stellt, weil beim JOIN doch gleich viele Werte vorhanden sein müssen? Der WHERE-Teil stattdessen mit OR gebaut stellt nicht sicher, daß es sich um das gleiche Wort handelt.

Wie kann ich also herausfinden, ob ein Wort schon eingetragen ist, aber der Eintrag nicht bloß ein Homonym ist? (Aussprache, Anmerkungen, Grammatik befindet sich alles in der Tabelle Zusatz und kann immer auch fehlen.)
Ranma

06.05.2016 03:23

2 Jörg

Das Problem fängt ja schon damit an, zu definieren, wann zwei Wörter überhaupt Homonyme sind, und wann es sich nur um zwei Polyseme handelt, siehe hierzu auch Wikipedia:

https://de.wikipedia.org/wiki/Homonym#Abgrenzung_zur_Polysemie

Beim Homonym ist der Eintrag zwar vorhanden, aber es ist trotzdem nicht das gleiche Wort. Das läßt sich nur an den Zusatzeinträgen in der Tabelle für die Zusätze erkennen.

Das lässt sich aber nicht automatisieren - oder finden sich im Wictionary-Dump Kennzeichen, über die man zweifelsfrei auf eine Homonymität schließen kann (im Gegensatz zur Polysemie)?

06.05.2016 17:03

3 Ranma (Gast)

Das Wiktionary ist zwar in erster Linie ein etymologisches Wörterbuch, aber ich erstelle nur mit Hilfe der Übersetzungshinweise im Wiktionary ein multilinguales Fremdwörterbuch. Das Gleiche, was ich schonmal mit den Dateien vom FreeDict-Projekt versuchte. Inzwischen werde ich mit den Nachteilen des XML-Dumps wie einer viel zu großen Datei fertig und kann ihre Vorteile nutzen wie alle Daten relativ einheitlich in nur einer Datei zu haben. Für ein Fremdwörterbuch ist der Unterschied zwischen Polysemie und Homonymie irrelevant. Wichtig ist, ob ein Wort zusammen mit allen Zusätzen nur einmal vorkommt.

Eine Lösung dafür wäre vielleicht ein UNIQUE INDEX über mehrere Spalten. Aber geht das über mehrere Tabellen hinweg? Falls das geht und ich das mache, dann hätte ich jedoch sofort wieder ein neues Problem. Diejenigen Werte, die dann nicht eingetragen werden, sind zwar schon vorhanden, aber deren ID würde nicht zurückgeliefert, sondern nur der Eintrag verworfen. Ich bräuchte dann aber die ID des schon vorhandenen Wertes, um die Verknüpfung herzustellen.

Suchen und umsortieren wie bei meinem früherem Versuch kommt nicht in Frage, weil das ewig und drei Tage dauert. Genau das will ich mit dem neuen Versuch vermeiden.
Ranma

07.05.2016 01:56

4 Ranma (Gast)

Ein UNIQUE INDEX ist doch nicht so praktisch. Die Stored Procedure nimmt immer ein Stück vom String und steckt es in eine der Datenbanktabellen. Das sind mehrere Vorgänge für jede Übersetzung. Ein UNIQUE INDEX würde erst beim letzten Eintrag wissen, ob die Kombination der Eintrage tatsächlich nur einmal vorkommt. Dann sind aber die übrigen Eintragungen bereits vorgenommen.

Meine Lösung ist eine extra Tabelle nur zur Kontrolle anzulegen, in die jeweils der noch nicht völlig zerlegte String eingetragen wird. Das wird die Datenbank natürlich fast doppelt so groß machen. Aber die Kontrolltabelle kann hinterher gelöscht werden.

Der Nachteil: Für spätere Aktualisierungen werde ich eine andere Methode brauchen.
Ranma

11.05.2016 01:48

5 Ranma (Gast)

Leider weiß ich noch nicht, ob die Stored Procedure funktioniert. Mein Skript kommt anscheinend nicht so weit, sie aufzurufen.
Ranma

11.05.2016 01:50

Beitrag schreiben (als Gast)





[BBCode-Hilfe]