99久久国产露脸精品麻豆,欧美日韩精品小说,亚洲免费在线美女视频,国产三级中文字幕,91极品国产情侣高潮对白,国产亚洲一区二区三区不卡片,欧美jizz精品欧美性,久久国产精品久久国产片

MYSQL全文索引的深入理解

袁志蒙 8075次瀏覽

摘要:在開發(fā)中經(jīng)常會(huì)有這樣的一個(gè)功能:就是一篇文章,可能會(huì)添加多個(gè)TAG標(biāo)簽,而數(shù)據(jù)庫(kù)設(shè)計(jì)的話通常是用一個(gè)字段來(lái)存儲(chǔ)這些標(biāo)簽的,如字段名為“tag”的值為“1,3,4,5,7”這樣的,用戶可能會(huì)通過這些標(biāo)簽...

在開發(fā)中經(jīng)常會(huì)有這樣的一個(gè)功能:

就是一篇文章,可能會(huì)添加多個(gè)TAG標(biāo)簽,而數(shù)據(jù)庫(kù)設(shè)計(jì)的話通常是用一個(gè)字段來(lái)存儲(chǔ)這些標(biāo)簽的,如字段名為“tag”的值為“1,3,4,5,7”這樣的,用戶可能會(huì)通過這些標(biāo)簽來(lái)搜索相關(guān)內(nèi)容,之前如果想查詢標(biāo)簽包含1的內(nèi)容的時(shí)候,用的都是 find_in_set('1',tag) 這樣的,那么現(xiàn)在問題來(lái)了,如果我想查詢包含兩個(gè)或者兩個(gè)以上的時(shí)候,怎么查詢呢?

要用 find_in_set('2',tags) OR find_in_set('4',tags),這樣的查詢方式嗎?

這樣的查詢也能出現(xiàn)結(jié)果,但似乎并不是最好的,而且用 find_in_set 用不到索引,如果數(shù)據(jù)量大的話,執(zhí)行時(shí)間就更別提了,于是用到了全文索引,不僅能用到索引,執(zhí)行效率也很高!

添加索引:

ALTER TABLE `yzm_test` ADD FULLTEXT INDEX (`tag`) ;

添加完全文索引后,我們就可以用全文索引來(lái)檢索了:

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('1');

奇怪了,怎么沒有查詢出結(jié)果?

原來(lái)是MySQL指定了最小字符長(zhǎng)度,默認(rèn)是4,必須要匹配大于4的才會(huì)有返回結(jié)果,可以用 SHOW VARIABLES LIKE 'ft_min_word_len'  來(lái)查看指定的字符長(zhǎng)度,也可以在mysql配置文件my.ini 更改最小字符長(zhǎng)度,方法是在my.ini 增加一行 比如:ft_min_word_len = 2,改完后重啟mysql即可。

有時(shí)候我們無(wú)法修改mysql的配置,這時(shí)候,我們就需要在表中通過添加“前綴”的方式來(lái)增加字符的長(zhǎng)度了,比如之前的“1”我們可以變成“tag1”,“2”我們可以變成“tag2”....


嗯,這個(gè)問題解決了,但又出現(xiàn)新的問題了,有的時(shí)候,查詢一個(gè)詞,明明很多條數(shù)據(jù)都包括這個(gè)詞,但返回的結(jié)果卻是空的,原來(lái)MySQL還會(huì)計(jì)算一個(gè)詞的權(quán)值,以決定是否出現(xiàn)在結(jié)果集中,具體如下:


mysql在集和查詢中的對(duì)每個(gè)合適的詞都會(huì)先計(jì)算它們的權(quán)重,一個(gè)出現(xiàn)在多個(gè)文檔中的詞將有較低的權(quán)重(可能甚至有一個(gè)零權(quán)重),因?yàn)樵谶@個(gè)特定的集中,它有較低的語(yǔ)義值。否則,如果詞是較少的,它將得到一個(gè)較高的權(quán)重,mysql默認(rèn)的閥值是50%,上面‘you’在每個(gè)文檔都出現(xiàn),因此是100%,只有低于50%的才會(huì)出現(xiàn)在結(jié)果集中。


