Лучший способ хранения и извлечения синонимов в базе данных mysql

Я делаю список синонимов, который я буду хранить в базе данных и извлекать его перед выполнением полнотекстового поиска.

когда пользователи входят как: word1

мне нужно найти это слово в моей таблице синонимов. Поэтому, если слово найдено, Я бы выбрал все синонимы этого слова и использовал его в полнотекстовом поиске по следующему запросу, где я создаю запрос, как

матч (columnname) против ((word1a word1b word1c) в логическом режиме)

Так как сохранить синонимы в таблице? Я нашел 2 варианта:

  1. использование ключевых и слов столбцов, таких как

    val  keyword
    -------------
    1    word1a
    1    word1b
    1    word1c
    2    word2a
    2    word2b
    3    word3a
    etc.
    

поэтому я могу найти точное совпадение введенного слова в одном запросе и найти его ID. В следующем выборе я получаю все слова с этим идентификатором и каким-то образом объединяю их с помощью цикла набора записей на стороне сервера langauge. Затем я могу построить реальный поиск на главной таблице, которую мне нужно искать слова.

  1. используя только столбцы word, такие как

    word1a|word1b|word1c
    word2a|word2b|word2c
    word3a
    

теперь я так выбираю для моего слова, если оно находится внутри любой записи, если это так, извлеките всю запись и взорвите ее в|, и у меня снова есть мои слова, которые я могу использовать.

этот второй подход выглядит проще поддерживать для того, кто сделает эту базу синонимов, но я вижу 2 проблемы:

a) Как найти в mysql, если слово находится внутри строки? Я не могу Как "word1a" это потому, что синонимы могут быть очень похожи в том, как word1a может быть strowberry и strowberries может быть птицы и слово 2a может быть ягодой. Очевидно, мне нужно точное совпадение, так как подобное утверждение может точно совпадать внутри строки?

b) я вижу проблему скорости, используя LIKE, я думаю, возьму больше mysql, чем"=", используя первый подход, где я точно соответствую слову. С другой стороны, в первом варианте мне нужно 2 оператора, один, чтобы получить идентификатор слова, а второй, чтобы получить все слова с этим ID.

Как бы вы решили эту проблему, скорее дилемму, какой подход принять? Есть ли третий способ, который я не вижу, что администратору легко добавлять / редактировать синонимы и в то же время быстро и оптимально? Хорошо, я знаю, что нет лучшего способа обычно ; -)

обновление: решение использовать две таблицы один для главного слова и второй для синонимов слов не будет работать в моем случае. Потому что у меня нет главного слова, которое пользователь вводит в поле поиска. Он может ввести любой из синонимов в поле, поэтому мне все еще интересно, как установить эти таблицы, поскольку у меня нет главных слов, которые у меня были бы ID в одной таблице и синонимы с ID мастера во второй таблице. Нет главного слова.

3 ответов


Не используйте строку (one) для хранения разных записей.

другими словами: создайте таблицу слов (word_ID, word) и таблицу синонимов (word_ID,synonym_ID), затем добавьте слово в таблицу слов и одну запись на Синоним в таблицу синонимов.

обновление (добавил 3-й синоним)

ваша таблица слов должна содержать каждое слово (все), ваша таблица синонимов содержит только указатели на синонимы (ни одного слова!) ..

Если вы было три слова: A, B и C, которые являются синонимами, ваш DB будет

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  

Не бойтесь многих записей в SYNONYM_TABLE, они будут управляться компьютером и необходимы для отражения существующих отношений между словами.



2-й подход

вы также можете быть соблазнены (я не думаю, что вы должны!) пойти с одной таблицей, которая имеет отдельные поля для word и список синонимов (или идентификаторов) (word_id, word, synonym_list). Остерегайтесь, что это противоречит тому, как работает реляционная БД (одно поле, один факт).


Я думаю, что 3 столбца и только одна таблица лучше WORD_TABLE

ID | WORD | GroupID
---+----------------
1  |  A   |   1
2  |  B   |   1
3  |  C   |   1

другой подход-хранить значение (это не использует основные слова, а таблицу значений, которая группирует вместо этого)

было бы хранить слова в таблице слов без синонимов и только с текстом, как это:

много слов, одно из значений слова

meaning_table

meaning_id
---
1
2
3

и сохраните слова в другой таблице, например, если A, B и C были синонимами 1 значения

word_table

word_id | meaning_id | word
--------+------------+------
1       |  1         |   A
2       |  1         |   B
3       |  1         |   C

хотя очень похоже на то, что Хасан Амин Отель Sarand предполагает, что у него есть ключевое отличие, что вы не выбираете из WORD_TABLE, а вместо этого выбираете из MEAN_TABLE, это намного лучше, и я узнал, что на жестком пути.

таким образом, вы храните значение в одной таблице и столько слов для этого значения, сколько вам нравится в другой.

хотя предполагается, что у вас есть 1 значение на слово.

много слов, много смыслов

если вы хотите хранить слова с несколькими значениями, вам нужен другой таблицы многие ко многим отношения и все будет:

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

теперь у вас может быть столько слов с таким количеством значений, сколько вы хотите, где любое слово может означать все, что вы хотите, и любое значение может иметь много слов.

если вы хотите выбрать слово и его синонимы, то вы

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

вы также можете сохранить значение, которое еще не имеет слова или которое вы не знаете.

если вы не знаете, что это значит принадлежит тогда вы можете просто вставить новое значение для каждого нового слова и исправить значение_id в word_table позже.

вы можете даже хранить и выбирать слова, которые одинаковы, но означают разные вещи

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