一,关系数据库三大范式
第一范式要求每一列都不可再分,即要满足原子性,这也是关系数据库设计中最基本都要求。第二范式是在它基础上要求所有非主键列都要完全依赖主键列,而不能只依赖部分主键列(若有此情况,应该拆分表)。第三范式是在第二范式基础上要求所有非主键列都必须要直接依赖主键列,而不是依赖某非主键列进而间接依赖主键列,比如用户表有用户id、用户名、组织id、组织名称字段时就不满足第三范式,因为组织名称是直接依赖组织id的。不过实际在关系数据库表设计时为了减少关联表查询都会采用这种冗余设计。
二、数据库表连间的连接关系
常见的数据库表间连接关系分为内连接、外连接、左(右)外连接、交叉连接几种。其中内连接返回两个表中满足条件的记录,外连接(全外连接)返回两个表中所有记录(包括满足条件的记录,其它左边表记录+右边表字段为空,其它右边表记录+左边表字段为空),左外连接以左边表为准,返回所有左边表记录(右边表不存在关联记录的返回空),交叉连接是返回两边记录的乘积。
三、数据库索引概念及注意事项
数据库索引目的是为了增加记录的查询排序效率,避免全表扫描提升效率,尤其是在表数据多情况下,正确使用索引能极大提高数据库的查询效率。通常数据库索引使用B+树结构,其它类似常用的索引结构有Hash索引、LSM树索引。
从记录顺序与物理磁盘顺序是否一致的角度看索引分为聚簇索引和非聚簇索引。聚簇索引是指索引记录顺序与物理记录顺序一致,查询效率更高,更适用于区间记录查询,每个表只能建一个聚簇索引,默认在建表主键时会把它设置为聚簇索引(如果要设置其它列为聚簇索引,要在指定主键前设置)。
常见索引分类有普通索引(常见的索引)、唯一索引(列值唯一的索引,允许空值)、主键索引(特殊的唯一索引)、单例索引、联合索引。使用索引有以下注意事项:
- 避免过度使用索引,如果表记录不多,或者是重复记录很多(比如性别列),或者表的增、改、删很频繁,不建议使用索引,因为索引效果不明显还增加了维护成本。
- 合理使用索引,尤其是联合索引,应将区分记录更多、查询条件在前的列放在联合索引的前面,避免像MySQL数据库左联合索引规则(假设联合索引列为a、b、c时如果条件中没有a列则不起作用,PgSql似乎没这个问题)。
- 任何对列的操作都将导致表扫描,它包括数据库函数、计算表达式等等,查询时要尽可能将操作移至等号右边。
- in、or子句常会使用工作表,使索引失效;如果不产生大量重复值,可以考虑把子句拆开;拆开的子句中应该包含索引。
哪些情况需要建索引:
1 主键,唯一索引
2 经常用作查询条件的字段需要创建索引
3 经常需要排序、分组和统计的字段需要建立索引
4 查询中与其他表关联的字段,外键关系建立索引哪些情况不要建索引:
1 表的记录太少,百万级以下的数据不需要创建索引
2 经常增删改的表不需要创建索引
3 数据重复且分布平均的字段不需要创建索引,如 true,false 之类。
4 频发更新的字段不适合创建索引
5 where条件里用不到的字段不需要创建索引
四、关系数据库表中不应存的三类值
- 大文件、声音图片文件,虽然数据库字段有blog类型,但最后还是不要直接将文件存入数据库,而是通过存入对应文件路径解决。因为通过数据库操作速度不如直接操作文件快,会增大数据库文件备份迁移数据麻烦。有网友表示在MySQL数据库中存储图片文件列,虽然在查询中不含该字段也会拖慢查询效率。
- 临时数据,比如session、每小时、天会过期清理的数据不应该存在数据库中,存在Redis之类的缓存中更合适。
- 大量日志文件,如果想将日志存入数据库以方便日志的查询最好也是单独建立日志库,避免因为频繁写入日志而影响主业务表的访问效率。