Der beste Weg zum Speichern und Abrufen Synonyme in der Datenbank mysql
Frage
Ich erstelle eine Liste Synonyme, dass ich es in der Datenbank gespeichert werden und abgerufen wird, bevor zur Volltextsuche zu tun.
Wenn Benutzer betritt wie: word1
Ich brauche in meinem Synonyme Tabelle für dieses Wort nachzuschlagen. Also, wenn das Wort gefunden wird, würde ich alle Synonyme dieses Wortes auswählen und in der Volltextsuche auf der nächsten Abfrage verwenden, wo ich die Abfrage wie
contructMATCH (column) AGAINST ((word1a word1b word1c) IN BOOLEAN MODE)
Wie speichere ich die Synonyme in einer Tabelle? Ich fand zwei Möglichkeiten:
-
Mit der Taste und Wort Spalten wie
val keyword ------------- 1 word1a 1 word1b 1 word1c 2 word2a 2 word2b 3 word3a etc.
So dann kann ich genaue Übereinstimmung des eingegebenen Wortes in einer Abfrage finden und die ID finden. In dem nächsten wähle ich alle die Worte mit dieser ID erhalten und sie irgendwie concate eine Re-Cord-Schleife in Server-Seite Langauge verwendet wird. Ich kann dann die reale Suche auf der Haupttabelle konstruieren, dass ich für die Worte zu suchen.
-
nur mit Wort Spalten wie
word1a|word1b|word1c word2a|word2b|word2c word3a
Jetzt habe ich so die SELECT für mein Wort, wenn es in jedem Datensatz ist, wenn es ist, extrahieren Sie alle Rekord und explodieren sie in | und ich habe meine Worte wieder, dass ich verwenden können.
Dieser zweite Ansatz lookes einfacher für den einen halten, die diese Datenbank von Synonymen machen würden, aber ich sehe zwei Probleme:
a) Wie kann ich in MySQL finden, wenn ein Wort in der Zeichenfolge ist? So kann ich nicht ‚word1a‘ es, weil synonims kann sehr ähnlich in einer Art und Weise word1a sein könnte strowberry sein und strowberries könnten Vögel und Wort 2a könnte Beere sein sein. Offensichtlich muss ich um eine genaue Übereinstimmung, so wie könnte eine LIKE-Anweisung genau innerhalb einer Zeichenfolge überein?
b) sehe ich ein Geschwindigkeitsproblem, mit LIKE würde ich nehmen erraten mehr mysql eingenommen hat, als „=“ den ersten Ansatz, wo ich ein Wort genau übereinstimmen. Auf der anderen Seite in der ersten Option brauche ich zwei Aussagen, man die ID des Wortes zu erhalten und die zweiten alle Worte mit dieser ID zu erhalten.
Wie würden Sie dieses Problem lösen, eher ein Dilemma, das nehmen nähern? Gibt es einen dritten Weg, ich sehe nicht, dass einfach für admin hinzufügen / bearbeiten Synonyme und in der gleichen Zeit schnell und optimal? Ok ich weiß, gibt es keinen besten Weg, in der Regel; -)
UPDATE : Die Lösung zu verwenden, um zwei Tabellen eine für Master-Wort und das zweite für die Synonym Worte nicht funktionieren in meinem Fall. Denn ich habe kein MASTER Wort, dass die Benutzertypen in Suchfeld ein. Er kann auf dem Gebiet eine der Synonyme geben, so dass ich bin immer noch fragen, wie diese Tabellen zu setzen, wie ich Master Worte nicht habe, dass ich IDs in einer Tabelle würde und synonims mit ID des Masters in der zweiten Tabelle. Es gibt kein Master-Wort.
Lösung
Don't use a (one) string to store different entries.
In other words: Build a word table (word_ID,word) and a synonym table (word_ID,synonym_ID) then add the word to the word table and one entry per synonym to the synonyms table.
UPDATE (added 3rd synonym)
Your word table must contain every word (ALL), your synonym table only holds pointers to synonyms (not a single word!) ..
If you had three words: A, B and C, that are synonyms, your DB would be
WORD_TABLE SYNONYM_TABLE
ID | WORD W_ID | S_ID
---+----- -----+-------
1 | A 1 | 2
2 | B 2 | 1
3 | C 1 | 3
3 | 1
2 | 3
3 | 2
Don't be afraid of the many entries in the SYNONYM_TABLE, they will be managed by the computer and are needed to reflect the existing relations between the words.
2nd approach
You might also be tempted (I don't think you should!) to go with one table that has separate fields for word and a list of synonyms (or IDs) (word_id,word,synonym_list). Beware that that is contrary to the way a relational DB works (one field, one fact).
Andere Tipps
I think 3 columns and only one table is better WORD_TABLE
ID | WORD | GroupID
---+----------------
1 | A | 1
2 | B | 1
3 | C | 1
Another approach is to store meaning (this does not use master words, but a meaning table that groups instead)
would be to store the words in a words table without synonyms and with only text, like this:
Many words, one meaning
meaning_table
meaning_id
---
1
2
3
And store the words in another table, for example if A, B and C were all synonyms of 1 meaning
word_table
word_id | meaning_id | word
--------+------------+------
1 | 1 | A
2 | 1 | B
3 | 1 | C
Even though it looks a lot like what Hasan Amin Sarand suggests, it has the key difference that you don't select from the WORD_TABLE but instead select from the MEANING_TABLE, this is much better and I learned that the hard way.
This way you store the meaning in one table and as many words for that meaning as you like in another.
Although it assumes that you have 1 meaning per word.
Many words, many meanings
if you want to store words with multiple meanings then you need another table for the many to many relationship and the whole thing becomes:
meaning_table
-------------
meaning_id
-------------
1
2
3
word_meaning_table
--------------------
word_id | meaning_id
--------+-----------
1 | 1
2 | 1
3 | 1
word_table
--------------
word_id | word
--------+-----
1 | A
2 | B
3 | C
Now you can have as many words with as many meanings as you want, where any word can mean anything you want and any meaning can have many words.
If you want to select a word and it's synonyms then you do
SELECT
meaning_id,word_id,word
FROM meaning_table
INNER JOIN word_meaning_table USING (meaning_id)
INNER JOIN word_table USING (meaning_id)
WHERE meaning_id=1
You can also then store meaning that does not have a word yet or that you don't know the word of.
If you don't know what meaning it belongs to then you can just insert a new meaning for every new word and fix the meaning_id in the word_table later.
You can then even store and select the words that are the same but mean different things
SELECT
meaning_id,word_id,word
FROM meaning_table
INNER JOIN word_meaning_table USING (meaning_id)
INNER JOIN word_table USING (meaning_id)
WHERE word_id=1