1.简述数据库三范式?什么是反模式?
总述
数据库范式是为解决关系数据库中数据冗余、更新异常、插入异常、删除异常问题而引入的。简单的理解,数据库范式可以避免数据冗余,减少数据库的空间,并且减轻维护数据完整性的麻烦。
第一范式(1NF)
第一范式,强调属性的原子性约束,要求属性具有原子性,不可再分解。
//举个例子,活动表(活动编码,活动名称,活动地址),假设这个场景中,
//活动地址可以细分为国家、省份、城市、市区、位置,那么就没有达到第一范式。
第二范式(2NF)
第二范式,强调记录的唯一性约束,表必须有一个主键,并且没有包含在主键中的列必须完全依赖于主键,而不能只依赖于主键的一部分。
//举个例子,版本表(版本编码,版本名称,产品编码,产品名称),其中主键是(版本编码,产品编码),
//这个场景中,数据库设计并不符合第二范式,因为产品名称只依赖于产品编码。
//存在部分依赖。所以,为了使其满足第二范式,
//可以改造成两个表:版本表(版本编码,产品编码)和产品表(产品编码,产品名称)。
第三范式(3NF)
第三范式,强调属性冗余性的约束,即非主键列必须直接依赖于主键。
//举个例子,订单表(订单编码,顾客编码,顾客名称),其中主键是(订单编码),
//这个场景中,顾客编码、顾客名称都完全依赖于主键,因此符合第二范式,
//但是顾客名称依赖于顾客编码,从而间接依赖于主键,所以不能满足第三范式。
//为了使其满足第三范式,可以拆分两个表:订单表(订单编码,顾客编码)和顾客表(顾客编码,顾客名称),
//拆分后的数据库设计,就可以完全满足第三范式的要求了。
值得注意的是,第二范式的侧重点是非主键列是否完全依赖于主键,还是依赖于主键的一部分。第三范式的侧重点是非主键列是直接依赖于主键,还是直接依赖于非主键列。
反模式
范式可以避免数据冗余,减少数据库的空间,减轻维护数据完整性的麻烦。
//然而,通过数据库范式化设计,将导致数据库业务涉及的表变多,并且可能需要将涉及的业务表
//进行多表连接查询,这样将导致性能变差,且不利于分库分表。
因此,出于性能优先的考量,可能在数据库的结构中需要使用反模式的设计,
即空间换取时间,采取数据冗余的方式避免表之间的关联查询。
//至于数据一致性问题,因为难以满足数据强一致性,一般情况下,使存储数据尽可能达到用户一致,
//保证系统经过一段较短的时间的自我恢复和修正,数据最终达到一致。
//需要谨慎使用反模式设计数据库。一般情况下,尽可能使用范式化的数据库设计,
//因为范式化的数据库设计能让产品更加灵活,并且能在数据库层保持数据完整性。
2.MySQL中varchar与char区别?varchar(50)的50代表的涵义?
- varchar 与 char 的区别,char 是一种固定长度的类型,varchar 则是一种可变长度的类型。
- varchar(50) 中 50 的涵义最多存放 50 个字符。varchar(50) 和 (200) 存储 hello 所占空间一样,但后者在排序时会消耗更多内存,因为 ORDER BY col 采用 fixed_length 计算 col 长度(memory引擎也一样)
3.一张表,里面有 ID 自增主键,当 insert 了 17 条记录之后,删除了第 15,16,17 条记录,再把 MySQL 重启,再 insert 一条记录,这条记录的 ID 是 18 还是 15?
一般情况下,我们创建的表的类型是 InnoDB ,如果新增一条记录(不重启 MySQL 的情况下),这条记录的 ID 是18 ;但是如果重启 MySQL 的话,这条记录的 ID 是 15 。因为 InnoDB 表只把自增主键的最大 ID 记录到内存中,所以重启数据库或者对表 OPTIMIZE 操作,都会使最大 ID 丢失。
但是,如果我们使用表的类型是 MyISAM ,那么这条记录的 ID 就是 18 。因为 MyISAM 表会把自增主键的最大 ID 记录到数据文件里面,重启 MYSQL 后,自增主键的最大 ID 也不会丢失。
建议:生产数据不建议进行物理删除记录