mysql 普通索引和全文索引的区别

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了mysql 普通索引和全文索引的区别相关的知识,希望对你有一定的参考价值。

mysql全文索引 FULLTEXT索引和like的区别 fulltext ,其实是一个索引,like语句很难用索引,所以提升了效率。
fulltext ,支持多个字段检索。
搜索功能一般都用带有中文分词的开源产品,像xunsearch。
一般小项目用like就行了
参考技术A 全文检索在MySQL里面很早就支持了,只不过一直以来只支持英文。缘由是他从来都使用空格来作为分词的分隔符,而对于中文来讲,显然用空格就不合适,需要针对中文语义进行分词。这不,从MySQL5.7开始,MySQL内置了ngram全文检索插件,用来支持中文分词,并且对MyISAM和InnoDB引擎有效。

在使用中文检索分词插件ngram之前,先得在MySQL配置文件里面设置他的分词大小,比如,
[mysqld]
ngram_token_size=2

这里把分词大小设置为2。要记住,分词的SIZE越大,索引的体积就越大,所以要根据自身情况来设置合适的大小。

示例表结构:
CREATE TABLE articles (
id INTUNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
titleVARCHAR(200),
body TEXT,
FULLTEXT (title,body) WITH PARSER ngram
) ENGINE=InnoDBCHARACTER SET utf8mb4;

示例数据,有6行记录。
mysql> select * from articles\G
***************************1. row ***************************
id: 1
title: 数据库管理
body: 在本教程中我将向你展示如何管理数据库
***************************2. row ***************************
id: 2
title: 数据库应用开发
body: 学习开发数据库应用程序
***************************3. row ***************************
id: 3
title: MySQL完全手册
body: 学习MySQL的一切
***************************4. row ***************************
id: 4
title: 数据库与事务处理
body: 系统的学习数据库的事务概论
***************************5. row ***************************
id: 5
title: NoSQL精髓
body: 学习了解各种非结构化数据库
***************************6. row ***************************
id: 6
title: SQL 语言详解
body: 详细了解如果使用各种SQL
6 rows inset (0.00 sec)

显式指定全文检索表源
mysql> SETGLOBAL innodb_ft_aux_table="new_feature/articles";
Query OK, 0 rows affected (0.00 sec)

通过系统表,就可以查看到底是怎么划分articles里的数据。
mysql> SELECT *FROM information_schema.INNODB_FT_INDEX_CACHE LIMIT 20,10;
+------+--------------+-------------+-----------+--------+----------+
| WORD | FIRST_DOC_ID | LAST_DOC_ID | DOC_COUNT | DOC_ID| POSITION |
+------+--------------+-------------+-----------+--------+----------+
| 中我 | 2 | 2 | 1 | 2 | 28 |
| 习m | 4 | 4 | 1 | 4 | 21 |
| 习了 | 6 | 6 | 1 | 6 | 16 |
| 习开 | 3 | 3 | 1 | 3 | 25 |
| 习数 | 5 | 5 | 1 | 5 | 37 |
| 了解 | 6 | 7 | 2 | 6 | 19 |
| 了解 | 6 | 7 | 2 | 7 | 23 |
| 事务 | 5 | 5 | 1 | 5 | 12 |
| 事务 | 5 | 5 | 1 | 5 | 40 |
| 何管 | 2 | 2 | 1 | 2 | 52 |
+------+--------------+-------------+-----------+--------+----------+
10 rows in set (0.00 sec)

这里可以看到,把分词长度设置为2,所有的数据都只有两个一组。上面数据还包含了行的位置,ID等等信息。
接下来,我来进行一系列检索示范,使用方法和原来英文检索一致。

1. 自然语言模式下检索:
A,得到符合条件的个数,
mysql>SELECT COUNT(*) FROM articles
-> WHERE MATCH (title,body) AGAINST ('数据库' IN NATURALLANGUAGE MODE);
+----------+
| COUNT(*) |
+----------+
| 4 |
+----------+
1 row in set (0.05 sec)

B,得到匹配的比率,

mysql>SELECT id, MATCH (title,body) AGAINST ('数据库' IN NATURAL LANGUAGE MODE)
AS score FROM articles;
+----+----------------------+
| id| score |
+----+----------------------+
| 1 | 0.12403252720832825 |
| 2 | 0.12403252720832825 |
| 3 | 0 |
| 4 | 0.12403252720832825 |
| 5 | 0.062016263604164124 |
| 6 | 0 |
+----+----------------------+
6rows in set (0.00 sec)

2. 布尔模式下搜索,这个就相对于自然模式搜索来的复杂些:
A,匹配既有管理又有数据库的记录,
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST ('+数据库 +管理' IN BOOLEAN MODE);
+----+------------+--------------------------------------+
| id| title | body |
+----+------------+--------------------------------------+
| 1 | 数据库管理 | 在本教程中我将向你展示如何管理数据库
|
+----+------------+--------------------------------------+
1 rowin set (0.00 sec)

B,匹配有数据库,但是没有管理的记录,
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST ('+数据库 -管理' IN BOOLEAN MODE);
+----+------------------+----------------------------+
| id| title | body |
+----+------------------+----------------------------+
| 2 | 数据库应用开发 | 学习开发数据库应用程序 |
| 4 | 数据库与事务处理 | 系统的学习数据库的事务概论 |
| 5 | NoSQL 精髓 | 学习了解各种非结构化数据库 |
+----+------------------+----------------------------+
3rows in set (0.00 sec)

