說到全文檢索的分詞,多半講到的是中(日韓)文分詞,少有英文等拉丁文系語言,因為英語單詞天然就是分詞的。
但更少講到阿拉伯數位。比如金額,手機號碼,座機號碼等等。
以下不是傳統的從0開始針對mysql全文索引前世今生講起。
我更喜歡從一個小問題入手,見縫插針的將相關的知識點,以非時間線性順序零散穿插起來。
我們有一張人口表,裡面的資料有多種資料來源合併而來,因此每個使用者的手機號可能有多個。
這也很好理解,有的人就是有多個手機號,有的人就是經常換手機號,對吧。
現在有個功能需要通過手機號去關聯使用者。
因為手機號有多個,所以要麼使用like進行模糊匹配。使用者表有上千萬條記錄,這樣的效率肯定是不能接受的。
select * from t_user where phone like '%13112345678%'
要麼使用另一個折中的方案,將手機號單獨成表,使用者表對手機號表一對多關聯。
這種方式效率上能接受,但需要改變現有資料結構,故放棄。
select u.id,u.username,u.phone from t_user u LEFT JOIN t_user_phone p on u.id = p.user_id where p.phone = '13112345678'
最終選用全文索引。(mysql 5.7.6+)
先在使用者錶針對手機號建立一個全文索引。
使用內建分詞引擎ngram
。
CREATE FULLTEXT INDEX idx_full_text_phone ON t_user (phone) WITH PARSER ngram;
當使用手機模糊查詢關聯使用者時可使用以下語句。
select * from t_user where match(phone) AGAINST('13996459860' in boolean mode)
select * from t_user where match(phone) AGAINST('13996459860' in NATURAL LANGUAGE mode)
或
select * from t_user where match(phone) AGAINST('13996459860')
根據我們的需求,查詢手機號需要全匹配才算命中。所以選擇布林模式。
自然語言模式做不到。
關於布林模式和自然語言模式的區別,後面做介紹。
以上算是簡單的背景介紹。
但是
萬惡的但是,雖遲但到
有一天產品過來告訴我,某個手機號關聯出來上百個人。
他問,這種情況是正常的嗎?
他如果直接說你這裡有個bug,我可能直接就懟回去了(bushi