使用檢索方式“IN BOOLEAN MODE”

比如說,每個(gè)行都有this這個(gè)字的話,那用this去查時(shí),會(huì)找不到任何結(jié)果,這在記錄條數(shù)特別多時(shí)很有用,原因是數(shù)據(jù)庫(kù)認(rèn)為把所有行都找出來(lái)是沒有意義的,這時(shí),this幾乎被當(dāng)作是stopword(中斷詞);但是若只有兩行記錄時(shí),是啥鬼也查不出來(lái)的,因?yàn)槊總€(gè)字都出現(xiàn)50%(或以上),要避免這種狀況,就要用到布爾全文檢索:IN BOOLEAN MODE。


布爾全文檢索語(yǔ)法:

“+”表示必須包含

“-”表示必須排除

“>”表示出現(xiàn)該單詞時(shí)增加相關(guān)性

“<”表示出現(xiàn)該單詞時(shí)降低相關(guān)性

“*”表示通配符

“~”允許出現(xiàn)該單詞,但是出現(xiàn)時(shí)相關(guān)性為負(fù)

“""”表示短語(yǔ)


例子:

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('tag1 tag2' IN BOOLEAN MODE);
tag1 和 tag2 之間是空格,空格表示OR,即至少包含 tag1 或者 tag2 中的一個(gè)。

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('+tag1 -tag2' IN BOOLEAN MODE);
必須包含tag1 ,并且不包含 tag2

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('+tag1 tag6' IN BOOLEAN MODE);
必須包含tag1 ,但是如果同時(shí)也包含 tag6 則會(huì)獲得更高的權(quán)重。

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('+tag1 ~tag6' IN BOOLEAN MODE);
~ 是我們熟悉的異或運(yùn)算符。返回的記錄必須包含 tag1 ,但是如果同時(shí)也包含 tag6 會(huì)降低權(quán)重。但是它沒有 +tag1 -tag6 嚴(yán)格,因?yàn)楹笳呷绻?tag6 壓根就不返回。

SELECT * FROM `yzm_test` WHERE MATCH(tag) AGAINST ('+tag1 +(>tag2 <tag6)' IN BOOLEAN MODE);
返回同時(shí)包含 tag1 和 tag2 或者同時(shí)包含 tag1 和 tag6 的記錄。但是同時(shí)包含 tag1 和 tag2 的記錄的權(quán)重高于同時(shí)包含 tag1 和 tag6 的記錄。

注意:

A. 只有存儲(chǔ)引擎類型為MyISAM類型的表,并且MySQL版本為4.X或者以上才能使用MySQL內(nèi)置的全文檢索支持

B. MySQL全文檢索默認(rèn)不支持中文,且對(duì)英文檢索時(shí)忽略大小寫

C. MySQL全文檢索時(shí),默認(rèn)檢索長(zhǎng)度為4,即關(guān)鍵詞的長(zhǎng)度必須大于5才能被捕獲

D. MySQL全文檢索時(shí),所有FULLTEXT索引列必須使用相同的字符集

E. MySQL全文檢索返回結(jié)果集時(shí)還會(huì)考慮權(quán)重

F. MySQL全文檢索還支持靈活的布爾全文檢索模式


更新:

MySQL 5.6.4以上版本InnoDB引擎支持全文索引

MySQL 5.7開始,MySQL內(nèi)置了ngram全文檢索插件,用來(lái)支持中文分詞,并且對(duì)MyISAM和InnoDB引擎有效。

隨機(jī)內(nèi)容

表情

共1條評(píng)論
  • 網(wǎng)友評(píng)論:

    InnoDB需要設(shè)置 innodb_ft_min_token_size=1,這時(shí)候發(fā)現(xiàn) 單個(gè)數(shù)字 也能搜到了!

    2021-09-02 15:42:31 回復(fù)

    點(diǎn)擊加載