C,匹配MySQL,但是把数据库的相关性降低,
mysql> SELECT * FROM articles WHERE MATCH (title,body)
-> AGAINST ('>数据库 +MySQL' INBOOLEAN MODE);
+----+---------------+-----------------+
| id| title | body |
+----+---------------+-----------------+
| 3 | MySQL完全手册 |学习MySQL的一切 |
+----+---------------+-----------------+
1 rowin set (0.00 sec)

3,查询扩展模式,比如要搜索数据库,那么MySQL,oracle,DB2也都将会被搜索到,

mysql> SELECT * FROM articles
-> WHERE MATCH (title,body)
-> AGAINST ('数据库' WITH QUERY EXPANSION);
+----+------------------+--------------------------------------+
| id| title | body |
+----+------------------+--------------------------------------+
| 1 | 数据库管理 | 在本教程中我将向你展示如何管理数据库
| 4 | 数据库与事务处理 | 系统的学习数据库的事务概论
| 2 | 数据库应用开发 | 学习开发数据库应用程序 |
| 5 | NoSQL 精髓 | 学习了解各种非结构化数据库 |
| 6 | SQL 语言详解 | 详细了解如果使用各种SQL|
| 3 | MySQL完全手册 | 学习MySQL的一切 |
+----+------------------+--------------------------------------+
6rows in set (0.01 sec)

当然,我这里只是功能演示,更多的性能测试,大家有兴趣可以进行详细测试。由于N-grm是中文检索常用的分词算法,已经在互联网大量使用,这次集成到mysql中,想必效果上不会有太大的问题。

mysql 索引和事务视图

MySQL索引的建立对于MySQL的高效运行是很重要的,索引可以大大提高MySQL的检索速度,数据库索引就好比好比是一本书全面的目录。

索引分5类

  1. 普通索引,这是最基本的索引类型,而且他没有唯一性之类的限制。
  2. 唯一性索引,这种索引和前面的“普通索引”基本相同,但有一个区别:索引列的所有值只能出现一次,即必须唯一。
  3. 主键索引,主键是一种唯一性索引,该索引要求主键中的每个值都唯一,不允许为空。
  4. 全文索引,索引类型为FULLTEXT,全文索引可以在CHAR、VARCHAR或者TEXT类型的列上创建。
  5. 单列索引和多列索引,索引可以在单列上创建的索引,也可以在多列上创建的索引。多列索引可以区分其中一列可能有相同值的行。

    创建索引方法

    1.创建普通索引,命令格式是:
CREATE INDEX <索引的名字> ON tablename (列的列表);
2.创建唯一索引,命令格式是:
CREATE UNIQUE INDEX <索引名字>
ON tablename(列的列表);
3.创建主键索引,有两种方式,一种是在创建表的同时创建主键,主键索引自动创建,命令格式如下:
CREATE TABLE tablename ([....],PRIMARY KEY(列的列表));
另一种是已经创建了表,没有指定主键,然后修改表加入主键,主键索引会自动创建,命令格式如下:
ALTER TABLE tablename ADD PRIMARY KEY(列的列表);
4.创建表示指定或修改表时指定全文索引,命令格式如下:
CREATE TABLE 表名 (列名 TEXT,FULLTEXT(列名));
5.创建多列索引,命令格式如下:
CREATE INDEX 多列索引名字 ON 列名_列名;
6.查询索引:
SHOW INDEX FROM 表名 G;

key_name 对应的是索引名字。Non_unique 对应值是1,表示不是唯一性索引,对应值为0,表示是唯一性索引。

7.删除索引:
DROP INDEX 索引名 from 表名;

事务:一组操作共同执行或者都不执行,结果保持一致。

事务的四大特性:

  1. 原子性:不可分割,视为一个整体。
  2. 一致性:前后结果保持一致。
  3. 隔离性:对数据进行修改的所有并发事务是彼此隔离的,表示事务是独立的,不应以任何方式依赖或影响其他事务。
  4. 持久性:一旦执行成功,不可逆转,数据永久变更。
    Mysql中使用命令控制事务需要用到3个命令:
    • begin :表示开始一个事务,后面会有多条数据库操作语句执行。
    • commit:表示提交一个事务,对应前面的begin操作,他们之间的数据库操作语句一起完成。
    • rollback:表示回滚一个事务,在begin和commit之间,如果某一个数据库操作语句出现错误,执行rollback回滚,数据库回到begin之前的状态。

      视图:数据库中的虚拟表,一张或者多表中的数据给不同权限用户提供访问。

      1.创建一个查询结果的视图:
CREATE VIEW 视图名 AS SELECT * FROM 表名 条件(where score>80);
2.查看视图:
SELECT * FROM 视图名;
3.删除一个视图:
DROP VIEW IF EXISTS 视图名;

IF EXISTS 参数指判断视图是否存在,如果存在则执行,不存在则不执行。

以上是关于mysql 普通索引和全文索引的区别的主要内容,如果未能解决你的问题,请参考以下文章

mysql 表有 2 个全文索引和 1 个普通索引是不好的设计吗? [关闭]

mysql主键普通索引唯一索引和全文索引的比较

mysql主键普通索引唯一索引和全文索引的比较

普通列和全文列的 MySQL 索引

怎么MySql添加全文索引

MySQL全文索引 FULLTEXT索引和like的区别