有效检查可能的重复实体

时间:2009-05-05 16:11:35

标签: database search duplicate-data

我要求在用户将实体保存到数据库之前生成可能重复的列表,并警告他们可能存在重复项。

有7个标准我们应该检查重复项,如果至少有3个匹配,我们应该将其标记给用户。 标准将全部与ID匹配,因此不需要模糊的字符串匹配,但我的问题来自这样一个事实:有很多可能的方法(如果我已经完成了我的总和,有99种方法)至少有3个项目可以匹配7种可能的清单。

我不想做99个单独的数据库查询来查找我的搜索结果,也不想从客户端的数据库和过滤器中恢复全部数据。我们目前可能只谈论成千上万的记录,但随着系统的成熟,这将增长到数百万。

任何人都有一个很好的有效方法来做到这一点? 我正在考虑一个简单的OR查询来获取记录,其中至少有一个字段与db匹配,然后在客户端上进行一些处理以对其进行更多过滤,但是一些字段具有非常低的基数并且实际上不会减少这个数字很大。

由于 乔恩

5 个答案:

答案 0 :(得分:3)

ORCASE求和将起作用但效率很低,因为它们不使用索引。

您需要使UNION索引可用。

如果用户将namephoneemailaddress输入数据库,您想要检查至少匹配3的所有记录在这些字段中,您发出:

SELECT  i.*
FROM    (
        SELECT  id, COUNT(*)
        FROM    (
                SELECT  id
                FROM    t_info t
                WHERE   name  = 'Eve Chianese'
                UNION ALL
                SELECT  id
                FROM    t_info t
                WHERE   phone = '+15558000042'
                UNION ALL
                SELECT  id
                FROM    t_info t
                WHERE   email = '42@example.com'
                UNION ALL
                SELECT  id
                FROM    t_info t
                WHERE   address = '42 North Lane'
                ) q
        GROUP BY
                id
        HAVING  COUNT(*) >= 3
        ) dq
JOIN    t_info i
ON      i.id = dq.id

这将使用这些字段上的索引,查询将很快。

有关详细信息,请参阅我的博客中的这篇文章:

另请参阅本文基于的question

如果要在现有数据中包含SELECT i.* FROM t_info i1 WHERE EXISTS ( SELECT 1 FROM ( SELECT id FROM t_info t WHERE name = i1.name UNION ALL SELECT id FROM t_info t WHERE phone = i1.phone UNION ALL SELECT id FROM t_info t WHERE email = i1.email UNION ALL SELECT id FROM t_info t WHERE address = i1.address ) q GROUP BY id HAVING COUNT(*) >= 3 ) 值列表,只需将此查询包装到子查询中:

DISTINCT

请注意,此A不具有传递性:如果B匹配BC匹配A,则这并不意味着C匹配{{1}}。

答案 1 :(得分:2)

您可能需要以下内容:

SELECT id
FROM 
    (select id, CASE fld1 WHEN input1 THEN 1 ELSE 0 "rule1",
        CASE fld2 when input2 THEN 1 ELSE 0 "rule2",
        ...,
        CASE fld7 when input7 THEN 1 ELSE 0 "rule2",
    FROM table)
WHERE rule1+rule2+rule3+...+rule4 >= 3

这未经过测试,但它显示了解决此问题的方法。

答案 2 :(得分:0)

你在使用什么DBS?有些人支持使用服务器端代码来使用这些约束。

答案 3 :(得分:0)

您是否考虑过使用带游标的存储过程?然后,您可以执行OR查询,然后逐个查找匹配的记录。使用存储过程可以让您对服务器进行所有检查。

但是,我认为包含数百万条记录的表扫描总是很慢。我认为你应该找出最有可能匹配的7个字段中的哪个是确保这些字段被编入索引。

答案 4 :(得分:0)

我假设您的系统正在尝试匹配某个帖子或类似内容的标签ID。这是一个多对多关系,您应该有三个表来处理它。一个用于帖子,一个用于标签,一个用于帖子和标签关系。

如果我的假设是正确的,那么处理此问题的最佳方法是:

SELECT postid, count(tagid) as common_tag_count
FROM posts_to_tags
WHERE tagid IN (tag1, tag2, tag3, ...)
GROUP BY postid
HAVING count(tagid) > 3;