首页 开发教程 数据库设计最佳实践:我们团队沉淀下来的规范

数据库设计最佳实践:我们团队沉淀下来的规范

开发教程 2025年12月4日
361 浏览

数据库设计规范化是保障产品质量的重要基础。结合 qKnow、qData、qModel 等产品的实践经验,我们制定了本《数据库设计规范》。
通过统一的数据库设计标准,团队可在不同项目间保持一致的结构风格,提高性能、降低维护成本,并确保产品具备良好的扩展能力。


一、模块设计

1. 模块划分规范

模块划分是数据库设计的基础环节,应以业务逻辑清晰结构合理易于维护与扩展为原则,确保系统在开发、迭代及后期运维中的可持续性。

  • 业务驱动:模块划分应基于实际的业务需求,确保每个模块对应一个明确的功能或业务流程,避免人为拆分或随意堆叠。
    示例:

    • 用户管理模块(User Management Module)负责用户注册、登录、角色分配等。
    • 项目管理模块(Project Management Module)负责项目信息维护、任务分配、进度跟踪。
    • 报表统计模块(Report Module)负责数据统计与可视化展示。
  • 高内聚低耦合:各模块之间的耦合应尽量降低,确保模块内部功能的高内聚性。比如,用户管理模块(um)不应直接依赖项目管理模块(pm)的表结构,而应通过接口或服务层交互。
    说明: 如果一个模块需要频繁调用另一个模块的接口,说明划分可能存在问题,应重新审视职责边界。

  • 分层设计:模块划分可根据业务逻辑和功能层次进行设计,通常包括:

    • 基础层:如数据库交互、通用工具类;
    • 逻辑层:如业务规则计算、状态机处理;
    • 应用层:如用户接口、API服务、前端对接逻辑。

    分层结构有助于系统解耦、测试隔离和分布式部署。

  • 均衡性:模块划分应尽量均衡,避免某些模块过大(如包含上百张表),影响后期的维护和扩展。建议单个模块所辖表数量不超过30张,若超出应考虑进一步拆分。

  • 灵活性与扩展性:模块设计应考虑到未来可能的扩展或变更,避免过度耦合,保持模块的灵活性和扩展性。例如,用户模块未来可能需要支持多租户,应在设计初期预留 tenant_id 字段或采用独立 schema 方案。

2. 模块命名规范

良好的模块命名是数据库可读性和可维护性的基础,模块命名应遵循统一、简洁、有意义的原则,确保团队成员一目了然。

  • 简洁且有意义:模块名称应简洁且能清晰表达模块的功能,避免过长或过于抽象的命名。
    示例:

    • 用户管理模块 → userum
    • 项目管理模块 → projectpm
  • 使用缩写:由于模块名将作为表名的前缀,命名时应简化为适当的缩写,确保不超过合理长度(建议2~4个字母)。常见示例:

    模块名称 缩写 示例表名
    用户管理模块 um um_user
    项目管理模块 pm pm_project
    系统配置模块 sc sc_config
  • 避免冗余:命名中避免使用“系统”、“管理”等冗余词汇,应侧重反映模块的核心功能。
    不推荐: user_manage_system
    推荐: um_user

  • 统一命名规则:所有项目必须采用统一的命名规范,避免因不同团队或开发人员命名方式不一致而影响维护性。建议在项目启动阶段由架构组统一发布模块缩写对照表。


二、数据库命名规范

1. 环境区分命名

为保障开发、测试、生产环境的数据隔离与部署安全,数据库命名必须严格区分环境:

  • 开发库[项目代号]_dev
    示例:qData_devqKnow_dev

  • 测试库[项目代号]_test
    示例:qData_testqModel_test

  • 生产库[项目代号]_prod
    示例:qKnow_prodqThing_prod

2. 项目代号命名

  • 项目代号应简短(建议2~10个字符)、唯一、具有业务识别性,便于管理和区分不同项目的数据库。
    • 示例:qData(千桐数据中台)、qKnow(千桐知识平台)、qAuth(统一身份认证平台)

