2017-04-21 83 views
0

我有一张表来存储书名。每当我插入一个新的标题,我想检查,如果标题已经存在。问题在于,由于拼写错误,无法进行完全匹配。MySQL匹配集词

例如

'My Dream of Wonder Land' 
'My Deam of Wonder Land' 

所以我的目标是为每个标题创建标签,至多3个标签为每本书。这些标签标题的3个最长的一句话:

'My Dream of Wonder Land' = dream, wonder, land 
'My Deam of Wonder Land'= deam, wonder, land 

现在,当我添加标题,我想找到的所有冠军,至少有两个匹配的标签。标签的顺序应该被忽略,这意味着

'land, dream, lego' 

也应该匹配。

在MySQL中存储数据的最佳方式是什么?

+0

您可以尝试模糊搜索以查看书名是否存在。 http://stackoverflow.com/questions/369755/how-do-i-do-a-fuzzy-match-of-company-names-in-mysql-with-php-for-auto-complete – fqhv

+1

问题是,您可以拥有相同标题的书籍。匹配应该在ISBN号码或类似的东西上完成,而不是标题。 – Shadow

+0

@fqhv谢谢,soundex听起来很有希望。但是,如果单词的顺序改变,它不起作用。 –

回答

0

我建议使用fuzzy matching,因为这些比较可能非常复杂。

也就是说,使用标签的想法听起来更有趣。

我可能会为表格标记并垂直存储它们。

CREATE TABLE BookTag (
    BookId INT, 
    Tag NVARCHAR(50)) 

然后,当插入书籍时,您将首先计算标签并将它们存储在临时表中。我会写一个函数从字符串中获取最大的单词。对于这个例子,我只是假设这个函数存在,叫做nthLargestWord(VARCHAR expression, INT n)

INSERT INTO TEMPORARY NewBookTag (Tag) 
SELECT nthLargestWord(@booktitle, 1) 
UNION 
SELECT nthLargestWord(@booktitle, 2) 
UNION 
SELECT nthLargestWord(@booktitle, 3) 

您现在可以将此表连接到您现有标记的表格以查看是否有任何共有2个表格。

SELECT e.BookId 
FROM NewBookTag n 
INNER JOIN BookTag e ON n.Tag = e.Tag 
GROUP BY e.BookId 
HAVING COUNT(*) >= 2 

你可以只是把这个在IF EXISTS插入时,它是假的。

插入你的书后,你已经准备好插入标签了!

INSERT INTO Book (BookTitle) 
VALUES (@BookTitle) 

INSERT INTO BookTag (BookId, Tag) 
SELECT b.BookId, t.Tag 
FROM Book b 
INNER JOIN NewBookTag t ON b.Title = @booktitle 

此解决方案允许您一次插入一本书,它可以被重构为允许多个如果需要的话。