author:空巷
WeChat Applet :Java空巷
QQ: 2399014502
Mail: [email protected]
WeiBo : KongXiang_
WeChat:
前言:数据库和数据库索引这两个东西是在服务器端开发领域应用最为广泛的两个概念,熟练使用数据库和数据库索引是后端开发人员在行业内生存的必备技能。数据库索引是用来提高数据库表的数据查询速度的。一个最优的索引能够轻易的将查询性能提高好几个数量级。
数据库索引:屎对数据库表中要查询的字段简历索引其实就是吧该字段按照一定的方式排序的结构。
但是总的来说利还是大于弊的,所以我们设计数据库的时候需要善于利用索引,善于优化索引。
这是最基本的索引,它没有任何限制。它有以下几种创建方式:
CREATE INDEX indexName ON mytable(username(length));
create index myDeptIndex on detail(dept_id);
如果是CHAR,VARCHAR类型,length可以小于字段实际长度;如果是BLOB和TEXT类型,必须指定length。
ALTER table tableName ADD INDEX indexName(columnName)
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
INDEX [indexName] (username(length))
);
DROP INDEX [indexName] ON mytable;
它与前面的普通索引类似,不同的就是:索引列的值必须唯一,但允许有空值。如果是组合索引,则列
值的组合必须唯一。它有以下几种创建方式:
CREATE UNIQUE INDEX indexName ON mytable(username(length))
ALTER table mytable ADD UNIQUE [indexName] (username(length))
CREATE TABLE mytable(
ID INT NOT NULL,
username VARCHAR(16) NOT NULL,
UNIQUE [indexName] (username(length))
);
有四种方式来添加数据表的索引:
ALTER TABLE tbl_name ADD PRIMARY KEY (column_list):
该语句添加一个主键,这意味着索引值必须是唯一的,且不能为NULL。
ALTER TABLE tbl_name ADD UNIQUE index_name (column_list): 这条语句创建索引的值必须是唯一的(除了NULL外,NULL可能会出现多次)。
ALTER TABLE tbl_name ADD INDEX index_name (column_list): 添加普通索引,索引值可出现多次。
ALTER TABLE tbl_name ADD FULLTEXT index_name (column_list):该语句指定了索引为FULLTEXT ,用于全文索引。
以下实例为在表中添加索引。
mysql> ALTER TABLE testalter_tbl ADD INDEX (c);
你还可以在 ALTER 命令中使用 DROP 子句来删除索引。尝试以下实例删除索引
mysql> ALTER TABLE testalter_tbl DROP INDEX c;
主键只能作用于一个列上,添加主键索引时,你需要确保该主键默认不为空(NOT NULL)。实例如下:
mysql> ALTER TABLE testalter_tbl MODIFY i INT NOT NULL;
mysql> ALTER TABLE testalter_tbl ADD PRIMARY KEY (i);
1、索引列上不能使用表达式或者函数 **
例子:select ...... from product where to_days(out_date) - to_days(current_data)<=30 to_days
就是使用了函数,out_date就是索引列。
优化后:select ...... from product where out_date<=data_add(current_data,interval 30 day)
这样对out_date索引列就没有使用函数。
2、联合索引,如何选择索引的顺序
3、索引不会包含有NULL值的列 **
只要列中包含有NULL值都将不会被包含在索引中,复合索引中只要有一列含有NULL值,那么这一列对
于此复合索引就是无效的。所以我们在数据库设计时不要让字段的默认值为NULL。
4、索引列排序 *
MySQL查询只使用一个索引,因此如果where子句中已经使用了索引的话,那么order by中的列是不会
使用索引的。因此数据库默认排序可以符合要求的情况下不要使用排序操作;尽量不要包含多个列的排序,如果需要最好给这些列创建复合索引。
5、like语句操作 **
一般情况下不鼓励使用like操作,如果非使用不可,如何使用也是一个问题。like “%aaa%” 不会使用索引而like “aaa%”可以使用索引。
eg:最后说一下:MySQL只对一下操作符才使用索引:<、<=、=、>、>=、between、in以及某些时候的
like(不以通配符%或_开头的情形)。而理论上每张表里面最多可创建16个索引。
索引根据其构造结构可以分为 : B-tree索引, B+tree索引, Hash索引,全文索引,空间数据索引(R-Tree),分行树索引(TokuDB中使用)
先介绍几种树的概念:
B树是二叉的排序树,也叫二叉查找树
红黑树是B树的变种,是平衡的二叉排序树
B-Tree 也是B树的改进,而不过二叉变成了多叉,而且非叶子节点中也存储了数据,搜索有可能到非叶结点就结束。
B+Tree 是B-tree的变种,所有的关键字都出现在叶子节点上,一次查找搜索必然是到叶子节点上才结束的。
B-tree 是一种平衡的多叉排序树,,,B-Tree它的特点如下:(M代表着阶数,代表着一个节点最多有多少个孩子节点,例如M阶B树代表着该B树的节点的孩子节点最多有M个)
定义任意非叶子结点最多只有M个儿子;且M>2;
根结点的儿子数为[2, M];
除根结点以外的非叶子结点的儿子数为[M/2, M];
每个结点存放至少M/2-1(取上整)和至多M-1个关键字;(至少2个关键字)
非叶子节点的关键字个数 = 指向儿子的指针个数 - 1;
非叶子结点的指针:P[1], P[2], …, P[M];其中P[1]指向关键字小于K[1]的子树,P[M]指向关键字大于K[M-1]的子树,其它P[i]指向关键字属于(K[i-1], K[i])的子树;
所有的叶子节点位于同一层
大部分的定义和B-Tree相同,但是它有独特于B-tree的地方,
MySQL 中 的 InnoDB和MyISAM存储引擎使用的就是B+Tree的实现方案:
在InnoDB中,数据的物理存放顺序是按照设定聚簇索引的列的顺序进行组织的(实质上是按照主键的顺序组织数据),聚簇索引(一定包含主键,但也可能是主键和其他列的复合索引),对于InnoDB中来说,它的索引文件和数据文件是同一个文件,所以读取进来的页中(也就是一个节点)包含了key和data(key 为索引,data为实际的数据)
{
同时,对于聚簇索引来说, key = 索引键值;data = 实际数据本身
对于非聚簇索引,key = 索引键值, data = 聚簇索引的值
}