3. 统一命名规则

  • 所有环境下的数据库命名格式必须统一,确保运维人员能快速识别环境类型。
  • 建议在数据库创建脚本、CI/CD 配置文件中强制校验命名规范。

三、表设计

1. 表命名规范

  • 小写字母与下划线:所有表名必须使用小写字母,单词之间用下划线分隔。
    正确示例:user_infoorder_detailsproduct_category
    错误示例:UserInfoORDERDETAILSuser-info
  • 简洁且准确:表名应简短且准确反映其存储的数据实体。
    示例:

    • um_user:用户管理模块中的用户主表
    • pm_project:项目管理模块中的项目主表
  • 避免业务术语泛化:禁止使用“数据表”、“记录表”、“信息表”等模糊词汇。应聚焦实体本身,如 user 而非 user_data_table

  • 避免特殊字符和数字:表名不得包含空格、中文、-#@ 等特殊字符,也不应以纯数字开头或结尾。

  • 前缀规则:所有业务表必须以所属模块缩写作为前缀。
    示例:

    • um_user_role_rel(用户-角色关系表)
    • om_order_history(订单历史表)
    • sm_system_config(系统配置表)

2. 特殊类型表命名标识

为提升数据库可读性,特定用途的表需使用统一后缀标识:

表类型 命名后缀 示例 说明
关系表 _rel um_user_role_rel 多对多关联表
日志表 _log sm_operation_log 操作日志、错误日志等
历史记录表 _history om_order_history 用于记录数据变更历史
配置表 _config sm_app_config 存储系统或应用级配置参数

四、字段设计

1. 字段逻辑名命名规范(技术命名)

  • 简短且明确:字段名应体现其业务含义,如 user_idorder_amount,避免 uidamt 等过度缩写。

  • 小写字母与下划线:字段名统一使用小写+下划线风格。
    示例:create_timerequest_ipdel_flag

  • 避免保留字:严禁使用 SQL 保留字作为字段名,如 ordergroupdescuser 等。若必须使用,需加反引号(不推荐)。

  • 统一命名规则:同一语义字段在不同表中应保持命名一致。
    示例:所有表中的“创建人”字段均命名为 create_by,而非 creatorcreated_by_user

2. 字段名命名规范(业务命名 / 中文注释用)

  • 中文命名:在数据模型文档或ER图中,字段应使用中文描述,确保业务人员可理解。
    示例:

    • 物理列名:user_id → 逻辑名称:用户ID
    • 物理列名:create_time → 逻辑名称:创建时间
  • 简洁明了:避免技术术语堆砌,如“用户唯一标识符”应简化为“用户ID”。

  • 避免歧义:如“时间”应明确为“创建时间”或“更新时间”,不可仅写“时间”。

3. 字段注释规范

高质量的字段注释是数据库自文档化的关键:

  • 简洁明了:注释应一句话说明字段用途。
    示例:user_status 的注释为:“用户状态:0-禁用,1-启用”

  • 业务驱动:注释应从用户或业务视角出发,而非技术实现。
    好注释:“是否接收营销短信(0-否,1-是)”
    差注释:“布尔标志位,用于短信订阅”

  • 注释内容应包含

    • 字段业务含义
    • 枚举值说明(如有)
    • 是否允许为空(NULL)
    • 是否为主键/外键
    • 默认值(如有)
  • 统一风格:建议采用如下模板:

  • 示例 SQL:

