怎么设计一个规范、可扩展、安全的数据库?

如何给项目设计数据库

在独立开发一个具备基本功能的网站时,需求分析与数据库设计往往是最耗时的部分之一

第一次从零开始设计数据库,我查阅了大量资料,也研究了很多成熟项目的数据库结构。以下是我在这个过程中总结的一些经验

设计一个规范的数据库

先问自己三个问题:

  • 要存什么?
  • 怎么存才能称得上合理?
  • 怎么存得快、查得快?

要存什么?

这个问题相对简单

我在开发前已经进行了详细的需求分析,并梳理出了系统所需的业务实体。基于这些实体,数据库中的表和字段基本可以确定

怎么存才能称得上合理?

也就是数据库结构怎么设计更规范、更清晰

我翻阅了《数据库设计》相关资料,复习了这个经典准则:数据库三范式(3NF)。几乎所有成熟系统的数据库结构,都遵循这一设计方法

  • 1NF:字段不可拆分

  • 2NF:字段完全依赖主键

  • 3NF:字段不传递依赖主键

实际开发中,为了性能可以适度反范式化,也就是有意识地违反三范式以提升查询效率

后面会详细将三范式

命名规范建议

  • 使用英文小写 + 下划线(如 user_id
  • 避免使用拼音或不常见缩写
  • 表名通常用复数(如 usersorders

到这里作为初学者已经结束了,接下来的内容是为了让项目的数据库更加完善

怎么存得快、查得快?

这里说两种常用的方式吧:

1. 添加必要的索引

  • 主键索引:如自增 id
  • 唯一索引:如 user_account
  • 普通索引:用于查询筛选字段,如 status, created_time

索引虽能提高查询速度,但也会增加写入成本,需合理设计

2. 反范式化

  • 为了提高性能,可以适当冗余部分数据,例如:
    • 在评论表中直接存储用户昵称(避免频繁关联用户表)
    • 拆分表结构:将日志、历史数据单独建表(如 log_xxxhistory_xxx

数据库三范式

第一范式(1NF):要求数据库表的每一列都是不可分割的原子数据项。

举例说明:

在上面的表中,“家庭信息”和“学校信息”列均不满足原子性的要求,故不满足第一范式,调整如下:

可见,调整后的每一列都是不可再分的,因此满足第一范式(1NF);

第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于候选码(在1NF基础上消除非主属性对主码的部分函数依赖)

第二范式需要确保数据库表中的每一列都和主键相关,而不能只与主键的某一部分相关(主要针对联合主键而言)。

举例说明:

在上图所示的情况中,同一个订单中可能包含不同的产品,因此主键必须是“订单号”和“产品号”联合组成,

但可以发现,产品数量、产品折扣、产品价格与“订单号”和“产品号”都相关,但是订单金额和订单时间仅与“订单号”相关,与“产品号”无关,

这样就不满足第二范式的要求,调整如下,需分成两个表:

第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)

第三范式需要确保数据表中的每一列数据都和主键直接相关,而不能间接相关。

举例说明:

上表中,所有属性都完全依赖于学号,所以满足第二范式,但是“班主任性别”和“班主任年龄”直接依赖的是“班主任姓名”,

而不是主键“学号”,所以需做如下调整:

这样以来,就满足了第三范式的要求。

设计一个高可扩展性与可维护性的数据库

1. 预留扩展字段

  • 使用 JSON 格式扩展字段(如 ext_json)存储一些不固定字段
  • 对不常用数据做非结构化存储,提升灵活性

2. 逻辑删除与状态字段设计

  • 使用 is_deleteddelete_flag 标识逻辑删除状态
  • 添加状态字段(如 status, audit_status)明确当前业务状态

设计一个安全的数据库

1. 添加审计字段

  • created_time, updated_time:用于追踪数据变更
  • created_by, updated_by(或 user_name):记录操作人员信息

2. 字段设计细节中的数据安全与可读性

项目 建议
字段类型 精确选择(如金额用 DECIMAL,状态用 TINYINT
字段长度 合理限制(如用户名不超过 50 字符)
是否可空 关键字段设置为 NOT NULL
默认值 避免出现 NULL
时间字段 统一使用 created_time, updated_time 命名

3. 数据权限与信息安全

  • 用户权限采用分级管理(如管理员、普通用户)
  • 对敏感字段(如手机号、身份证)进行加密或脱敏处理
  • 使用数据库层访问控制(如视图、只读账号)

对自己的一段话

想着什么都顾及上,最后只会极其臃肿且不合理。数据库的设计并非一蹴而就,在项目的不同阶段,可能需要根据业务变化进行优化与调整。初期尽量遵循三范式,随着业务复杂度提升,再根据性能、扩展性、安全性逐步反范式化或重构。


欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1701220998@qq.com
导航页 GitHub