MySQL

数据库

  1. 建表三范式
    1. 第一范式:每一列不可再拆分。(实体属性的原子性)
    2. 第二范式:必须有主键,并且每一列必须完全依赖于主键。
    3. 第三范式:不允许存在传递依赖,有类似需求时,使用外键等来满足。
  2. 索引
    1. 数据结构
      1. 常用数据结构:B+Tree、Hash
        1. B+Tree索引与Hash的区别
          1. hash索引等值查询比较快
          2. B+Tree能够提供比较稳定的查询速度,因为Hash存在冲突,假设使用拉链法来解决hash冲突的话,在数组上时O(1),但是进入链表,时间复杂度就变成了O(n)
          3. Hash索引不支持范围查询(或者说非等值查询)
          4. Hash索引无法支撑排序(不支持group by、order by等操作)
          5. Hash索引无法支持模糊查询
          6. Hash索引无法支持最左有限匹配原则
        2. B+Tree以及B-Tree的特点
          1. B-Tree
            1. 假设是n阶树
            2. 根节点的子树个数为2~n
            3. 除根节点和子树节点之外,其他节点的子树个数为n/2向上取整 ~ n
            4. 每个节点里面存储的元素内容为:p1,k1,p2,k2 … pn,元素有序,p为指向子树的指针。
            5. 在B-Tree中,每一个元素只出现一次
            6. 在B-Tree中,叶子节点不存储具体的数据内容,所有的数据都存储在非叶子节点上。
          2. B+Tree
            1. 假设是n阶树
            2. 根节点的子树个数为2~n
            3. 除根节点和子树节点之外,其他节点的子树个数为n/2向上取整 ~ n
            4. 每个节点中存储的元素内容为: p1, k1, p2, k2 … pn,kn,元素有序,p为指向子树的指针(p和k的个数相等)
            5. 父节点的内容会在其子节点中存储
            6. 所有具体的数据信息都存储在了叶子节点上
          3. 其他
            1. AVL:平衡二叉树,左右子树高度不超过一
            2. 完全二叉树:除最底层全满,最底层子节点全部靠左
            3. 二叉查找树:BST,中序遍历为从小到大有序
            4. 红黑树:一种自平衡二叉查找树
              1. 节点是红色或者黑色
              2. 根节点是黑色
              3. 叶子结点是黑色
              4. 每个红色节点的子节点必须是黑色
              5. 从每个节点到其下面的任何叶子节点拥有相同的黑色节点个数
        3. 为什么选用B+Tree
          1. 查询效率比较高并且稳定,为O(logdn),以d为底n的对数。
          2. 比较契合操作系统的磁盘预读原理
            1. 每个节点存储的数据量比较大,所以逻辑上相邻的数据在物理上也很有可能相邻(与二叉树、红黑树做比较)
            2. 实际上对B+Tree还做了改进,每个叶子结点会有一个指向最相邻的下一个叶子结点的指针,这样的话,范围查询,可以直接顺着指针查下去。
          3. 因为以上两点,并且在B+Tree中每个节点存储的k要比B-Tree多,所以B+Tree更适合做索引。
      2. 使用注意点
        1. 最左匹配原则
        2. 每次只能用到一个索引
        3. %放最前面无法用到索引
        4. 多个范围查询的话,即使是联合索引,后面的范围查询字段也是用不到索引的
        5. 列参与运算用不到索引
        6. null不计入索引
        7. or的两个部分都有索引,并且是不同字段,如果MySQL判断扫全表需要更长时间的话,会同时用到这两个索引(这是唯一一个可能违反每次只用一个索引的地方)
      3. explain
        1. 字段
          1. select type
          2. type
            1. system
            2. const
            3. eq_ref
            4. ref
            5. ref_or_null
            6. range
            7. index
            8. all
          3. possible_keys
          4. key
          5. rows
      4. 其他
        1. 索引创建的注意点
          1. 一张表不能有太多索引
            1. 会影响插入效率
          2. 创建索引的时候一般需要考虑索引的区分度
            1. 用distinct/总量,0.95以上基本没问题
          3. 在InnoDB中,推荐使用自增的int来做主键索引,这样一来可以提高效率,二来防止往中间页频繁插入,导致裂项,进而导致空间浪费。
            1. 但是如果没有主动设置主键索引时,会默认设置一个自增的int做主键索引
          4. 存在null时,是可以给这一列创建唯一索引的, 但是唯一索引会把两个null认为重复。
    2. 存储引擎
      1. MyISAM和InnoDB的区别
        1. MyISAM的文件分三份:表定义、数据文件、索引文件,InnoDB只有数据文件和日志文件。
          1. 所以MyISAM的数据迁移特别方便。
          2. 还有,MyISAM删全表数据(delete)也特别方便,直接删掉数据文件和索引文件即可。但是InnoDB只能一行一行去删。不过,一旦delete存在where子句,那么两个一样。
        2. MyISAM支持表锁,而InnoDB支持到行锁。
        3. MyISAM不支持事务,InnoDB支持事务。如果强行在MyISAM上使用事务,那么在多条操作中间某一条失败时,前面的所有操作都不会被回滚。
        4. MyISAM会记录当前表的总条数,所以count(1)的时候,能够直接读取,但是InnoDB只能一次次去查。(猜测,如果存在where子句,两个还是一样的操作)
        5. 注意MyISAM和InnoDB的索引文件是有差别的。InnoDB的主键索引才会存储所有的数据。
        6. 对于auto_increment的列,InnoDB要求必须给单独建索引,但是MyISAM没这要求,让它与其他列建联合索引就行。
    3. 事务隔离级别
      1. 未提交读
        1. 一个事务还没有提交,另一个事务就能读到此次修改的内容
        2. 会出现脏读、幻读、不可重复读的情况
      2. 读已提交
        1. 只要事务提交了数据,就能被另一个事务读到
        2. 会出现幻读、不可重复读的情况
          1. 幻读主要是指插入
          2. 不可重复读主要是指更新
      3. 可重复读
        1. 一个事务多次读的结果是一样的
        2. 理论上是无法解决幻读的问题的,但是InnoDB做了优化,可以解决幻读的情况
        3. 可重复读比读已提交,是多了对当前修改行的行锁
        4. InnoDB的优化,是在行锁之外,加了间隙锁,导致对当前行做修改时,第一不能再次修改当前行,第二不能在临近行新增数据
      4. 串行化读
        1. 读加读锁(表级锁),写加写锁
        2. 效率会大受影响
    4. redo/undo/binlog
      1. redo日志
        1. 记录的是当前的操作(或者说是修改后的数据结果)
        2. 在事务开始之后就开始记录,不停地进行落盘
        3. 事务提交,数据落盘之后,redo日志就已经失效了
        4. 主要是为了保证持久性,部分为了保证原子性(因为undo动作也会在redo日志里面有记录)
      2. undo日志
        1. 记录的是被修改数据的原始内容
        2. 事务开始时进行记录
        3. 事务提交,数据落盘,如果没有其他事务还在使用当前undo日志里面的版本,则事务失效
        4. 主要是为了保证原子性
      3. binlog
        1. 数据库操作的日志记录
        2. 数据格式
          1. 低版本的支持二进制流和文本文件两种格式,高版本的只支持二进制流
        3. 记录方式
          1. row模式:记录每一行的变更。但是高版本的话,对于ddl,也是直接记录语句
          2. statement模式:记录语句
          3. mix模式:mysql自己决定按哪种形式记录
        4. 记录时间:事务提交时,所以一旦开启,有可能对事务速度造成影响
        5. 失效时间:定时失效,可以调整定时的时间
    5. 死锁
      1. 出现原因:
        1. 两个事务分别持有对方所需的资源,并且在等待对方释放所有的资源
      2. 示例:
        1. update table set a = A where a = B, update table set b = B where b = A ;
        2. update table set a = A where b = A, update table set b = B where a = B ;
      3. 检查方式:
        1. 检查业务日志
        2. 确定mysql事务隔离级别(因为RR里面的间隙锁也有可能导致死锁)
        3. 检查数据库日志
      4. 避免方法:
        1. 大事务拆小
        2. 最好能够一次性获取到所有的资源
        3. 加索引(能够避免尝试锁全表)
    6. 其他
      1. 语句
        1. join
          1. left join
          2. right join
          3. inner join
          4. full join
          5. inner join里面驱动表的选择:小表驱动大表
          6. outer join 里面,无匹配的行,其会填充null
        2. union、union all
      2. 数据类型
        1. int(4)与int(11)的区别
        2. varchar与char的区别
        3. text与varchar的区别
        4. datetime和timestamp的区别
          1. timestamp会自动替换成utc时间进行存储,然后取出的时候替换成当前时区
          2. datetime存是什么样的,取的时候就是什么样的
          3. timestamp的时间区间是1970 ~ 2138年
          4. datetime的时间区间是0000 ~ 9999年

你可能感兴趣的:(MySQL)