全文索引


  現有的數據庫系統,絕大多數是以結構化數據檢索的主要目標,因此實現相對簡單。比如數值檢索,可以建立一張排序好的索引表,這樣速度可以得到提高。但對於非結構化數據,即全文數據,要想實現檢索,一般都是采用模糊查詢的方式實現的,這種方式不僅速度慢,而且容易將漢字錯誤切分,於是產生了全文檢索技術。

  全文檢索技術是智能信息管理的關鍵技術之一,其主要目的就是實現對大容量的非結構化數據的快速查找。

  全文檢索的中文分詞依賴系統詞庫,該詞庫是只讀的,不允許修改。學過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

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM