Mysql

Posted miraclemaker

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Mysql相关的知识,希望对你有一定的参考价值。

1.什么是ER图:

  • 表示实体,属性和联系的图
  • 实体:业务对象,矩形表示。
  • 属性:实体的属性字段,椭圆形表示。
  • 联系:实体与实体间的关系,能表示业务关系和数量关系,菱形表示。

2.数据库三范式:

  • 1NF:属性不可再分。
  • 2NF:1NF+非主键列不能对主键的子集产生依赖。
    3NF:1NF+2NF+非主键列不能依赖其他非主键列。
  • 如果不满足的话,可能数据会很杂乱,很多不应该在一起存放的数据存放在一起,删除的时候就会删多;更新的时候更新的多,考虑的多;

3.外键:

  • 主键与外键:

。主键:一个表只能有一个主键,不能为NULL,不能重复。

。外键:一个表可以有多个外键,外键可以为NULL(尚不确定映射到其他标的哪一行),可以重复(可能映射到其他表的好几行,一个员工映射十个订单)。

  • 为什么不推荐级联:级联是指更新数据后引发数据库的一连串更新

。存在外键增加了复杂性,编写代码的时候要时刻考虑外键约束;

。数据库为了维护外键,会触发一些检查,拖慢了响应速度;

。大数据下的分库分表无法使用外键。

4.DML跟DDL:

  • DML:数据库操作语言,对数据表的增删改查。
  • DDL:数据库定义语言,对数据库内部对象的增删改。

5.内连接左连接右连接的区别:

  • 内连接:查询两张表的交集部分。
  • 左连接:我们一般用左外连接,查询左表全部数据及两表交集(可以查出左表中链接字段为null的数据)
  • 右连接:右连接可以化为左连接。

6.数据库设计分几步:

  • 分析用户需求,抽取实体,实体属性,实体间的关联关系;
  • 构建ER图,将ER图转化为数据表;
  • 构建数据库,编程测试,试运行;
  • 系统运行,日常维护。

7.sql执行顺序:

  • sql执行顺序:SELECT * FROM * WHERE * GROUP BY * HAVING * ORDER BY * LIMIT * ;
  • 各种函数的使用:distinct,聚合函数,日期函数,字符串函数等都放在select * from中。

8.char和varchar:

  • char:创建的时候指定最大长度,创建后不管进来是多大,长度都固定(最大一个字节,255)
  • varchar:创建的时候指定最大长度,但是会根据字符串长度存储(一到二个字节,最长存2^16),存的1-2^8(加一个额外长度),2^8-2^16(加两个额外长度),时间换空间。

9.sql和nosql:

  • sql:有严格的标准,操作简单,文档丰富,支持事务ACID,可以进行多表复杂查询,分库分表
  • nosql:不支持事务,高性能高扩展性,更灵活,适合海量数据存储。

。类型分为文档型(MongDB),键值(Redis),图形(Neo4j),宽列(HBase)。

10.mysql的体系结构:

  • 连接层:管理连接,权限认证;
  • 服务层:完成大部分功能,如语法分析,sql优化,缓存查询,存储过程,函数的执行;
  • 引擎层:真正负责数据的存储和读取,提供接口,不同的存储引擎有不同的功能;
  • 存储层:存储数据,与引擎层交互。

11.存储引擎:

  • 定义:决定数据CRUD如何实现,不同的表可以有不同的存储引擎,亦可以自己编写存储引擎。
  • InnoDB和MyIsAm的区别:

。InnoDB(默认):支持事务,外键,行级锁,能解决幻读问题,聚集索引

。MyIsAm:大部分操作都是读和插入时适用,不支持事务,外键,行级锁,崩溃后无法恢复,采用非聚集索引,被MongDB代替。

13.索引:

  • 定义:快速检索数据的数据结构,InnoDB使用优化后的B+树查找数据。
  • 优缺点:提高查询速度,但同时创建和维护索引也降低了sql执行效率。
  • 实现方式:

。Hash表:虽然快,但是不支持顺序和范围查询。

。Full-Text:对字符,text类型可以加这个全文索引,主要是用于模糊查询,原理是倒排索引,在辅助表中存储着词和文档位置的映射

。B树和B+树:

。B树所有节点既存放key也存放data,查询的时候查询到一半可能就结束了

。B+树只有叶子节点存放key和data,非叶子节点只存放key,并且叶子节点间存在引用链,所以B+树每次都是到叶子结点才能把数据查出来。范围查询不需要回溯。

。innodb优化b+树:叶子结点指针改为双向。

  • 类型:

。主键索引和二级索引:主键索引是指key为主键;二级索引(唯一,普通,前缀)是指data为主键的索引。

。聚集索引和非聚集索引:聚集索引是指data存放的是数据,非聚集索引是指data存放的是数据的地址。

。覆盖索引和联合索引:覆盖索引是指索引包含需要查询的字段值,联合索引是指多个字段创建索引。

  • 建议:选取频繁查询,排序的作为索引,尽量选择联合索引。不选取频繁更新,字段可为NULL的作为索引。
  • 失效:

