一。关于表连接
1. 表连接主要包括外连接和内连接,内连接只是选出连接的两张表中的相匹配的记录,但是外连接会选出其它不匹配的记录。内连接和外连接有不同的应用场景。
2. 左连接是以左边表中的记录为准,如果右边表中没有和左边表相匹配的记录,左边表的记录还是会显示。
3. 右连接是以右边表中的记录为准,如果左边表中没有和右边表相匹配的记录,右边表的记录还是会显示。
4. 由2和3中可以知道,左连接和右连接是可以互相转换的
二。关于内建函数,需要用的时候可以查表,尽量使用这些函数,避免自己实现
1. 字符串函数,concat等
2. 数值函数,rand函数
3. 日期和时间函数,unix_timestamp(date)和from_unixtime()
4. 流程函数,比如if,和casewhen
5. 其它常用函数,Ip和long转换,md5,password函数等
三。关于存储引擎,根据不同的应用类型选择合适的存储引擎
1. 常用的存储引擎包括innodb和myisam,其中myisam主要用于OLAP的应用,innodb主要用于OLTP的应用。
2. myisam表文件:.frm(表定义).myd(存储数据).myi(存储索引)
3. myisam表支持的存储格式:
a. 静态表(每条记录都是固定长度,存储非常迅速,容易缓存,缺点是占用的空间比动态表多,因为存储的时候会按照列的宽度定义来补足空格)
b. 动态表(包含变长字段,记录不是固定的长度,存储占用空间相对少,但是频繁更新删除会造成碎片,需要执行optimize table)
c. 压缩表(占据磁盘空间很小,每个记录单独压缩)
4. innodb自动增长列必须是索引,如果是组合索引,必须是组合索引的第一列。
5. innodb支持外键,外键约束详见:
6. innodb存储表和索引有共享表空间和多表空间存储的形式。及时在多表空间的存储方式下,共享表空间仍然是必须的,innodb会把内部数据词典和未作日志放在这个文件之中。
7. 如果应用以读操作和插入操作为主,只有很少的更新和删除操作,并且对事务的完整性,并发性要求不高,那么就选择myisam引擎。如果对事务的完整性要求比较高,在并发情况下 要求数据的一致性,数据CRUD操作都有,那么选择innodb存储引擎,这样可以有效的降低由于删除和更新导致的锁定,确保事务的完整性。
四。关于数据类型
1. 少量字符串的时候选择char和varchar,大量文本的时候用text或者blob,blob用来保存二进制数据。不过blob和text在删除操作的时候会留下很大的空洞,以后填入这些空洞的记录在插入的性能上会有影响。可以用optimize table来整理碎片。小技巧是可以使用合成索引(根据大文本来建立一个散列值)提高查询性能,不过只能应用于精确查找。
2. 浮点数要注意精度和四舍五入的问题。在一些精度要求比较大的应用中应该使用定点数或者字符串来存储数据。
3. 根据实际需要来选择满足应用的最小存储的日期类型。datetime类型记录的年份能够比较久远,timestamp能够和实际时区相对应。
五。关于字符集
1. 关于常用的编码知识,详见:
2. 在选择数据库字符集的时候需要根据应用的需求来的ing,是否满足应用所支持的语言的需求,是否需要处理各种各样的蚊子,或者发布到不同语言的国家和地区。如果数据库中已经存在了数据,还需要充分考虑数据库字符集对已有数据的兼容性。比如汉字编码比较多,那么可以选择GBK,因为GBK汉字占用两个字节,UTF8占用三个字节,如果仅有少量汉字数据,那么选择UTF8好,因为UTF8英文字符只需要一个字节,其余的GBK或者UTF16都需要两个字节来对西文字符进行编码。
3. mysql保存数据的字符集和校对规则有4个级别的默认设置:服务器级别,数据库级别,表级别和字段级。分别在不同的地方设置,作用也不同。
4. 还需要注意客户端和服务器之间交互的字符集和校对规则,mysql提供了三个不同的参数来代表客户端,连接和返回结果的字符集,通常情况下,这三个字符集应该是一样。
5. 字符集的修改步骤:
六。关于索引
1. 索引的列的值波动范围越大,索引的效果越好。
2. 如果对字符串列进行索引,应该指定一个前缀长度,这样能够节省大量的索引空间。
3. 利用最左前缀,在创建一个N列的索引时,实际上是创建了mysql可利用的N个索引。多列索引可以起几个索引的作用,因为可利用索引中最左边的列集来匹配,这样的列称为最左前缀
4. 不要过度索引,索引会占用磁盘空间,降低写操作的性能,此外,mysql在生成一个执行计划的时候需要考虑各个索引,这也会花费时间。
5. innodb记录默认会按照主键或者唯一索引来保存记录,要选择最常访问的列作为主键,提高查询效率。innodb的表的普通索引也都会保存主键的键值,所以主键要尽可能选择较短的数据类型,这样可以减少索引的磁盘占用。
6. btree索引的介绍:
7. 大多数的mysql索引(primarykey,unique,index和fulltext)在btree中存储。空间列类型的索引使用RTREE,并且memory表还支持hash索引。
七。关于视图
八。关于存储过程和函数
1. 存储过程的详细语法介绍:
2. 存储过程和函数的优势是可以将数据的处理放在数据库服务器上进行,避免将大量的结果集传输给客户端,减少数据的传输,但是数据库服务器上进行大量的运算也会占用服务器的CPU,造成数据库服务器的压力,所以要仔细斟酌。
九。关于触发器
1. 触发器是与表相关的数据库对象,在满足定义条件时出发,并且执行触发器中定义的语句集合。作用是可以协助应用在数据库端确保数据的完整性。
2. 触发器的语法详见:
十。事务和锁
1. mysql支持对myisam的表级锁定,对innodb的行级别锁定。当与服务器的连接被关闭的时候,所有由当前线程锁定的表都会被解锁。
2. myisam锁和事务详细列子:
3. 分布式事务:
十一。sql安全和sql mode
1. sql注入:程序对用户输入的数据没有进行严格的过滤,导致非法数据库查询语句的执行,同理的还有xss注入。java中采用prepareStatement来防止sql注入。
2. sqlmode:通过设置sql mode,可以完成不同严格程度的数据校验,有效的保障数据的准确性。
十二。复杂sql的编写
1. groupby和having, with rollup, bit函数,rand()函数
十三。优化SQL语句
1. show status命令来了解当前数据库的情况,比如查询更新的比例,事务执行情况,慢查询的次数,连接次数等
2. 慢查询日志一定要开启,通过查看慢查询日志来定位执行很慢的sql语句。show processlist命令可以查看当前mysql在进行的线程,包括线程的状态,是否锁表。
3. 使用explain和desc命令来查询sql执行计划。关于explain命令的详细解释:
4. sql执行使用的索引问题。
5. 定期分析表和检查表,优化表。
6. 大批量插入数据,先关闭索引更新然后load,再打开索引。
7. innodb类型的表按照主键顺序保存,所以导入数据按照主键顺序排列可以提高导入数据的效率。在导入数据前关闭唯一性校验也可以提高导入效率。
十四。索引
1. myisam存储引擎的表的数据和索引是分开存储的,innodb存储引擎的表的数据和索引时存储在同一个表空间里的。
2. 查询中使用索引的最主要条件是查询条件中使用了索引关键字,如果是多列索引,那么只有查询条件使用了多列关键字最左边的前缀时才可以使用索引,否则不能使用索引,索引具有前缀特性。
3. mysqlBTREE索引的详细解释:
4. 对于like查询,后面如果是常量并且只有%不在第一个字符,索引才可能被使用
5. mysql在以下情况下不会使用索引:比如使用索引比全表扫描更慢,hash索引where条件中不使用=,用or分隔开的条件,如果or前的条件中的列有索引,后面列中没有,那么不会用到索引。
6. 使用show status like "Handler_read%"查看索引使用情况
十五。优化数据库对象
1. 优化表的数据类型,在表运行一段时间之后使用函数procedure analyse来对表进行分析,优化表的字段类型。
2. 对表进行拆分,包括垂直拆分和水平拆分。垂直拆分以后查询所有数据需要join,水平拆分查询数据需要union。水平拆分可以按照时间或者按照某个列
3. 设计表的时候可以适当的增加冗余字段,这样可以降低连接操作的需求,不必死守数据库规范。但是这样在更新的时候可能会造成数据的不一致,所以需要定期更新或者使用触发器。
十六。锁问题
1. 锁冲突是影响数据库并发访问性能的一个重要因素。所以理解sql语句执行的时候是否会加锁以及加什么锁很重要。主要用到mysql表所和innodb行锁。
2. mysql锁分为表级锁,行级锁,页面锁。innodb支持行级锁和表级锁。myisam支持表锁。表级锁不会出现死锁,但是锁定粒度大,发生锁冲突的概率最高,并发度最低。行级锁开销大,会出现死锁,锁定粒度最小,发生锁冲突的概率最低,并发度也最高。
3. myisam在执行查询select前,会自动给涉及的所有表加读锁,在执行(update,delete,insert)前,会自动给涉及的表加写锁。但是显式加锁必须要手动解锁,在执行lock tables后,只能访问显式加锁的这些表,不能访问未加锁的表。myisam总是一次获得SQL语句锁需要的全部锁,所以myisam表不会出现死锁。
4. myiasm表锁的例子:
5. innodb锁问题。
十七。事务
1. 事务ACID属性,原子性:事务是一个原子操作单元,其对数据的修改,要么全都执行,要么全都不执行。一致性:在事务开始和完成时,数据都必须保持一致状态。隔离性:数据库系统提供一定的隔离机制,保证事务在不受外部并发操作影响的独立环境执行。持久性:事务完成之后,它对于数据的修改是永久性,及时出现系统故障也能够保持。
2. 并发事务处理会提高数据库系统的事务吞吐量,从而可以支持更多的用户,但是也会带来一些问题,主要包括:更新丢失,脏读,不可重复读,幻读。
3. 更新丢失是应用的责任,脏读不可重复读以及幻读,这是数据库读一致性的问题,必须由数据库提供一定的事务隔离机制来解决。数据库实现事务隔离的方式,基本上分为两种,一种是加锁,另外一种是MVCC(不加锁,通过一定机制生成一个数据请求时间点的一致性数据快照)
4. 为了处理隔离与并发的矛盾,有4个事务隔离级别,RU,RC,RR,S。事务隔离级别对应的例子:
十八。备份和恢复
1. mysql的主从备份就是slave mysql在不断的做基于BINLOG的恢复。主从备份有多重级别,比如基于行级别,或者基于sql语句级别,或者两者兼顾
3. 备份分为逻辑备份和物理备份,逻辑备份使用mysqldump,myisam存储引擎在备份的时候需要加锁来保证数据的一致性,对于innodb来说通过--single-transaction可以获得一个快照,这样使备份的数据能够保持一致性。恢复很简单,直接将mysqldump的输出当成输入执行即可。可以打开备份文件看看内容。
4. 表的导出可以select into outfile,mysqldump也可以。导入可以用load data infile。
十九。mysql日志
1. mysql有四种日志,分别是错误日志,二进制日志(binlog日志),查询日志和慢查询日志。
2. 错误日志用于记录数据库出现的问题,当系统故障的时候首先要检查错误日志。
3. 二进制日志使用mysqlbinlog来查看,binlog比较大,需要定期删除。在主从备份的环境中需要确保从库已经拷贝了binlog,以免备份发生问题。
4. 查询日志记录了客户端的查询操作,对于访问频繁的系统,此日志对系统性能的影响比较大。一般关掉
5. 慢查询日志记录了包含所有执行时间超过参数long_query_time所设置值的sql语句的日志。
二十。mysql权限
1. mysql的权限是通过用户名和ip地址来确定的。mysql数据库里面的user,host,db表
参考资料:书籍《深入浅出,mysql数据库开发,优化与管理维护》