CREATE TABLE um_user (
    id BIGINT PRIMARY KEY COMMENT \'主键ID。非空,唯一标识用户记录。\',
    username VARCHAR(50) NOT NULL COMMENT \'用户名。唯一且非空。\',
    password VARCHAR(100) NOT NULL COMMENT \'登录密码。加密存储,非空。\',
    status TINYINT DEFAULT 1 COMMENT \'用户状态。取值:0=禁用,1=启用。非空,默认1。\',
    create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT \'记录创建时间。默认当前时间。\',
    update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT \'记录最后修改时间。自动更新。\'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT=\'用户信息表。用于存储系统用户的基本信息。\';

4. 字段数据类型设置规范

  • 合理选择数据类型

    业务场景 推荐类型 示例
    用户ID、订单ID BIGINT 自增主键或雪花ID
    用户名、邮箱 VARCHAR(50~255) 根据实际长度预估
    密码 VARCHAR(100) 存储加密后的字符串
    金额 DECIMAL(18,2) 避免使用 FLOAT/DOUBLE
    创建时间 DATETIME 精确到秒
    是否删除 TINYINT(1) 0-否,1-是
    长文本(如描述) TEXT 不建议超过 64KB
  • 预设类型配置:建议在数据库建模工具中预定义常用字段模板(如“标准主键”、“标准时间戳”),供设计时直接复用。

  • 兼顾扩展性:如手机号当前为11位,但未来可能支持国际号码,建议 VARCHAR(20) 而非 CHAR(11)。

  • 避免过度设计:不要为“可能将来会用到”的场景预留超大字段。例如,用户昵称通常不超过30字符,无需定义为 VARCHAR(255)。


五、字段排序原则

合理的字段顺序有助于提升可读性和查询效率。

1. 常规字段排序(推荐顺序)

  1. 主键字段(如 id
  2. 外键字段(如 user_id, project_id
  3. 核心业务字段(如 username, order_no, amount
  4. 状态/分类字段(如 status, type, gender
  5. 元数据字段(如 create_by, create_time, update_time, del_flag
id,
tenant_id,          -- 多租户场景
username,
email,
phone,
status,             -- 0-禁用 1-启用
gender,             -- 性别:0-未知 1-男 2-女
create_by,
create_time,
update_time,
del_flag

2. 类型字段排序

  • 分类字段靠前:如 genderuser_typeorder_source 等,便于 WHERE 条件过滤。
  • 枚举字段优先:高频使用的枚举字段(如状态)建议排在业务字段之后、时间字段之前。

六、字段分组原则

1. 相关字段分组

  • 逻辑相关字段集中放置

    • 用户基本信息:username, email, phone, avatar
    • 审计字段:create_by, create_time, update_by, update_time
    • 软删除字段:del_flag, delete_time
  • 数据类型相似字段分组

    • 所有时间字段集中(create_time, update_time, login_time
    • 所有金额字段集中(order_amount, discount, pay_amount

2. 频繁查询字段优先

  • 高频查询字段靠前:如 user_idorder_statuscreate_time 等常用于 WHERE 或 JOIN 的字段,应置于表前部。
  • 索引字段显性化:虽然字段物理位置不影响索引性能,但将索引字段靠前有助于开发人员快速识别关键字段。

附录:常见字段命名及其规范

序号 字段含义 字段名称 备注 类型 长度
1 分类/类别 category 用于表示类别或分类的字段。 VARCHAR 128
2 类型 type 用于表示类型的字段,常见于状态类型等。 VARCHAR 10
3 描述 description 用于简要描述某个数据实体的字段。SQL中多处使用 varchar(512) VARCHAR 512
4 介绍 introduction 用于详细介绍或说明某个数据实体的字段。 TEXT
5 编码 code 唯一标识编码(如:商品编码,用户编码等)。 VARCHAR 128
6 级别 level 用于表示级别、权限等级等。 INT
7 内容 content 用于存储主要的内容字段。 TEXT
8 排序值 order_num 排序字段,通常用于排序或优先级控制。 INT
9 状态 status 状态字段(如:启用/禁用,激活/冻结等)。 CHAR 1
10 审核状态 audit_status 审核状态(如:待审核、审核通过、审核拒绝)。 CHAR 1
11 审核人 auditor_id 审核人(通常是审核人的ID或用户名)。 BIGINT
12 审核时间 audit_time 表示审核的时间,通常用于记录审核的具体时间点。 DATETIME
13 名称 name 用于表示名称字段,如用户姓名,项目名称等。 VARCHAR 128
14 手机号 phone 手机号码字段。 VARCHAR 20
15 邮箱 email 邮箱字段。 VARCHAR 100
16 地址 address 地址字段。 VARCHAR 255
17 性别 gender 性别字段(如:男/女)。 TINYINT 1
18 年龄 age 年龄字段。 INT
19 生日 birthday 出生日期字段。 DATE
20 头像 avatar 头像字段。 VARCHAR 256
21 创建人 create_by 记录创建人的姓名。 VARCHAR 32
22 创建人id creator_id 记录创建人的id。 BIGINT
23 创建时间 create_time 记录创建时间字段。 DATETIME
24 更新人 update_by 记录最后更新人的姓名。 VARCHAR 32
25 更新人id updater_id 记录最后更新人的id。 BIGINT
26 更新时间 update_time 记录最后更新时间字段。 DATETIME
27 删除人 delete_by 软删除字段,表示记录删除者的姓名。 VARCHAR 32
28 删除人id deleter_id 软删除字段,表示记录删除者的id。 BIGINT
29 删除时间 delete_time 软删除字段,表示记录删除的时间。 DATETIME
30 是否删除 del_flag 软删除标志(0: 未删除,1: 已删除)。 VARCHAR 1
31 是否有效 valid_flag 用于表示是否有效(0: 无效,1: 有效)。 VARCHAR 1
32 是否锁定 lock_flag 用于表示是否被锁定(0: 未锁定,1: 已锁定)。 VARCHAR 1
33 是否启用 enable_flag 0表示禁用,1表示启用。 CHAR 1
34 是否必填 require_flag 用于表示字段是否为必填项,(0: 不必填,1: 必填)。 VARCHAR 1
35 备注 remark 用于补充说明或备注信息。 VARCHAR 512
36 父级ID parent_id 记录的父级ID,用于树状结构或层级关系的父节点标识。 BIGINT
37 子级ID child_id 用于树状结构或层级关系的子节点标识。 BIGINT
38 路径 path 用于存储路径信息,如文件路径,URL路径等。 VARCHAR 256
39 关联ID related_id 关联其他实体的ID(如:订单关联的用户ID)。 BIGINT
40 操作类型 action_type 操作的类型(如:添加、删除、更新等)。 CHAR 1
41 权限 permission 权限字段。 VARCHAR 100
42 权限组 role_group 权限组字段(例如角色分配)。 VARCHAR 100
43 文件名 file_name 文件的名称。 VARCHAR 128
44 文件大小 file_size 文件的大小。 BIGINT
45 文件路径 file_path 文件存储路径。 VARCHAR 256
46 文件类型 file_type 文件类型(如:pdf,jpg,png等)。 VARCHAR 32
47 过期时间 expiry_date 表示某个数据是否过期的时间字段。 DATETIME
48 时间戳 timestamp 用于记录时间戳。 DATETIME
49 请求来源 source 请求来源字段。 CHAR 1
50 请求参数 params 请求参数字段。 TEXT
51 请求IP request_ip 请求来源IP地址。 VARCHAR 45
52 IP地址 ip_address 存储IP地址字段。 VARCHAR 45
53 版本号 version 数据版本字段,记录版本号。 INT
54 是否默认 default_flag 是否为默认值字段(0: 否,1: 是)。 VARCHAR 1
55 触发时间 trigger_time 触发事件的时间。 DATETIME
56 响应时间 response_time 响应事件的时间。 DATETIME
57 访问次数 visit_count 记录访问次数。 INT
58 验证信息 verification_info 用于存储验证信息(如验证码)。 VARCHAR 100
59 唯一标识符 uuid 唯一标识符,常用于分布式系统中。 VARCHAR 36
60 序列号 serial_no 常用于物品、订单、产品等的唯一编号。 VARCHAR 64
61 标签 tag 记录项目、用户、产品等的标签信息。 VARCHAR 128

遵守规范,方能行稳致远。

发表评论
暂无评论

还没有评论呢,快来抢沙发~

客服

点击联系客服 点击联系客服

在线时间:09:00-18:00

关注微信公众号

关注微信公众号
客服电话

400-888-8888

客服邮箱 122325244@qq.com

手机

扫描二维码

手机访问本站

扫描二维码
搜索