面试小纸条(MySQL第一弹)
数据库三大范式
一,列不可再分
要求每个列的属性含义是不可再分的,并且含义接近的的字段应尽量合并。这样是为了更精细的按照字段属性分组,当只有一个字段描述地址和分别通过省,市,区三个字段描述,地址更合适,更有利于以后的分组查询。
二, 属性完全依赖主键,而非只依赖一部分
第二范式的意义在于出现联合主键时,存放联合主键的表不会出现冗余的数据而只关注与两表之间的联系上。
三,列中的每一个属性和主键直接相关而非间接相关
在第一范式的基础上,规范了属性和主键的关系,即表中的字段属性的存在必定是因为主键的存在而存在的。即属性和主键是有直接联系,因此,当出现冗余的与主键非直接相关的属性,例如账户对应用户,账户为主键,其中含有用户id时,用户的姓名等就不应该出现在该表中,而应该单独设置在以用户id为主键的表中,在需要查出账户及用户信息时通过联合查询获得。
联合主键和复合主键
复合主键
通过将一个表中的几个不唯一字段组合作为唯一的主键从而保证了记录的唯一性。因为我们有时不会设定一个没有业务意义的自增id作为主键。同时,复合主键能够作为一个整体来建立索引
联合主键
对于多个表而言,存在多对多的关系时,可以通过建立联合主键来确立表与表之间记录与记录的关系,通常将两个表的主键单独存放在一个表中作为联合主键用于记录关系。因为是多对多的关系,在存放联合主键的表中两个表的主键可能出现多次,联合主键就确定表之间字段与字段之间联系的唯一性。
索引
目的就是通过分段查询不断缩小范围从而增加查询速率。
磁盘io与预读
数据库引擎是一页一页读取磁盘中的数据到内存中的,当一次io进行时,数据库会同时把当前磁盘地址和附近地址的数据同时读入内存中,一次io的数据量大约是4k或8k,因此,加快数据库查询的方式就是尽可能减少io的次数,即以尽量快的速度定位我们所需得数据在哪一页中,于是就需要b+树这一数据结构
b+树
每一个节点由数据项和指针组成,我们通过索引和数据项的比较最后定位到一个叶子节点,在b+树中只有叶子节点存放真正磁盘块数据,非叶子节点只存储指向下一层的指针,由此我们可以发现,这时我们io的次数取决于b+树的高度。
b+树的两个性质
索引字段越小,查询速率越大
在b+树中的节点所能承载的数据项总量一定时,索引字段的大小决定了一个非叶子节点能承载多少的数据项,而一个节点所能承载的数据项越多,在一次io时所能完成的对磁盘块的定位就越精细,体现在b+树上就是高度更小,形状更加扁平,这样定位需要io的次数就更少。
索引的最左匹配特性
当索引,即数据项是由多个字段组合而成的复合结构时,构建b+树时是从左至右选取字段作为数据项作为讲数据分块的依据的,当我们需要查询时,首先就要获得当初在构建索引时,给定的复合数据项的最左数据,并以此来确定位置,当找到多个相同的数据项时,在从左到右依次比较,直到找到匹配数据项所指定的方向,所以最左边的数据项是必需的,我们必须由此初步确定方向,才能考虑后面的数据项匹配问题,在最左匹配的情况下,后面的数据项确实是不会影响的。
b+树存在的问题
b+树是一种平衡查找树,所以当表中的数据发生变动时,索引树是需要重新维护,从而维持平衡,这样是消耗性能的,所以索引的使用会造成增加删除修改的性能降低,所以索引更适合在不需要频繁修改的表中使用。
聚集索引与非聚集索引
一个表只能有一个聚集索引,通过聚集索引查询就是,根据数据项一层层定位到包含磁盘数据的叶子节点的过程。而非聚集索引的叶子节点存储的不是磁盘数据,而是聚集索引对应的数据项,通过非聚集索引查询就是先定位聚集索引的数据项,再二次查询根据聚集索引确定实际的磁盘数据。
什么时候可以使用索引
-
对含有大量数据不常变动且需要频繁查询的表
-
需要查询获得一段有序数据的表
-
经常进行分组,统计查询的表
什么时候不该用索引
- 数据频繁更新的表
- 记录过少的表,因为生成树也会占用内存,查找数据项的时间也许就能直接查找到数据。
- 大量重复且分布平均的字段,根据这样的字段确定数据项,并不能生成一个可以将磁盘数据合理分片的树,这样的操作是没有意义的。