。能走覆盖索引的情况下使用了你你 SELECT * 进行查询;

。创建了组合索引,但查询条件未准守最左匹配原则;

在索引列上进行计算、函数、类型转换等操作;

。以 % 开头的 LIKE 查询比如 like \'%abc\';

。索引字段上出现!=<> not in时会失效;in后面的数据如果超过30%就会走全表,不走索引。

。查询条件中使用 or,且 or 的前后条件中有一个列没有索引,涉及的索引都不会被使用到;

14.三大日志:

  • mysql操作:mysql操作数据时会将那一数据也的内容都提取出来放到Buffer Pool,后续的操作都是先看Buffer Pool上有没有数据,没有再去磁盘中寻找。
  • redo log:重做日志,物理上记录磁盘中对数据页的修改,先记录到 redo log buffer中,每隔1s,事务提交一次,redo log buffer内存占用超出一半时,刷盘到redo log日志中。
  • binlog:二进制日志,逻辑上记录sql反向语句,先记录到binlog cache,事务提交后写入binlog中。
  • undolog:回滚日志,逻辑上记录sql反向操作,先记录到undolog中,根据回滚指针形成undolog版本链,再进行实际的操作。先于数据库存储到磁盘上
  • redo log 保证持久性,使用 undo log 保证原子性,MVCC保证隔离性,一致性通过A,I,D实现的。
  • redo log和binlog都保证数据库的一致性,但保护层面不同,记录内容,记录时间,执行效率都不同

15事务:

  • ACID:

。原子性:操作要不都起作用,要不都不起作用;

。一致性:操作执行前后,数据从一个一致性状态转换到另一个一致性状态;

。隔离性:并发访问数据库时,事务之间不会互相干扰;

。持久性:事务提交后,对数据的改变是持久的。

  • 隔离级别:读未提交,读已提交,可重复读,串行化。

。脏读:事务a读取到事务b修改的数据,但事务b回滚了,a读到了脏数据。

。不可重复读:事务a两次读同一数据的间隙,事务b修改了数据并提交了。

。幻读:事务a两次读同一数据的间隙,事务b新增了数据并提交。

  • 并发事务的控制方式:锁(悲观)和MVCC(乐观)
  • MVCC:为每个事务生成一个版本数据,保证事务的隔离性,利用隐藏字段,undolog,readview实现

。隐藏字段:每个表创建的时候都会有隐藏的DB_TRX_ID:最近事务的id,DB_ROLL_PTR:回滚指针,指向上一个版本数据,DB_ROW_ID:隐藏主键,没有主键时会自动生成。

。undolog:每次执行操作后都会形成一行记录之前版本的数据,包括DB_TRX_ID和DB_ROLL_PTR指向上上个版本的数据,最终形成一个undolog版本连记录在undolog日志中。

。readview:(不同隔离级别生成readview的时机不同)每次操作后会生成一个readview(四个字段分别记录当前活跃事务id集合,最小活跃事务id,与分配事务id,readview创建者的事务id)记录数据,DB_TRX_ID与这四个字段进行对比来判断具体应该将undolog版本链中的哪一条数据回滚。

16锁:

  • 类别:表锁和行锁,这两种锁都包括共享锁和排它锁
  • 表锁和行锁:

。表锁:资源消耗少,加锁快,锁冲突概率高,性能差。

。意向共享锁:加表锁的时候验证表内有无行锁,意向锁之间互相兼容,只有意向共享锁和表级共享

。意向排他锁:锁兼容,其余均互斥。

。行锁:资源消耗多,加锁慢,锁冲突概率低,性能好。

。记录锁:对记录加锁。

。间隙锁:对记录的间隙加锁,防止插入数据。

。临键锁:记录锁+间隙锁,能够解决幻读问题,mysqlc、查询数据加的都是临键锁,只有查询的字段只包含唯一索引且不是范围查询时,降级为记录锁。

  • 共享锁和排它锁:

。共享锁:事务读取时获取共享锁,读读共享。

。排它锁:事务修改时获取排它锁,与任何都不共享。

17.为什么主键既不连续也不单调:

  • 单调:每次插入数据后,Mysql会自动保存一个值作为下次插入的主键值,如果此时mysql重启了,保存的数据还没更新,就会导致主键还跟上次一致,现在采用了redolog日志解决了这个问题。
  • 连续:插入数据时不会对主键设置事务锁,事务a插入数据主键+1,事务b插入数据主键又+1,若此时事务a回滚了,就会造成主键不连续。

18当前读和快照读:

  • 当前读:读的是最新数据,读的时候加读锁,保证其他事务不会修改这条数据。(修改数据或for update时会发生当前读)
  • 快照读:读的是当前记录的可见版本,多用于对一致性要求低,对性能要求高。

