数据库系统(Database system)= 数据库管理系统(DBMS,Database Management System)+数据库(Database)
数据库管理系统(DBMS)可分为两类:一类为基于共享文件系统的DBMS,另一类为基于客户机-服务器的DBMS。
Mysql是最流行的关系型数据库管理系统,在WEB应用方面MySQL是最好的RDBMS(Relational Database Management System:关系数据库管理系统)应用软件之一。
MySQL的优点:
MySQL是开源的,所以不需要支付额外的费用。
MySQLMysql支持大型的数据库。可以处理拥有上千万条记录的大型数据库。
MySQL使用标准的SQL数据语言形式。
MySQL可以允许于多个系统上,并且支持多种语言。这些编程语言包括C、C++、Python、Java、Perl、PHP、Eiffel、Ruby和Tcl等。
MySQL对PHP有很好的支持,PHP是目前最流行的Web开发语言。
MySQL支持大型数据库,支持5000万条记录的数据仓库,32位系统表文件最大可支持4GB,64位系统支持最大的表文件为8TB。
MySQL是可以定制的,采用了GPL协议,你可以修改源码来开发自己的Mysql系统。
业务开发:懂基本SQL语句的编写。
SQL优化:懂索引,懂引擎。
分库分表,懂主从,懂读写分离。
安全,懂权限,懂备份,懂日志。
在关系数据库中,索引是一种单独的、物理的对数据库表中一列或多列的值进行排序的一种存储结构,它是某个表中一列或若干列值的集合和相应的指向表中物理标识这些值的数据页的逻辑指针清单。(百度百科)
从上面的定义中我们可以知道,索引是一种存储结构;是数据库表中一列或若干列值的集合,或者是指向表中数据页物理标识的逻辑指针清单。
索引在数据库中叫做键(Key),是存储引擎用于快速找到记录的一种数据结构,当表中数据量增大的时候,索引对性能的影响愈发重要,因此索引优化是查询性能优化最有效的手段。
创建表:
CREATE TABLE `example_table` ( `id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT '自增ID', `name` varchar(10) NOT NULL COMMENT '姓名', `age` smallint(5) unsigned NOT NULL COMMENT '年龄', `card_id` smallint(5) unsigned NOT NULL COMMENT '学生卡号', `create_time` datetime DEFAULT NULL COMMENT '创建时间', `update_time` timestamp NULL DEFAULT NULL ON UPDATE CURRENT_TIMESTAMP COMMENT '表更新时间', PRIMARY KEY (`id`), UNIQUE KEY `idx_card_id` (`card_id`), KEY `idx_age` (`age`,`create_time`) ) ENGINE=InnoDB AUTO_INCREMENT=30 DEFAULT CHARSET=utf8;B-Tree索引(技术上的B+树):对于上图表中索引结构,给出可能的索引数据结构。
B-Tree可以加快访问数据的速度,存储引擎不会进行全表扫描而是从索引的根节点进行搜索,向下查找。B-Tree对索引列是按照顺序存储的,适合范围查找。B-Tree索引对多个值的排序根据创建语句定义的顺序查找,B-Tree索引只适用全键值,键值范围或者键值前缀查找,键值前缀查找适合最左前缀查找。 全键值:比如查找age = 18, create_time = 2012-05-25 21:18:12 的人。最左前缀:所有age = 18的人,只是用索引的第一列。匹配列前缀:比如查询age以1开始的所有人,也是只索引的第一列。匹配范围: 比如age > 10 and age < 100的人,也只是索引的第一列。精确怕匹配前一列后一列进行范围查找: 比如 age = 18 and create_time >= 2012-05-25 21:18:12 and create_time <= 2019-05-25 21:18:12 ,索引的前一列准确查询后一列范围查询。只访问索引查询:select age / select age , create_time from example_table where ....,查询字段即使索引,在后续的优化中会对,只查询索引,避免查询数据行的情况 "覆盖索引”;如果不是按照索引的最左前缀查找无法使用索引,因为索引的排序规则根据创建表语句中索引的定义顺序来排序。不能跳过列进行查询,即index(a,b,c),如果查询a = ? and c = ?只能用到第一列索引(a);如果查询中,某个列进行范围查询,后面的列都不能使用索引查询。Hash索引:(Key-Value)
通过哈希函数计算hash值在对应的槽位存放指向对应行数据的指针。 哈希索引只保存哈希值和行指针,而不存放字段值,所以不能使用索引中的值来避免读取行。哈希索引数据不是根据索引值顺序存储的,所以无法排序。哈希索引也不支持部分索引列匹配,因为哈希值是根据所有哈希内容来计算哈希值的。哈希索引只支持等值比较查询,包括=,IN(),<=>,不支持任何的范围查询。访问哈希索引的数据非常快O(1),但是如果哈希冲突严重的话,必须遍历链表来查找对应的数据,代价非常大。全文索引&空间数据索引:可以自己探索下,全文索引多用于搜索引擎(Solr等)
索引优点总结:
索引的列可以保证行的唯一性,生成唯一的rowId
索引大大减少了服务器需要扫描的数据量,可以有效缩短数据的检索时间
索引可以帮助服务器避免排序和临时表
索引可以将随机I/O改成顺序I/O
索引缺点总结:
创建索引和维护索引需要时间成本,这个成本随着数据量的增加而加大
创建索引和维护索引需要空间成本,每一条索引都要占据数据库的物理存储空间,数据量越大,占用空间也越大(数据表占据的是数据库的数据空间)
会降低表的增删改的效率,因为每次增删改索引需要进行动态维护,导致时间变长。
聚簇索引是对磁盘上实际数据重新组织以按指定的一个或多个列的值排序的算法。特点是存储数据的顺序和索引顺序一致。 一般情况下主键会默认创建聚簇索引,且一张表只允许存在一个聚簇索引。
聚簇索引的叶子节点就是数据节点,而非聚簇索引的叶子节点仍然是索引节点,只不过有指向对应数据块的指针。
MYISAM是按列值与行号来组织索引的。它的叶子节点中保存的实际上是指向存放数据的物理块的指针。 从MYISAM存储的物理文件我们能看出,MYISAM引擎的索引文件(.MYI)和数据文件(.MYD)是相互独立的。而InnoDB按聚簇索引的形式存储数据,所以它的数据布局有着很大的不同
INNODB的二级索引与主键索引有很大的不同。InnoDB的二级索引的叶子包含主键值,而不是行指针(row pointers),这减小了移动数据或者数据页面分裂时维护二级索引的开销,因为InnoDB不需要更新索引的行指针。
INNODB和MYISAM的主键索引与二级索引的对比:
InnoDB的的二级索引的叶子节点存放的是KEY字段加主键值。因此,通过二级索引查询首先查到是主键值,然后InnoDB再根据查到的主键值通过主键索引找到相应的数据块。而MyISAM的二级索引叶子节点存放的还是列值与行号的组合,叶子节点中保存的是数据的物理地址。所以可以看出MYISAM的主键索引和二级索引没有任何区别,主键索引仅仅只是一个叫做PRIMARY的唯一ID.
字段的选取(最小原则) 越小的数据类型,通常处理的速度更快,因为占用的磁盘,内存,CPU缓存更少,处理时需要的CPU周期也更短。对于不确定的数值范围,选取最小的可储蓄类型。 数据类型数值范围字节常用场景tinyint unsigned0-2551表示人的年龄等smallint unsigned0-655352乌龟年龄等int unsigned0-42.9亿4恐龙化石时间等bigint unsigned0-10^198太阳的年龄char(N)最大为N个字节N对于固定长度的字段(比如人名)varchar(N)最大为N个字节,N尽量小于255/5000N根据业务需求datatime1601-9999年8常用的日期储蓄timestamp1601-9999年4有自动更新机制,update_time简单原则 简单的数据类型需要的CPU周期更短,整形比字符整体的操作代价少很多,建议IP的储蓄用整型。尽量避免使用NULL 通常情况下,字段设置为NOT NULL,NULL为默认属性,对于查询来说有NULL的列,MySql优化很难,查询起来会更麻烦,占用的储蓄空间可更多SQL查询优化 查询优化,在where以及order by 涉及的字段上建立索引。避免使用where 属性 = null,这样MySQL会进行全局查询。避免在where使用 != 或 < > 等字段。避免where 与 or 进行连接查询,使用 union all 进行代替.避免使用 in 和 not in 等,连续的范围尽量用between避免使用like "%XX%".避免where 的字段使用表达式操作.where num/2 = x等避免where的字段使用函数操作。字段含有大量的相同值比如(sex..),索引的优化没有效果,,MySQL根据字段的内容进行优化,因此进行建立索引;索引提高的select 的效率,但降低了insert ,update的效率,建议索引最多建立6个.字段的内容如果都为数字的话,避免使用字符作为属性,字符根据每个字符进行比较,数字只会比较一次;select * from table,尽量使用字段代替 * ,减少查询量,即使需要查询字段也要用全部字段代替 *。维护索引的代价比较高,主键索引尽量使用自增形式(数据库自增/业务实现自增ID),避免不必要的索引页调整。。 数据库版本,服务器内存与性能对比(X轴表示内存容量GB,Y轴每秒查询次数