現有的數據庫系統,絕大多數是以結構化數據檢索的主要目標,因此實現相對簡單。比如數值檢索,可以建立一張排序好的索引表,這樣速度可以得到提高。但對於非結構化數據,即全文數據,要想實現檢索,一般都是采用模糊查詢的方式實現的,這種方式不僅速度慢,而且容易將漢字錯誤切分,於是產生了全文檢索技術。
全文檢索技術是智能信息管理的關鍵技術之一,其主要目的就是實現對大容量的非結構化數據的快速查找。
全文檢索的中文分詞依賴系統詞庫,該詞庫是只讀的,不允許修改。學過solr的都知道分詞器(可以將一段內容分成多個短語)。
全文索引不能達到like的效果,因為會分詞,所以連着的兩個字不一定正好會分成一個詞。
1. 索引的准則
1.在表中插入數據后創建索引
一般情況下,在插入或裝載了數據后,為表創建索引會更加有效率,如果裝載數據之前創建一個或多個索引,在插入每行時都必須更改和維護每個索引,會使得插入效率降低。
2.索引正確的表和列
使用下面的准則決定何時創建索引:
1. 如果需要經常地檢索大表中的少量的行,就為查詢鍵創建索引
2. 為了改善多個表的鏈接性能,可以為連接列創建索引
3. 主鍵和唯一鍵自動有索引,外鍵很多情況也會自動創建索引
4. 小表不需要索引
選取索引列時考慮幾點:
1.列中的值相對比較唯一;
2. 取值范圍大,適合建立索引
3. CLOB和TEXT只能建立全文索引,BLOB不能建立任何索引(適用於ORACLE和國產的達夢數據庫)
3. 為性能而安排索引列
在create index 語句中列的排序會影響查詢的性能。通常將最常用的列放在最前面。
如果多個字段組合定位,不要為每個字段都建立索引,考慮組合索引。當兩個或多個字段都是等值查詢時,組合索引中各個列的前后關系是無關緊要的;但如果是非等值查詢,要想有效利用組合索引,則應該按照等值字段在前、非等值字段在后的原則創建組合索引。
4.限制索引數量
一個表可以有任意數量的所有。但是索引越多修改數據的開銷就越大。當一個表主要用於讀時,索引多就有好處。
2. mysql全文索引的用法
0. 簡介
全文索引以詞為基礎的,MySQL默認的分詞是所有非字母和數字的特殊符號都是分詞符,與索引有關的幾個變量如下:
mysql> SHOW VARIABLES LIKE 'ft%'; +--------------------------+----------------+ | Variable_name | Value | +--------------------------+----------------+ | ft_boolean_syntax | + -><()~*:""&| | | ft_max_word_len | 84 | | ft_min_word_len | 4 | | ft_query_expansion_limit | 20 | | ft_stopword_file | (built-in) | +--------------------------+----------------+ 5 rows in set, 1 warning (0.08 sec)
ft_boolean_syntax:改變IN BOOLEAN MODE的查詢字符,不用重新啟動MySQL也不用重建索引
ft_max_word_len : #最長的索引字符串,默認值為84,修改后必須重建索引文件
ft_min_word_len : #最短的索引字符串,默認值為4,(通常改為1)修改后必須重建索引文件
ft_query_expansion_limit: #查詢括展時取最相關的幾個值用作二次查詢
ft_stopword_file (built-in):#全文索引的過濾詞文件
1. mysql中全文索引
1.建表的時候創建全文索引
CREATE TABLE article ( id INT AUTO_INCREMENT NOT NULL PRIMARY KEY, title VARCHAR(200), body TEXT, FULLTEXT(title, body) );
mysql> show create table article\G *************************** 1. row *************************** Table: article Create Table: CREATE TABLE `article` ( `id` int(11) NOT NULL AUTO_INCREMENT, `title` varchar(200) DEFAULT NULL, `body` text, PRIMARY KEY (`id`), FULLTEXT KEY `title` (`title`,`body`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 1 row in set (0.00 sec)
2. 查看索引
SHOW INDEX FROM article;
3. 刪除索引
DROP INDEX title ON article;
4. 修改表結構創建索引
ALTER TABLE `article` ADD FULLTEXT title_f (title,body);
或者
ALTER TABLE `article` ADD FULLTEXT INDEX title_f (title,body);
5. 直接創建索引 (重要)
CREATE FULLTEXT INDEX title_f ON article (title, body)
補充:上面建的是聯合索引,下面創建單列索引
CREATE FULLTEXT INDEX body_f ON article ( body)
6. 使用索引(如果對沒有全文索引的列進行match會報錯)
使用全文索引的格式: MATCH (columnName) AGAINST ('string')
例如:
查詢包含精忠報國的數據:
SELECT * FROM article WHERE MATCH(body ) AGAINST('精忠報國');
7. 全文本布爾操作符
布爾操作符 | 說明 |
+ | 包含,詞必須存在 |
- | 排除,詞必須不出現 |
> | 包含,而且增加等級值 |
< | 包含,且減少等級值 |
() | 把詞組成子表達式(允許這些子表達式作為一個組被包含、排除、排列等) |
~ | 取消一個詞的牌謔值 |
* | 詞尾的通配符。這個只能放在詞后面 |
"" | 定義一個短語(與單個詞的列表不一樣,它匹配整個短語以便包含或排除這個短語) |
例如:
+:查詢必須包含精忠報國的:
SELECT * FROM article WHERE MATCH(body ) AGAINST('+精忠報國' IN BOOLEAN MODE );
-:必須不包含精忠報國的:
SELECT * FROM article WHERE MATCH(body ) AGAINST('-精忠報國' IN BOOLEAN MODE );
空格:查詢包含史無前例或者大義滅親的
SELECT * FROM article WHERE MATCH(body ) AGAINST('史無前例 大義滅親' IN BOOLEAN MODE );
>:查詢包含精忠報國的,如果包含大義滅親的往前排
SELECT * FROM article WHERE MATCH(body ) AGAINST('精忠報國 >大義滅親' IN BOOLEAN MODE );
<:查詢包含精忠報國的,如果包含大義滅親的往后排
SELECT * FROM article WHERE MATCH(body ) AGAINST('精忠報國 <大義滅親' IN BOOLEAN MODE );
*:查詢以大義滅親結尾的
SELECT * FROM article WHERE MATCH(body ) AGAINST('+精忠報國*' IN BOOLEAN MODE );
3. Oracle全文索引用法
主要介紹三種自然語言的分析器:
basic_lexer(默認的分析器):主要針對英語。有較高的處理效率,因為它只認空格和標點,所以對於漢語沒有空格的情況不會分詞
chinese_vgram_lexer: 專用漢語分析器,支持所有漢字字符集,因為采用了分詞的方法,可以查到所有的分詞,效率差
chinese_lexer: 新漢語分析器,只支持utf8, 支持識別大部分的分詞,但是會過濾掉很多無法識別的分詞,因為這個原因也導致效率很高,如果數據庫是zhs16gbk字符集,則只能使用Chinese vgram lexer
注意:追求效率那么使用CHINESE_LEXER,如果追求准確度那么使用CHINESE_VGRAM_LEXER(推薦使用chinese_vgram_lexer)
1. 創建文本解析器
BEGIN ctx_ddl.create_preference ('my_lexer', 'chinese_vgram_lexer'); END;
2. 刪除文本解析器
BEGIN ctx_ddl.drop_preference ('my_lexer'); end;
3. 創建全文索引
CREATE INDEX prop_2_f ON 合同2(檔案屬性) indextype is ctxsys.context parameters('lexer my_lexer');
4. 使用全文索引(如果對沒有全文索引的列進行contains函數會報錯)
包含:
select id from 合同2 where contains(檔案屬性, '測試檔案屬性') > 0
不包含:
select id from 合同2 where not contains(檔案屬性, '測試檔案屬性') > 0
5. 刪除全文索引
drop index prop_2_f
6. 優化全文索引
begin ctx_ddl.optimize_index('prop_2_f','full'); END;
4. SQLServer全文索引用法
1、全文索引可對char、varchar、nchar、nvarchar、text、ntext、image、xml、varbinary 或 varbinary(max) 類型字段進行檢索,是解決海量數據模糊查詢的好辦法。
2、一個表只能建立一個全文索引(但可以對多個字段)。
3. 全文索引並不能達到like的效果,因為會進行分詞,不一定連着的兩個正好是一個詞
4. 建立全文索引的表表中必須有一個唯一性索引,並不需要是主鍵(建議是主鍵)。
SQLServer中一個表只能有一個全文索引,索引的列可以是多列。一個全文索引目錄可以對應多個表(建議最好是一對一,便於刪除或者進行其他操作)。
1. 首先開啟全文索引服務
檢查服務里面帶有Full-text字樣的服務是否存在並開啟,如果不存在帶有Full-text字樣的服務的,確認是否安裝了sqlserverFullTextSearch
2. 新建全文目錄
create fulltext catalog ftc_test1 with accent_sensitivity = off;
3.建立全文索引
(1)查看表的主鍵索引名稱
select convert(varchar(100), CONSTRAINT_NAME) from INFORMATION_SCHEMA.KEY_COLUMN_USAGE WHERE OBJECTPROPERTY(OBJECT_ID(CONSTRAINT_NAME), 'IsPrimaryKey') = 1 and table_name = 'test1';
結果:
PK_test1
(2)建立全文索引(創建全文索引的時候必須指定一個唯一索引,所以建議用主鍵索引)
create fulltext index on test1 key index [PK_test1] on ftc_test1 with (CHANGE_TRACKING AUTO)
(3)全文索引中添加列
alter fulltext index on test1 add ([name] LANGUAGE [Simplified Chinese])
(4)查看
可以通過可視化工具查看:
4. 使用全文索引-如果對未建立全文索引的列使用contains會報錯
包含: 名字包含夢想的
select * from test1 where contains(name , '夢想')
內容包含什么和結局的:
select * from test1 where contains(content, '什么 and 結局')
內容包含什么或結局的:
select * from test1 where contains(content, '什么 or 結局')
帶有張*詞語的
select * from test1 where contains(name, '"張*"')
包含韓國和首都,且這兩個詞緊鄰
select * from test1 where contains(content, '韓國 near 首都')
name包含什么或者content包含什么的:
select * from test1 where contains((name, content), '什么')
全部索引列中查詢包含結局的
select * from test1 where contains(*, '結局')
不包含:
select * from test1 where not contains(name , '夢想')
更多的語法參考:https://docs.microsoft.com/zh-cn/previous-versions/sql/sql-server-2008/ms187787(v=sql.100)
5. 索引優化
(1)查看全文索引目錄
select name from SYS.fulltext_catalogs
結果:
ftc_test1
(2)重新優化
alter fulltext catalog [ftc_test1] reorganize
6. 刪除索引以及相關目-刪除的時候與增加的順序相反。
(1)從全文索引中移除
alter fulltext index on test1 drop ([name])
(2) 刪除全文索引
drop fulltext index on test1
(3) 刪除表
drop table test1
(4) 刪除全文索引目錄
drop fulltext catalog ftc_test1