主键索引:数据列不容许重复,不容许为NULL。一个表只能有一个主键索引。InnoDB的主键索引为聚簇索引,而MyISAM的主键索引为非聚簇索引。 建立:ALTER TABLE table_name ADD PRIMARY KEY (column);
mysql
惟一索引:数据列不容许重复,容许为NULL,一个表中容许建立多个惟一索引。惟一索引能够用做业务防重。 建立:ALTER TABLE table_name ADD UNIQUE (column1, column2);
git
普通索引:基本的索引类型,没有惟一性的限制,容许为NULL值。 建立:ALTER TABLE table_name ADD KEY (column1, column2)
github
全文索引:是目前搜索引擎使用的一种关键技术,InnoDB不支持全文索引,MyISAM支持全文索引。 建立:ALTER TABLE table_name ADD FULLTEXT (column);
算法
联合索引从左边的列到右边的列依次匹配,联合索引的最左前缀原则以下: 对于联合索引:index(co1, col2, col3)sql
where col1=1
,where col1=1 and col2=2
,where col1=1 and col2=2 and col3=3
都会走这个索引。第一个语句使用 col1,第二个语句使用 col1,col2,第三个使用 col1,col2,col3;where col2=2
,where col2=2 and col3=3
不会走索引;where col3=3 and col2=2 and col1=1
未经查询优化的话不会走索引,可是通过查询优化后会走索引...;where col1=1 and col3=3
仅使用 col1;where col1=1 and col2>2 and col3=3
仅使用 col1,col2;where col1=1 and col2 like 'xx%'
使用 col1,col2;where col1=1 and col2 like '%xx''
仅使用 col1。B-Tree索引:数据库
B-Tree索引是一棵多路查找平衡树,InnoDB 和 MyISAM 存储引擎都支持 B-Tree 索引。InnoDB 支持聚簇索引,InnoDB 默认会为主键建立聚簇索引,聚簇索引的非叶子节点不保存数据,只有叶子节点会保存数据,聚簇索引的叶子节点还会保存相邻的后一个节点的指针。非聚簇索引叶子节点不保存数据,只保存主键索引。缓存
HASH索引:安全
Hash 索引检索效率高,只须要一次定位,不像 B-Tree 索引须要从根节点到叶子节点,最后才能访问到页节点这样屡次的IO访问。 Hash索引虽然检索效率高,可是也有不少的不足之处:并发
Hash 索引仅仅能知足”=”,”IN”和”<=>”查询,不能使用范围查询。 因为 Hash 索引比较的是进行 Hash 运算以后的 Hash 值,因此它只能用于等值的过滤,不能用于基于范围的过滤,由于通过相应的 Hash 算法处理以后的 Hash 值的大小关系,并不能保证和Hash运算前彻底同样。函数
Hash 索引没法被用来避免数据的排序操做。 因为 Hash 索引中存放的是通过 Hash 计算以后的 Hash 值,并且 Hash 值的大小关系并不必定和 Hash 运算前的键值彻底同样,因此数据库没法利用索引的数据来避免任何排序运算;
Hash 索引不能利用部分索引键查询。 对于组合索引,Hash 索引在计算 Hash 值的时候是组合索引键合并后再一块儿计算 Hash 值,而不是单独计算 Hash 值,因此经过组合索引的前面一个或几个索引键进行查询的时候,Hash 索引也没法被利用。
Hash 索引在任什么时候候都不能避免表扫描。 前面已经知道,Hash 索引是将索引键经过 Hash 运算以后,将 Hash运算结果的 Hash 值和所对应的行指针信息存放于一个 Hash 表中,因为不一样索引键存在相同 Hash 值,因此即便取知足某个 Hash 键值的数据的记录条数,也没法从 Hash 索引中直接完成查询,仍是要经过访问表中的实际数据进行相应的比较,并获得相应的结果。
Hash 索引遇到大量Hash值相等的状况后性能并不必定就会比B-Tree索引高。 对于选择性比较低的索引键,若是建立 Hash 索引,那么将会存在大量记录指针信息存于同一个 Hash 值相关联。这样要定位某一条记录时就会很是麻烦,会浪费屡次表数据的访问,而形成总体性能低下。
B-Tree vs. HASH索引
索引名 | HASH | B-Tree |
---|---|---|
是否支持最左前缀匹配原则 | 不支持,只有索引的所有字段都用上才会匹配到 | 支持,用上索引的第一个字段就能够匹配索引 |
MyISAM和InnoDB是否支持 | 不支持(只有Memory和NDB引擎索引支持) | 支持 |
范围查询可否命中索引 | 不能够,只有“=”,“IN”,“<=>”(等价于的意思)查询能命中 | 能够 |
是否必定会全表扫描 | 是 | 否 |
整数: tinyint、smallint、mediumint、int、bigint
type | Storage | Minumun Value | Maximum Value |
---|---|---|---|
(Bytes) | (Signed/Unsigned) | (Signed/Unsigned) | |
TINYINT | 1 | -128 | 127 |
0 | 255 | ||
SMALLINT | 2 | -32768 | 32767 |
0 | 65535 | ||
MEDIUMINT | 3 | -8388608 | 8388607 |
0 | 16777215 | ||
INT | 4 | -2147483648 | 2147483647 |
0 | 4294967295 | ||
BIGINT | 8 | -9223372036854775808 | 9223372036854775807 |
0 | 18446744073709551615 |
浮点数: float、double、real、decimal
属性 | 存储空间 | 精度 | 精确性 | 说明 |
---|---|---|---|---|
FLOAT(M, D) | 4 bytes | 单精度 | 非精确 | 单精度浮点型,m总个数,d小数位 |
DOUBLE(M, D) | 8 bytes | 双精度 | 比Float精度高 | 双精度浮点型,m总个数,d小数位 |
FLOAT容易形成精度丢失
定点数DECIMAL
date、time、datetime、timestamp、year
类型 | 字节 | 例 | 精确性 |
---|---|---|---|
DATE | 三字节 | 2015-05-01 | 精确到年月日 |
TIME | 三字节 | 11:12:00 | 精确到时分秒 |
DATETIME | 八字节 | 2015-05-01 11::12:00 | 精确到年月日时分秒 |
TIMESTAMP | 2015-05-01 11::12:00 | 精确到年月日时分秒 |
5.6.4
版本以后,TIMESTAMP
和DATETIME
支持到微秒。TIMESTAMP
会根据系统时区进行转换,DATETIME
则不会TIMESTAMP
存储范围:1970-01-01 00::00:01 to 2038-01-19 03:14:07DATETIME
的存储范围:1000-01-01 00:00:00 to 9999-12-31 23:59:59TIMESTAMP
国际化BIGINT
字符串: char、varchar 文本: tinytext、text、mediumtext、longtext
类型 | 单位 | 最大 | 特性 |
---|---|---|---|
CHAR | 字符 | 最大为255字符 | 存储定长,容易形成空间的浪费 |
VARCHAR | 字符 | 能够超过255个字符 | 存储变长,节省存储空间 |
TEXT | 字节 | 总大小为65535字节,约为64KB | - |
tinyblob、blob、mediumblob、longblob
MVCC的实现,是经过保存数据在某个时间点的快照来实现的,根据事务开始时间的不一样,每一个事务对于同一张表,同一时刻看到的数据多是不一样的。
InnoDB的 MVCC ,是经过在每行记录的后面保存两个隐藏的列来实现的。这两个列,一个保存了行的建立时间,一个保存了行的过时时间(或删除时间), 固然存储的并非实际的时间值,而是系统版本号。
能够认为MVCC是行级锁的一个变种,可是它在不少状况下避免了加锁操做,所以开销更低。虽然实现机制有所不一样,但大都实现了非阻塞的读操做,写操做也只锁定必要的行。
在MVCC协议下,每一个读操做会看到一个一致性的 snapshot,而且能够实现非阻塞的读。MVCC 容许数据具备多个版本,这个版本能够是时间戳或者是全局递增的事务 ID,在同一个时间点,不一样的事务看到的数据是不一样的。
其中,写操做(insert、delete和update)执行时,须要将系统版本号递增。 因为旧数据并不真正的删除,因此必须对这些数据进行清理,innodb会开启一个后台线程执行清理工做,具体的规则是将删除版本号小于当前系统版本的行删除,这个过程叫作purge。 经过MVCC很好的实现了事务的隔离性,能够达到repeated read级别,要实现serializable还必须加锁。
MVCC只在READ COMMITED 和 REPEATABLE READ 两个隔离级别下工做。READ UNCOMMITTED老是读取最新的数据行,而不是符合当前事务版本的数据行。而SERIALIZABLE 则会对全部读取的行都加锁。
单条索引记录上加锁,InnoDB 的行锁是经过索引实现的,如没有索引,则锁住的不是记录行而是整个表。
间隙锁,锁定一个范围,但不包括记录自己。GAP锁的目的,是为了防止同一事务的两次当前读,出现幻读的状况。
Next-key lock 就是 Record lock + Gap lock 的组合,它锁定的是一个范围,而且锁定记录自己。对于行的查询,都是采用该方法,主要目的是解决幻读的问题。
mysql的事务隔离级别是可重复读(RR,Repeatable Read),而且 innodb_locks_unsafe_for_binlog
参数设置为0
truncate 和 delete只删除数据,不删除表结构 ,drop删除表结构,而且释放所占的空间。
删除数据的速度,通常来讲: drop> truncate > delete
delete属于DML语言,须要事务管理,commit以后才能生效。drop和truncate属于DDL语言,操做马上生效,不可回滚
使用场合:
explain 用于查看 SQL 语句执行计划,其结果主要包含如下几个重要参数:id、select_type、table、type、possible_keys、key、key_len、ref、rows、Extra,下面对这些字段出现的可能进行解释。
表示查询中每一个select子句的类型
表示MySQL在表中找到所需行的方式,又称“访问类型”。
经常使用的类型有: ALL, index, range, ref, eq_ref, const, system, NULL(从左到右,性能从差到好)
指出MySQL能使用哪一个索引在表中找到记录,查询涉及到的字段上若存在索引,则该索引将被列出,但不必定被查询使用 该列彻底独立于EXPLAIN输出所示的表的次序。这意味着在possible_keys中的某些键实际上不能按生成的表次序使用。 若是该列是NULL,则没有相关的索引。在这种状况下,能够经过检查WHERE子句看是否它引用某些列或适合索引的列来提升你的查询性能。若是是这样,创造一个适当的索引而且再次用EXPLAIN检查查询
key列显示MySQL实际决定使用的键(索引) 若是没有选择索引,键是NULL。要想强制MySQL使用或忽视possible_keys列中的索引,在查询中使用FORCE INDEX、USE INDEX或者IGNORE INDEX。