目录
先思考数据库建表三大范式
对照需求或者原型图进行基础表字段设计,参考数据库表三大范式
数据库表三大范式
数据库有8种范式(Normal Form),通常只用到前3种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF),我们设计的关系数据库要满足这3种范式。
第一范式
1NF是对属性的原子性约束,要求属性具有原子性,不可再分解。
第二范式
2NF是对记录的惟一性约束,要求记录有惟一标识,即实体的惟一性。表中的每一条记录都要是可区分的,表中必须要有一个unique字段作为主键。
第二范式建立在第一范式的基础上,满足第二范式必须要先满足第一范式。
第三范式
3NF是对字段冗余性的约束,要求属性不能有依赖传递(只依赖于主键,不依赖于主键之外的其它属性),简单来说就是要求没有冗余字段。
第三范式建立在第二范式的基础上,满足第三范式需要先满足第二范式。
范式、冗余的取舍:有时为了提高效率,可以适当违反第三范式,冗余部分字段以减少多表查询,用空间换时间。
场景描述
假设有一个电商系统,包含订单表 Orders
和用户表 Users
。在严格遵循第三范式的情况下,订单表只存储 用户ID
,需要通过联表查询获取用户的详细信息。
遵循第三范式的设计
- 用户表 Users
用户ID | 用户姓名 | 用户地址 |
U01 | 张三 | 北京市 |
U02 | 李四 | 上海市 |
- 订单表 Orders
订单ID | 用户ID | 订单日期 | 总金额 |
1001 | U01 | 2023-10-01 | 500元 |
1002 | U02 | 2023-10-02 | 300元 |
在这种设计下,每次查询订单信息时,都需要通过联表查询获取用户的详细信息,这在高并发、大数据量的情况下会增加查询时间和系统负载。
违反第三范式的设计
为了提高查询性能,可以在订单表中冗余存储 用户姓名
和 用户地址
等信息,这样查询订单信息时无需联表查询 Users
表,从而提升查询速度。
- 用户表 Users
用户ID | 用户姓名 | 用户地址 |
U01 | 张三 | 北京市 |
U02 | 李四 | 上海市 |
- 订单表 Orders
订单ID | 用户ID | 用户姓名 | 用户地址 | 订单日期 | 总金额 |
1001 | U01 | 张三 | 北京市 | 2023-10-01 | 500元 |
1002 | U02 | 李四 | 上海市 | 2023-10-02 | 300元 |
对设计出的表字段进行适当的冗余,用空间换时间。
数据库三大范式的形成是由于在早期计算机系统中,存储资源(如磁盘空间)非常有限且昂贵。因此,减少数据冗余不仅可以节省存储空间,还能降低存储成本。这种需求促使数据库设计者努力优化数据存储结构,以确保数据的高效存储和管理。
但是现在随着关系数据库理论的成熟和范式理论的出现,技术的逐渐成熟,存储成本逐渐降低,而性能优化成为更重要的考虑。范式化设计通过减少冗余,降低了数据存储量,从而提高了查询和更新操作的效率。此外,范式化设计还通过规范化表结构,使得数据库更容易维护和扩展。
由第三范式中引申出来的问题,需要对设计出的表字段进行适当的冗余,以减少多表查询,用空间换时间。这点需要在长期多次对库表进行设计或者对对应的业务逻辑更加了解,才会知道哪些字段做成冗余字段,会更好的减少多表查询的工作量。
增加对业务的了解程度,多方了解,提前进行确认
简而言之,就是提前对业务进行了解和询问,提前与售前等人员进行沟通,或者在进行开发时,即使进行反馈和确认,减少后期因为返工带来的重复性工作。
适时使用拓展字段
扩展字段一般用于存储一些不太关键但是有需要存储的数据,一般不用于查询条件,仅用于展示用。这些字段可能有很多,一般我们直接存储成json。如果真的需要添加一些仅用于展示用的字段,而没有深入业务逻辑的字段,则可以在拓展字段中添加,但如果需要添加与业务逻辑强绑定的字段,还是需要添加,而不是写入拓展字段中。