19.性能优化:

  • 开启慢查询日志,或用explain查看sql执行计划,filesoft:排序的字段没加索引;temporary:排序或分组的字段来自其他表;
  • 避免主键过长,避免使用UUID;
  • 对于需要分组和排序的字段最好建立索引;
  • 表中数据是否太大,是不是要分库分表;
  • 写sql语句时做优化:

。select:尽量用select(字段),避免select(*),因为select(*)会多一步查询字段的操作,select(字段)效率稍高,能够明确表达业务需求。

update:where条件要添加索引,否则会锁会从行锁升级为表锁。

。count:尽量使用count(*),避免count(字段)。

。insert:批量插入,开启事务,事务内部采用有序插入和一个insert插入多个value,这样可以避免sql多次重复解析,减少了日志量,避免事务的频繁创建。

。limit:分页查询时,如果偏移量太大,会使得性能很低。将where查询条件用order by分组后再limit;或者业务上商讨不做过多的分页。

20.sql执行计划:

  • explain:在sql语句最前面加上explain关键字就可以显示这条语句的执行效率。

。type:

。key:用到的索引;key_len:用到的索引长度;

。rows:必须要执行查询的行数;

。extra:额外信息:

。Using filesort:在排序时字段没有建立索引。

。Using temporary:需要创建临时表(查询字段来自其他表),常见于 ORDER BY 和 GROUP BY。

。Using index:表明查询使用了覆盖索引,不用回表,查询效率非常高。

。Using index condition:表示查询优化器选择使用了索引条件下推这个特性。

。Using where:表明查询使用了 WHERE 子句进行条件过滤。一般在没有使用到索引的时候会出现。

。Using join buffer:连表查询的方式,表示当被驱动表的没有使用索引的时候

21.MVCC+临键锁防止幻读:

  • 快照读:如果为快照读,那么读取的只是快照,不会出现幻读。
  • 当前读:如果为当前读,那么在读取的时候为数据加上临键锁,防止插入,就不会造成幻读。

22.数据库崩溃恢复后:

  • 已经commit的但还没来得及把数据写入磁盘的,执行前滚(redolog)。
  • 还没commit的,执行回滚(undolog)。

23.count的几种方式:

24.最左前缀法则的生效条件:

  • 根据创建联合索引的顺序,依次对你的where条件进行检测。遇到范围(<,>,between,like)当前算上之后就结束,如where a = 1 and b = 2 and c > 3 and d = 4,索引(a,b,c,d)中只能用到abc(a,b,d,c)全能用上。并且不管你联合索引的顺序,你写(a,b,c,d)就先看a在不在where后面并且不是范围,再看b;(b,a,c,d)就先看b在不在,再看a。

25.数据行和行溢出:

  • 数据行:mysql底层有两种数据行,现在默认使用Compact,使得一个数据页能够保存更多的行数据;在存储一些大记录数据格式时,当数据本身超过768byte时就会将超出的数据放到另一个数据溢出页中。
  • 行溢出:首先我们直到一个数据页是16kb,也就是16384byte,但是一个数据行最大可以保存65535byte 数据,当插入行大于数据页大小,或者大于页中剩余空间大小时就会发生行溢出,将溢出的数据写到溢出页中,设置一个偏移量指针将两者关联起来。

26.order by 和group by底层原理:

  • order by:如果字段加了索引,就按照b+树进行排序;如果没加索引,如果数据行字段数比较少,就走单路排序(一次IO操作,一次性将所有需要排序的数据行都取出来在sort buffer中快速排序),反之走二路排序(两次IO操作,先取排序字段于sort buffer中,排序字段快速排好后,再根据排序字段取数据行),这两种排序中,如果sort buffer放不下数据了,都会创建临时文件触发归并排序。
  • group by:只是在orde by的基础上做了分组,所以group by优化还是order by优化。

26.进阶:

  1. 主从复制:将主库中修改的数据自动同步到从库
  • 原理:主库操作后将记录写入二进制文件,从库读取主库二进制日志写入自己的中继日志,从库读取并操作。
  1. 分库分表:
  • 水平分库和水平分表:差不多,字段数不变,数据按照行分表存储。
  • 垂直分库:一个库中的表拆分到几个库中。垂直分表:将表的字段分开,都包括主键就可以
  • mycat:作为客户端和mysql间的中间件,客户端链接的时候将mysql换成mycqt即可。

。无论是垂直还是水平,都是要去修改配置文件schema.xml rule.xml service.xml

  1. 读写分离:
  • 基于主从复制,主机写,从机读叫一主一从。两台主机写,两台从机读叫双主双从,同时两台主机间也互相复制,防止一台主机宕机后功能无法实现。都可以基于mycat实现。

以上是关于Mysql的主要内容,如果未能解决你的问题,请参考以下文章

mysql(设置/更改mysql密码,连接MySQL,MySQL常用命令,MySQL两种引擎区别)

MySQL教程

MySQL

MySQL

有什么学习MySQL的好教程吗?

MySql 详解