11

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

当用户输入时:word1

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

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

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

  1. 使用 key 和 word 列,如

    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 的同义词。没有主语。

4

3 回答 3

14

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

换句话说:构建一个单词表(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)。请注意,这与关系数据库的工作方式相反(一个字段,一个事实)。

于 2010-10-20T04:08:51.180 回答
8

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

ID | WORD | GroupID
---+----------------
1  |  A   |   1
2  |  B   |   1
3  |  C   |   1
于 2011-07-12T06:08:42.630 回答
5

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

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

很多词,一个意思

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 中修复meaning_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
于 2013-11-25T15:54:39.103 回答