「我試圖找到一種可靠的方法來匹配數據庫中的重複記錄 記錄。」
唉,沒有這樣的事情。你所希望的最多的是一個具有合理元素的懷疑係統。
SQL> select n1
, n2
, soundex(n1) as sdx_n1
, soundex(n2) as sdx_n2
, utl_match.edit_distance_similarity(n1, n2) as ed
, utl_match.jaro_winkler_similarity(n1, n2) as jw
from t94
order by n1, n2
/
2 3 4 5 6 7 8 9
N1 N2 SDX_ SDX_ ED JW
-------------------- -------------------- ---- ---- ---------- ----------
MARK MARKIE M620 M620 67 93
MARK MARKS M620 M620 80 96
MARK MARKUS M620 M622 67 93
MARKY MARKIE M620 M620 67 89
MARSK MARKS M620 M620 60 95
MARX AMRX M620 A562 50 91
MARX M4RX M620 M620 75 85
MARX MARKS M620 M620 60 84
MARX MARSK M620 M620 60 84
MARX MAX M620 M200 75 93
MARX MRX M620 M620 75 92
11 rows selected.
SQL> SQL> SQL>
SOUNDEX的一大優點是,它的標記化字符串。這意味着它可以爲您提供,它可以編入索引:當涉及到大量數據時,這是非常有價值的。另一方面,它又古老又粗俗。還有更新的算法,比如Metaphone和Double Metaphone。你應該能夠通過Google找到它們的PL/SQL實現。
評分的優點是它們允許一定程度的模糊性;所以你可以找到所有的行where name_score >= 90%
。壓制的缺點是分數是相對的,所以你不能爲它們編制索引。這種比較會導致大量的處理。
這意味着:
- 你需要的戰略組合。沒有單一的算法可以解決你的問題。
- 數據清理很有用。比較MARX與MRX和M4RX的得分:名稱中的剝離數提高了命中率。
- 你無法在飛行中獲得大量的名字。如果可以的話,使用標記和預先評分。如果你沒有很多流失,請使用緩存。如果你負擔得起,使用分區。
- 使用Oracle Text(或類似軟件)構建暱稱和變體的同義詞庫。
- Oracle 11g爲Oracle Text引入了特定的名稱搜索功能。 Find out more.
- 建立一個規範名稱表來評分並將實際數據記錄鏈接到該表。
- 使用其他數據值(尤其是可編入索引的數據值,如出生日期)來預過濾大量名稱或提高建議匹配的置信度。
- 請注意,其他數據值也帶有自己的問題:出生在31/01/11 11個月或80歲的人是誰?
- 請記住,名字是棘手的,尤其是當你必須考慮名字被羅馬化時:有超過400種不同的拼寫方式,用Moammar Khadaffi(以羅馬字母表) - 甚至谷歌都不能同意哪個變體是最經典的。
根據我的經驗,連接令牌(名字,姓氏)是一種混合的祝福。它可以解決某些問題(比如道路名稱是出現在地址欄1還是地址欄2),但會導致其他問題:考慮格拉漢OLIVER vs OLIVER GRAHAM對OLIVER vs OLIVER,GRAHAM VS GRAHAM,OLIVER對GRAHAM和GRAHAM對OLIVER的得分。
無論你做什麼,你仍然會有誤報和錯過命中。沒有任何算法能夠抵抗拼寫錯誤(儘管Jaro Winkler在MARX和AMRX上表現不錯)。
來源
2011-11-22 17:42:09
APC
當您在標題中說「重複列值」時,您實際上表示「相似」或「幾乎相同」。 – APC
是的,我認爲「重複」在邏輯上是不正確的,他們是同一個人,但數據不是完全匹配。 – Ollie