数据库常见问题

简单记录数据库中常见的概念和相关原理。

参考:

事务的四大特性(ACID)

  • 原子性:不可分割的操作单元,事务中所有操作,要么全部成功;要么撤回到执行事务之前的状态。
  • 一致性:如果在执行事务之前数据库是一致的,那么在执行事务之后数据库也还是一致的。
  • 隔离性:事务操作之间彼此独立和透明互不影响。事务独立运行。这通常使用锁来实现。一个事务处理后的结果,影响了其他事务,那么其他事务会撤回。事务的100%隔离,需要牺牲速度。
  • 持久性:事务一旦提交,其结果就是永久的。即便发生系统故障,也能恢复。

MySQL事务的隔离级别

  • 未提交读(Read Uncommitted):允许脏读,其他事务只要修改了数据,即使未提交,本事务也能看到修改后的数据值。也就是可能读取到其他会话中未提交事务修改的数据。
  • 提交读(Read Committed):只能读取到已经提交的数据。Oracle等多数数据库默认都是该级别 (不重复读)。
  • 可重复读(Repeated Read):可重复读。无论其他事务是否修改并提交了数据,在这个事务中看到的数据值始终不受其他事务影响。(MySQL默认)
  • 串行读(Serializable):完全串行化的读,每次读都需要获得表级共享锁,读写相互都会阻塞。

索引

索引,是数据库管理系统中一个排序的数据结构,以协助快速查询、更新数据库表中数据。通常有B+树实现,存储引擎不会再去扫描整张表得到需要的数据;它从根节点开始,根节点保存了子节点的指针,存储引擎会根据指针快速寻找数据

  • B-树:
    • 结构
      • 树中每个结点最多有m个孩子结点;
      • 若根结点不是叶子节点,则根结点至少有2个孩子结点;
      • 除根结点外,其它结点至少有(m/2的上界)个孩子结点;
      • 结点的结构如下图所示,其中,n为结点中关键字个数,(m/2的上界)-1 <= n <= m-1;di(1<=i<=n)为该结点的n个关键字值的第i个,且di< d(i+1);ci(0<=i<=n)为该结点孩子结点的指针,且ci所指向的节点的关键字均大于或等于di且小于d(i+1);
        B-树的节点构成
      • 所有的叶结点都在同一层上,并且不带信息(可以看作是外部结点或查找失败的结点,实际上这些结点不存在,指向这些结点的指针为空)
        4阶B-树
    • B_TREE的查找类似二叉排序树的查找,所不同的是B-树每个结点上是多关键码的有序表,在到达某个结点时,先在有序表中查找,若找到,则查找成功;否则,到按照对应的指针信息指向的子树中去查找,当到达叶子结点时,则说明树中没有对应的关键码。
  • B+ 树索引
    • 定义:根节点的槽中存放了指向子节点的指针,存储引擎根据这些指针向下层查找;通过比较节点页的值和要查找的值可以找到合适的指针进入下层子节点,这些指针实际上定义了子节点页中值的上限和下限,最终存储引擎要么找到对应的值,要么该记录不存在;对于B+树,不管查找成功与否,每次查找都是走了一条从根到叶子结点的路径。
      3阶B+树
    • 性质1:IO次数取决于b+数的高度h,假设当前数据表的数据为N,每个磁盘块的数据项的数量是m,则有h=㏒(m+1)N,当数据量N一定的情况下,m越大,h越小;而m = 磁盘块的大小 / 数据项的大小,磁盘块的大小也就是一个数据页的大小,是固定的,如果数据项占的空间越小,数据项的数量越多,树的高度越低。
    • 性质2:索引的最左匹配特性:当b+树的数据项是复合的数据结构,比如(name,age,sex)的时候,b+数是按照从左到右的顺序来建立搜索树的,比如当(张三,20,F)这样的数据来检索的时候,b+树会优先比较name来确定下一步的所搜方向,如果name相同再依次比较age和sex,最后得到检索的数据。
  • 为什么B+树比B树更适合用作操作系统的文件索引和数据库索引
    • B+树的磁盘读写代价低:B+tree的内部结点并没有指向关键字具体信息的指针,因此其内部结点相对B 树更小。树的高度更低。
    • B+tree的查询效率更加稳定
    • 数据库索引采用B+树而不是B树的主要原因:B+树只要遍历叶子节点就可以实现整棵树的遍历,而且在数据库中基于范围的查询是非常频繁的,而B树只能中序遍历所有节点,效率太低
  • 什么样的字段适合索引
    • 经常作查询选择的字段
    • 经常作表连接的字段
    • 经常出现在order by, group by, distinct 后面的字段
    • 索引字段越小越好:数据库的数据存储以页为单位一页存储的数据越多一次IO操作获取的数据越大效率越高
  • 索引的优缺点
    • 优点:大大加快数据的检索速度、加速表和表之间的连接、使用分组和排序子句进行数据检索时,同样可以显著减少查询中分组和排序的时间
    • 缺点:当对表中的数据进行增加、删除和修改的时候,索引也要动态的维护,这样就降低了数据的维护速度
  • 聚集索引和辅助索引
    • 相同点:不管是聚集索引还是辅助索引,其内部都是B+树的形式,即高度是平衡的,叶子结点存放着所有的数据。
    • 不同点:聚集索引中,叶子节点存放的全部数据,直接指向数据页;辅助索引的叶子节点不包含行记录的全部数据,叶子节点除了包含键值以外,还包含一个书签,用来指明与索引相对应的行数据的具体位置。
    • 聚集索引的优点:1、对主键的排序查找和范围查找速度非常快,叶子节点的数据就是用户所要查询的数据;2、范围查询,通过叶子节点的上层中间节点就可以得到页的范围,之后直接读取数据页即可
    • 聚集索引的缺点:1、如果数据全部都放在内存中,则访问速度就没那么重要了,聚簇索引也就没什么优势了;2、插入速度严重依赖于插入顺序;3、更新索引代价大,因为要强制每个行移动到新的位置
    • 每个表只能有一个聚集索引,因为目录只能按照一种方法进行排序。但是可以有多个非聚集索引。比如说字典是按字的拼音顺序的聚集索引,但是却可以有偏旁这种非聚集索引。
  • 哈希索引:基于哈希表实现,只有精确匹配索引所有列的查询才有效;哈希索引将所有的哈希码存储在索引中,同时在哈希表中保存指向每个数据行的指针;不支持排序、范围查询、发生哈希冲突时也要维护
  • 索引的大致分类
    • 普通索引和唯一性索引:索引列的值的唯一性
    • 单个索引和复合索引:索引列所包含的列数
    • 聚簇索引和非聚簇索引:类比查字典用读音和偏旁
  • 主键、自增主键、主键索引与唯一索引概念区别
    • 主键:指字段 唯一、不为空值 的列;
    • 主键索引:指的就是主键,主键是索引的一种,是唯一索引的特殊类型。创建主键的时候,数据库默认会为主键创建一个唯一索引;
    • 自增主键:字段类型为数字、自增、并且是主键;
    • 唯一索引:索引列的值必须唯一,但允许有空值。主键是唯一索引,这样说没错;但反过来说,唯一索引也是主键就错误了,因为唯一索引允许空值,主键不允许有空值,所以不能说唯一索引也是主键。
  • 主键和索引的区别
    InnoDB作为MySQL存储引擎时,默认按照主键进行聚集,如果没有定义主键,InnoDB会试着使用唯一的非空索引来代替。如果没有这种索引,InnoDB就会定义隐藏的主键然后在上面进行聚集。所以,对于聚集索引来说,你创建主键的时候,自动就创建了主键的聚集索引。
  • 索引操作:
    • 查看索引:show indexes from students
    • 显示查询的执行过程:explain select xxx
    • 添加索引:alter table students add index(Age)

