数据库设计
三大范式
目前关系数据库有六种范式,理论上,一般而言应当实现第三范式,实际上根据业务考量不会严格实现。
第一范式,1NF
数据库表的每一列都是不可分割的原子数据项,而不能是集合,数组,记录等非原子数据项,一列仅仅表示一个不可分割的属性
第二范式,2NF
在第一范式的基础上,非码属性必须完全依赖于候选码,第二范式要求数据库表中的每个实例或记录必须可以被唯一地区分。选取一个能区分每个实体的属性或属性组,作为实体的唯一标识。
第三范式,3NF
在第二范式的基础上,任何非主属性不依赖与其他非主属性
字段设计
单个字段多种状态
爱好
- 篮球
- 动漫
- 小说
- 电影
- 健身
前端处理
1,2,3 动漫小说电影
后端处理
- 100001
篮球和写博客 - 101010
篮球、小说和健身
表存储,二进制或字符串
动漫、小说和写博客 select * from xxx where interest like '_11__1'
动漫、小说和写博客 select * from xxx where interest &38
无法走索引,如果状态较多,无法枚举
visible_type,可见类型
0b000 0 不展示
0b001 1 对所有人展示
0b010 2 仅对持仓者展示
0b011 3 --
0b100 4 仅对内展示
0b101 5 --
0b110 6 对持仓者和对内展示
0b111 7 --
通常状态不多,会有因为某些状态不会采用,枚举而使用索引
主键设计
无意义业务无关ID
无意义的意思其实就是 ID 中不应该包含任何与具体场景或者业务相关的内容,包含这些内容并不是不可以,只是一旦出现这些内容,要么 ID 重复的可能性会增加,这很可能对我们的业务逻辑造成比较严重的影响,以我们的身份证号为例,它的 18 位数字(或符号)大多都是有意义的。
这 18 位数字中的前 6 位表示的是地区,也就是省份、城市和区县,随后的 8 位表示的是出生年月日,接下来的 3 位才同时表示 ID 和性别,最后 1 位用于做校验码防止出现身份证号输错的情况。用上述图中的黄色部分中有一半的数字是用来表示出生的男性,另一半表示出生的女性,所以如果同一个地区的同一天,同时出生了 501 位男性或者女性就会导致潜在的重复问题。
上面谈到的问题其实也是我们在各种业务场景中经常能够遇到的问题,18 位的数字中真正用于表示序列的 ID 其实只有 1000 的一半,如果 18 位数都是无意义的,那它们可以表示 10 亿亿个人,但是一旦在 ID 中引入了业务上的具体信息,就增加了冲突的可能性。