【问题标题】:Best way to store and retrieve synonyms in database mysql在数据库mysql中存储和检索同义词的最佳方法
【发布时间】:2011-04-27 20:13:50
【问题描述】:

我正在制作一个同义词列表,我会将其存储在数据库中并在进行全文搜索之前检索它。

当用户输入类似:word1

我需要在我的同义词表中查找这个词。因此,如果找到这个词,我会选择这个词的所有同义词,并在下一个查询的全文搜索中使用它,我会像这样构建查询

MATCH (columnname) AGAINST ((word1a word1b word1c) IN BOOLEAN MODE)

那么如何将同义词存储在表中?我找到了 2 个选择:

  1. 使用关键字和单词列,如

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

然后我可以在一个查询中找到输入单词的完全匹配并找到它的 ID。在下一个选择中,我得到具有该 ID 的所有单词,并以某种方式使用服务器端语言中的记录集循环将它们连接起来。然后我可以在主表上构建真正的搜索,我需要查找这些单词。

  1. 只使用单词列,如

    word1a|word1b|word1c
    word2a|word2b|word2c
    word3a
    

现在,如果我的单词在任何记录中,我将选择它,如果是,则提取所有记录并将其分解为 |我又能用我的话了。

对于制作这个同义词数据库的人来说,第二种方法看起来更容易维护,但我发现了两个问题:

a) 如果一个单词在字符串中,我如何在 mysql 中查找?我不能喜欢“word1a”,因为同义词可能非常相似,word1a 可能是草莓,草莓可能是鸟,而单词 2a 可能是浆果。显然我需要完全匹配,那么一个 LIKE 语句怎么能在一个字符串中完全匹配呢?

b) 我看到一个速度问题,我猜使用 LIKE 会比使用我精确匹配单词的第一种方法的“=”花费更多的 mysql。另一方面,在第一个选项中,我需要 2 个语句,一个用于获取单词的 ID,第二个用于获取具有此 ID 的所有单词。

您将如何解决这个问题,更多的是采取哪种方法?是否有第三种方式我认为管理员不容易添加/编辑同义词,同时又快又优化?好的,我知道通常没有最好的方法;-)

更新:在我的情况下,使用两个表的解决方案,一个用于主词,第二个用于同义词。因为我没有用户在搜索字段中键入的 MASTER 词。他可以在该字段中键入任何同义词,所以我仍然想知道如何设置这些表,因为我没有主词,我会在一个表中拥有 ID,而在第二个表中具有主 ID 的同义词。没有主词。

【问题讨论】:

  • 感谢您修复我的文字并使其更清晰,下次我会尝试做同样的事情!
  • 不,1 个表是有问题的,因为单词 B 可以在更多组中,如果 WORD 是唯一的,则无法使用此方法完成。

标签: mysql synonym


【解决方案1】:

不要使用(一个)字符串来存储不同的条目。

换句话说:构建一个单词表(word_ID,word)和一个同义词表(word_ID,synonym_ID),然后将单词添加到单词表中,并将每个同义词一个条目添加到同义词表中。

更新(添加了第三个同义词)

你的词表必须包含每个词(ALL),你的同义词表只保存指向同义词的指针(不是一个词!)..

如果你有三个词:A、B 和 C,它们是同义词,你的数据库应该是

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中的许多条目,它们将由计算机管理,需要反映单词之间的现有关系。



第二种方法

您可能还想(我认为您不应该这样做!)使用一个表,该表具有单独的单词字段和同义词(或 ID)列表(word_id、word、synonym_list)。请注意,这与关系数据库的工作方式相反(一个字段,一个事实)。

【讨论】:

  • 您的意思是 2 个表:带有 WordID 和单词列的单词表和带有 WordID 和同义词列的同义词表?我可以搜索一个单词表并将其与同义词表连接起来,以将结果放入一个记录集中,然后循环并以某种方式将它们放在一起?
  • 你是对的......当你发表评论时,我试图将其添加到我的答案中。
  • SELECT synonim FROM wordtable w LEFT JOIN synonymstable sy ON sy.WordID=w.WordId where word = 'mysearchword'?有没有办法让结果返回 ONE 行而不是同义词行数?在同一个 SELECT 中以某种方式连接行?
  • 我认为你对表格提出了很好的观点。然后我只能选择一次。如果只有一种方法可以以某种方式将行 CONCAT 合并为一行,以某种方式将结果作为 word1a word1b word1c 以某种方式进入主搜索查询(然后不需要 RS 循环)
  • 我想我找到了自己问题的答案:可能是 group_concat 是我正在寻找的 ;-)
【解决方案2】:

我认为 3 列,只有一个表更好 WORD_TABLE

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

【讨论】:

  • 你提出了一个很好的建议......这将解决 OP 的问题,他在评论中添加了关于管理表格的问题..
【解决方案3】:

另一种方法是存储含义(这不使用主词,而是使用分组的含义表)

将单词存储在没有同义词且只有文本的单词表中,如下所示:

很多词,一个意思

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

尽管它看起来很像 Hasan Amin Sarand 建议的内容,但它的关键区别在于您不是从 WORD_TABLE 中选择而是从 MEANING_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

您还可以存储还没有单词或您不知道单词的含义。

如果您不知道它属于什么含义,那么您可以为每个新单词插入一个新含义,然后在 word_table 中修复含义_id。

您甚至可以存储和选择相同但含义不同的单词

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-03-07
    • 1970-01-01
    • 1970-01-01
    • 2012-07-27
    • 2021-04-02
    • 1970-01-01
    • 2023-03-24
    • 2012-12-21
    相关资源
    最近更新 更多