存储过程

  • 定义:事先经过编译并存储在数据库中的一段SQL语句的集合,些T-SQL语句代码像一个方法一样实现一些功能(对单表或多表的增删改查),然后再给这个代码块取一个名字,在用到这个功能的时候调用他就行了。
  • 特点:
    1. 存储过程只在创建时进行编译,以后每次执行存储过程都不需再重新编译
    2. 减少网络传输,在客户端调用一个存储过程比执行一串SQL传输的数据量要小
    3. 通过存储过程能够使没有权限的用户在控制之下间接地存取数据库,从而确保数据的安全

视图和游标

  • 视图:视图是一种虚拟的表,通常是有一个表或者多个表的行或列的子集,具有和物理表相同的功能,可以对视图进行增,删,改,查等操作
  • 游标:对查询出来的结果集作为一个单元来有效的处理。游标可以定在该单元中的特定行,从结果集的当前行检索一行或多行。比如网页中用户看上一条和下一条信息

触发器

触发器(TRIGGER)是由事件来触发某个操作。这些事件包括INSERT语句、UPDATE语句和DELETE语句。当数据库系统执行这些事件时,会激活促发其执行相应的操作。

create trigger trig_book after insert 

           on t_book for each row 

                  update t_bookType set bookNum = bookNum+1 where new.bookTypeId = t_booktype.id;

数据库3大范式

  • 第一范式:1NF是对属性的原子性约束,要求字段具有原子性,不可再分解
  • 第二范式:2NF是在满足第一范式的前提下,非主键字段不能出现部分依赖主键;解决:消除复合主键就可避免出现部分以来,可增加单列关键字(比如说主键字段有货物类型和ID两个,但是“注意事项”这个非主属性之部分依赖与“货物类型”,并不依赖ID,所以不符合第二范式)
  • 第三范式:3NF是在满足第二范式的前提下,非主键字段不能出现传递依赖,比如某个字段a依赖于主键,而一些字段依赖字段a,这就是传递依赖。解决:将一个实体信息的数据放在一个表内实现
    第2范式就是在第1范式的基础上再保障非主属性完全依赖于主属性;第3范式,在2NF基础上消除传递依赖

脏读 & 不可重复读 & 幻读

  • 脏读:指事务T1将某一值修改,然后事务T2读取该值,此后T1因为某种原因撤销对该值的修改,这就导致了T2所读取到的数据是无效的。(发生了数据回滚)
  • 不可重复读:是指在数据库访问时,一个事务范围内的两次相同查询却返回了不同数据。(发生了数据的更新)
  • 幻读:第一个事务对一个表中的数据进行了修改,同时事务2插入了数据,结果事务1结束发现有一条数据没有发生更改。(更新数据时插入了新数据)
  • 不可重复度的重点在于更新和删除,需要加行锁, 幻读的重点在于插入,需要加表锁。

MyISAM和MySQL之间的区别

  • InnoDB支持事务,MyISAM不支持
  • InnoDB支持外键,MyISAM不支持
  • InnoDB支持行锁(默认)和表锁,MyISAM是表锁

delete、drop、truncate区别

  • delete和truncate用来删除数据、drop将表结构和数据一起删除了
  • 当你不再需要该表时, 用 drop
  • 不需要表中所有数据,但是还要保留表结构,用truncate
  • 不需要表中的部分数据时,用delete
posted @ 2019-12-30 19:44  冰糖ryj  阅读(139)  评论(0编辑  收藏  举报