内容多摘自《MySQL技术内幕:SQL编程》
联机事务处理(OnLine Transaction Processing),也被称为面向交易的处理系统,是传统数据库的主要应用,主要是面向基本的、日常的事务处理。例如银行交易。
联机分析处理(OnLine Analysis Processing),是数据仓库系统的主要应用,支持复杂的分析操作,侧重决策支持,并且提供直观易懂的查询结果。
第三方的,特点是存储是按照列而非行的,因此非常适合OLAP的数据库应用。
网易公司开发的面向其内部使用的存储引擎。目前的版本不支持事务,但提供压缩、行级缓存等特性。。。
数据库设计之三范式与反范式
UNSIGNED
,可能会带来意想不到的效果,对于INT类型可能存放不了的数据,可以在设计阶段提升为BIGINT类型。ZEROFILL
对列的数字,比如int(4)的数字1,查询的话,显示结果为0001
。UNSIGNED
属性。DATETIME
:占8个字节,范围1000-01-01 00:00:00到9999-12-31 23:59:59
DATE
:占3个字节,范围1000-01-01到9999-12-31
TIMESTAMP
:占用4字节,范围1970-01-01 00:00:00 UTC 到 2038-01-19 03:14:07 UTC。显示结果和DATETIME
一样,实际存储的内容为1970-01-01 00:00:00到当前时间的毫秒数。
UTC:协调世界时,又称世界统一时间、世界标准时间和国际协调时间。
区别:
TIMESTAMP可以在建表时给默认值,DATETIME不行。
更新表时,可以设置TIMESTAMP列自动更新时间为当前时间
YEAR:占用1个字节,可以在定义时指定宽度。YEAR(4)范围19012155;YEAR(2)范围19702070。YEAR(2)设置下的0069代表20002069
TIME:占用3个字节,范围-838:59:59~838:59:59.
CHAR
和VARCHAR
:CHAR(N)
用来保存固定长度的字符串,VARCHAR(N)
用来存储变长字符类型。CHAR(N)
中N
的范围0255;VARCHAR
中N
的范围065535.这里的N
都代表字符长度而非字节长度。BINARY
和VARBINARY
:BLOG
和TEXT
BLOG
(Binary Large Object):用来存储二进制大数据类型的,大多数情况下可以看做是足够大的VARBINARY
类型的列TEXT
:可以看做是足够大的VARCHAR
类型的列。VARBINARY
和VARCHAR
不同的地方在于:ENUM
和SET
ENUM
最多可枚举65536个元素,SET
最多可枚举64个元素AVL
树。B+树索引的本质就是B+树在数据库的实现,而B+树索引在数据库中的一个特点就是高扇出性
(例如:在InnoDB存储引擎中,每个页的大小为16KB。因此在数据库中,每个B+树的高度一般在2~4
层,意味着查找某一个键值最多只需要2~4
次IO操作。而现在一般的磁盘每秒至少可以做100次IO操作。)。
索引是在存储引擎中实现的,因此每个引擎的B+树的实现方式可能是不同的,取决于存储引擎本身。
B+树索引可以分为聚集索引和辅助索引(非聚集索引),区别在于存放数据的内容。
InnoDB存储引擎是索引组织表(Index Organized Table,IOT),也就是说数据文件本身 就是按照B+树方式存放数据的。其中B+树的键值为主键,若在建立时没有显式的指定主键,则InnoDB默认会自动创建一个6字节的列作为主键。
因此在InnoDB引擎中,可以将B+树索引分为聚集索引和辅助索引。无论哪种索引,每个页的大小都是16KB,且不能更改。
根据主键创建的一颗B+树,聚集索引的叶子节点存放了表中的所有记录。
根据索引键创建的一颗B+树,与聚集索引不同的是,其叶子节点仅存放索引键值,以及该索引键值指向的主键。
也就是说,通过辅助索引来查找数据,那么当找到辅助索引的叶子节点后,很可能还需要根据主键值查找聚集索引来得到数据,这种查找方式又被称为书签查找。
因为辅助索引不包含行记录的所有数据,这就意味着每页可以存放更多的键值,因此其高度一般都要小于聚集索引。
若辅助索引时一个包含主键的联合索引,那么并不需要一个额外的列来存放主键。辅助索引会选择通过联合索引中的主键进行查找。
MyISAM存储引擎其实更像一张堆表,所有的行数据都存放与MYD
文件中,其B+树索引都是辅助索引,存放与MYI
文件中。PRIMARY_KEY
索引和其它索引不同之处在于其必须是唯一的,并且不可为NULL值。其索引页大小默认为1KB
,同样不可以调整。与InnoDB不同的是,因为没有聚集索引,其索引叶节点存放的键值不是主键值,而是在MYD
文件中的物理位置。
并不是所有在查询条件中出现的列都需要加索引。一般经验是:在访问表中很少一部分行时使用B+树索引才有意义。
比如性别字段(只有男、女)这种,取值范围较小,称为低选择性的。以性别为条件查询出的结果是表中50%的数据(假设男女比例1:1),此时设置B+树索引就完全没必要。
如果某个字段取值范围很广,几乎没有重复的,就是高可选择性的。
如何查看索引是否是高可选择性的:
通过SHOW INDEX
语句中的Cardinality
列来观察,Cardinality表示索引中唯一记录数量的预估值。在实际应用中,Cardinality/n_rows_in_table
应尽可能接近1,如果非常小,就需要考虑是否还要建这个索引。
SHOW INDEX FROM table_name
对表上的多个列(大于等于2)进行索引。
假定有两个整型列组成的索引,两个键值分别为a、b。
索引结构如图:
可以看到键值都是排序的,通过叶子节点可以逻辑上顺序的读出所有数据:(1,1),(1,2),(2,1),(2,4),(3,1),(3,2)。数据按照(a,b)的顺序存放。
显然,当查询SELECT * FROM TABLE WHERE a=xxx and b=xxx
,可以使用这个(a,b)索引。SELECT * FROM TABLE WHERE a=xxx
也可以使用这个(a,b)索引,SELECT * FROM TABLE WHERE b=xxx
,不可以使用这个索引。
InnoDB支持覆盖索引,或称索引覆盖。即从辅助索引中就可以得到查询的记录,而不需要查询聚集索引中的记录。
个人理解:当你要查询的记录通过辅助索引就可以查到,这时的辅助索引就可以称为覆盖索引。
使用覆盖索引的好处是辅助索引不包含整行记录的信息,故其大小要远小于聚集索引,因此可以减少大量的IO操作。
InnoDB版本小于1.0或者MySQL版本为5.0或以下的,不支持。
某些情况下,当执行EXPLAIN
时,会发现优化器并没有选择索引去查找数据,而是通过扫描聚集索引,也就是直接进行全表扫描来得到数据。这种情况多发生于范围查找、JOIN操作等。
SELECT * FROM orderdetails WHERE orderid>10000 and orderid <10200;
orderid
的单个索引。但是优化器却选择了PRIMARY
索引,而非orderid辅助索引。MySQL支持INDEX HINT显式的告诉优化器使用哪个索引。SELECT * FROM table USE INDEX(a) WHERE a=1 AND b=2
USE INDEX
只是告诉优化器可以选择该索引,但实际上优化器会根据自己的判断进行选择。
如果确定用哪个索引来完成查询时,最可靠的是使用FORCE INDEX
而不是USE INDEX
。
索引查询失效的情况
MySQL索引优化铁则
索引分析的工具:explain
命令加在要执行的sql语句前面,执行结果中的key
这一列,就是用到的索引,如果为NULL,则说明没有使用索引。
like
以%
开头时。
前缀没有%
,后缀有%
则依然有效
or
语句前后没有同时使用索引时。or
左右查询字段只有一个是索引,该索引失效;左右的字段都是索引时,索引才有效。
组合索引,不是使用第一列索引,索引失效。
失效原理,见:索引>联合索引中的图解
数据类型出现隐式转化。
如:varchar
不加单引号的话可能会自动转化为int
类型,使索引失效,变成全表扫描。
在索引列上使用not、<>、!=
。
不等于操作是永远都不会用到索引的。
对索引字段进行计算操作、字段上使用函数。
当全表扫描速度比索引查询的速度快时,MySQL会使用全表扫描,此时索引失效。
假设有id=10
这行数据的name=张三
,现在要更新为xxx
,此时得先把要更新的原来的值张三
和id=10
这些信息,写入到undo日志文件中去。用于回滚
redo日志存的是对数据做了什么修改,比如对id=10
这行记录修改了name
字段的值为xxx
。可用于异常宕机时恢复,可以继续执行
又叫做归档日志。记录的是偏向于逻辑性的日志,类似于:对users表中id=10这样数据做了更新操作,更新以后的值是xxx
。
binlog日志不是InnodB存储引擎特有的额,是属于MySQL server自己的日志文件。可用于数据恢复,主从复制
版权说明 : 本文为转载文章, 版权归原作者所有 版权申明
原文链接 : https://www.cnblogs.com/onlyrun/p/15164826.html
内容来源于网络,如有侵权,请联系作者删除!