Mysql索引n-gram分词引擎使⽤概述:
  类似于书籍的⽬录,到⼀本书的特定内容,需要⾸先到内容对应页码,定位对应页码
  存储引擎使⽤类似⽅法进⾏数据查,先到索引中对应值,然后根据匹配的索引到对应⾏
实现原理:
  索引的实现通常使⽤B-Tree 及其变种B+树。(还有HASH)
优缺点:
  优点:
通过创建唯⼀性索引,可以保证数据库表中每⼀⾏数据的唯⼀性
可以⼤⼤加快数据的检索速度,这也是创建索引的最主要的原因
帮助服务器避免排序和临时表
  缺点:
降低写、改速度
占⽤磁盘空间
使⽤场景:
对于⾮常⼩的表,全表扫描更快
中⼤型表索引⾮常有⽤
使⽤:
Mysql常见索引有:主键索引、唯⼀索引、普通索引、全⽂索引、组合索引
PRIMARY KEY(主键索引)
ALTER TABLE `table_name` ADD PRIMARY KEY ( `col` )
UNIQUE(唯⼀索引)
查看mysql索引ALTER TABLE `table_name` ADD UNIQUE (`col`)
INDEX(普通索引)
ALTER TABLE `table_name` ADD INDEX index_name (`col`)
FULLTEXT(全⽂索引)
ALTER TABLE `table_name` ADD FULLTEXT ( `col` )
组合索引 (复合索引)
ALTER TABLE `table_name` ADD INDEX index_name (`a`, `b`, `c` )
遵循前缀原则
WHERE( `a` = 1,`c` = 1) 不会⽤到索引
WHERE(`a` = 1 , `b` =1)可以⽤到索引
删除索引
ALTER TABLE table_name DROP INDEX index_name
查看索引
mysql> show index from tblname;
mysql> show keys from tblname;
主键索引和唯⼀索引区别:
主键索引只能有⼀个
主键索引⼀定是唯⼀索引,唯⼀索引不⼀定是主键索引
主键索引不能为空
索引创建原作
最适合索引的列是 WHERE⼦句或者 ON ⼦句后的列
根据情况适当创建复合索引
尽可能选择数据⼩的列,节约磁盘空间
mysql 常⽤命令⾏:
查看表结构
SHOW CREATE TABLE tableName \G
修改存储引擎
ALTER TABLE my_table ENGINE = InnoDB;
注意事项:
1.索引不存储null值
2.不适合键值较少的列(重复数据较多的列)
3.前导模糊查询不能利⽤索引(like '%XX'或者like '%XX%')
4.索引失效的⼏种情况
  1.如果条件中有or,即使其中有条件带索引也不会使⽤(这也是为什么尽量少⽤or的原因)要想使⽤or,⼜想让索引⽣效,只能将or条件中的每个列都加上索引
  2.对于多列索引,不是使⽤的第⼀部分,则不会使⽤索引
  3.like查询以%开头 
  4.如果列类型是字符串,那⼀定要在条件中将数据使⽤引号引⽤起来,否则不使⽤索引
  5.如果mysql估计使⽤全表扫描要⽐使⽤索引快,则不使⽤索引
全⽂索引:
分词索引基本使⽤⽅法:
SELECT*FROM `student` WHERE MATCH(`name`) AGAINST('聪')
分词,全⽂索引以词为基础的,MySQL默认的分词是所有⾮字母和数字的特殊符号都是分词符
也就是说
SELECT*FROM `vote_record` where MATCH(`user_id`) AGAINST('aewk');
⽆法检索到数据库中user_id字段为 aewK0F7rGWvxZbNiTqj7 的值
mysql5.7版本之前不⽀持中⽂检索
解决⽅法:
  1 . 在表中新建⼀个拼⾳字段,程序将中⽂转换拼⾳后存⼊这个字段
  2. mysql5.7.6之后⾃带有 parser ,我们可以⽤他轻松的实现分词功能
使⽤⽅法:
注意:
1 . ngram只⽀持InooDB引擎
2.  每次在修改完mysql.ini后需要 OPTIMIZE TABLE TABLE_NAME 对索引重构
1. 在mysql.ini中设置分词⼤⼩,默认是2
[mysqld]
ngram_token_size=2
分词的SIZE越⼤,索引的体积就越⼤,所以要根据⾃⾝情况来设置合适的⼤⼩。
2. 创建表
CREATE TABLE articles (
id INT UNSIGNED AUTO_INCREMENT NOT NULL PRIMARY KEY,
title VARCHAR(200),
body TEXT,
auth VARCHAR(30),
FULLTEXT (title,body) WITH PARSER ngram  //这⾥声明使⽤分词引擎n-gram
) ENGINE=InnoDB AUTO_INCREMENT=1DEFAULT CHARSET=utf8;
如果是已经创建的表可以使⽤
ALTER TABLE table_name ADD FULLTEXT INDEX ft_name  (`name`, `company_code`, `office_address`) WITH PARSER ngram;
最后记得 OPTIMIZE TABLE table_name 重建索引(需要定期执⾏)
3. 显式指定全⽂检索表源(这是⼀个⾮常有⽤的调试⼯具。如果我们发现⼀个包含某个词的⽂档,没有如我们所期望的那样出现在查询结果中,那么这个词可能是因为某些原因不在全⽂索引⾥⾯。)
mysql>SET GLOBAL innodb_ft_aux_table="new_feature/articles";  //new_feature为数据库名称, articles为表名称
Query OK, 0 rows affected (0.00 sec)
通过系统表,就可以查看到底是怎么划分articles⾥的数据。
mysql>SELECT*FROM information_schema.INNODB_FT_INDEX_CACHE LIMIT 20,10;
我们可以通过查询和来查询哪些词在全⽂索引⾥⾯。
查询:
1.⾃然语⾔模式下检索:
得到符合条件的个数
mysql>SELECT COUNT(*) FROM articles
->WHERE MATCH (title,body) AGAINST ('数据库'IN NATURALLANGUAGE MODE);
+----------+
|COUNT(*) |
+----------+
|4|
+----------+
1 row in set (0.05 sec)
得到匹配的⽐率
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.布尔模式下搜索,这个就相对于⾃然模式搜索来的复杂些:
匹配既有管理⼜有数据库的记录
mysql>SELECT*FROM articles WHERE MATCH (title,body)
->    AGAINST ('+数据库 +管理'IN BOOLEAN MODE);
+----+------------+--------------------------------------+
| id| title      | body                                  |
+----+------------+--------------------------------------+
|1|数据库管理|在本教程中我将向你展⽰如何管理数据库|
+----+------------+--------------------------------------+
1 rowin set (0.00 sec)
匹配有数据库,但是没有管理的记录
mysql>SELECT*FROM articles WHERE MATCH (title,body)
->    AGAINST ('+数据库 -管理'IN BOOLEAN MODE);
+----+------------------+----------------------------+
| id| title            | body                      |
+----+------------------+----------------------------+
|2|数据库应⽤开发|学习开发数据库应⽤程序|
|4|数据库与事务处理|系统的学习数据库的事务概论|
|5| NoSQL 精髓|学习了解各种⾮结构化数据库|
+----+------------------+----------------------------+
3 rows in set (0.00 sec)
匹配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)

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。