如何设计数据库

结合你之前问的 Java 17MySQL,设计数据库不仅要考虑业务,更要考虑Java 对象映射(ORM)MySQL索引/存储特性。给你一套实战性很强的设计方法论:

1. 核心设计三范式(要遵守,但别死守)

  • 基础:遵循第三范式(3NF),消除冗余,避免更新异常。
  • 适度冗余(反范式):为了查询性能,允许适度冗余。比如订单表冗余商品名称,这样即使商品改名,历史订单仍显示旧名称(快照),还能减少连表查询。

2. 字段类型选型(结合 Java & MySQL)

选错类型是性能杀手,对照着选:

  • 主键 ID:Java 用 Long,MySQL 用 BIGINT。有分布式需求不要用 UUID(性能差),建议用雪花算法(Snowflake)生成的 bigint
  • 短文本/枚举:Java 用 IntegerString,MySQL 用 TINYINT(状态码)或 VARCHAR(32)
  • 长文本:Java 用 String,MySQL 用 TEXTLONGTEXT。注意,含 TEXT 字段的表性能较差,建议拆到单独的附表
  • 金额/价格绝对不要用 float/double!Java 用 BigDecimal,MySQL 用 DECIMAL(18,2)(18位整数,2位小数),精度最高。
  • 时间强烈建议用 DATETIME(范围广、不带时区陷阱)或 TIMESTAMP。Java 对应 LocalDateTime,配合 MyBatis-Plus 自动填充。

3. 索引设计(最关键的“银弹”)

  • 必备索引WHEREORDER BYGROUP BYJOIN 关联字段必须建索引。
  • 联合索引原则:遵循最左前缀法则,把区分度最高(选择性好)的字段放最左边。
  • 覆盖索引:查询字段尽可能是索引里的字段(SELECT 只取必要列),避免“回表”查询。
  • 注意VARCHAR 长字段建索引要指定长度(如 name(50)),不要无脑全字段索引。

4. 必备“审计”字段(对接 Java 17 最佳实践)

每个表必须包含以下 4 个字段,配合 Spring Data JPA 或 MyBatis-Plus 的自动填充:

create_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) COMMENT '创建时间';
update_time DATETIME(3) NOT NULL DEFAULT CURRENT_TIMESTAMP(3) ON UPDATE CURRENT_TIMESTAMP(3) COMMENT '更新时间';
created_by BIGINT NOT NULL COMMENT '创建人ID';
updated_by BIGINT NOT NULL COMMENT '修改人ID';

小技巧:DATETIME(3) 支持毫秒,Java 17 的 InstantLocalDateTime 完美映射。

5. 避免“大表”和“大事务”

  • 单表数据量预估超 500万-1000万 时,必须考虑分库分表(如 ShardingSphere)或分区表
  • 事务中尽量只操作必要表,避免在事务中调用远程 RPC 或外部接口,防止锁时间过长。

最后给你的设计清单(Checklist)

  1. 是否有逻辑删除(is_deleted)字段?(用 tinyint,配合唯一索引时记得把删除标记带进去做复合唯一)。
  2. 字符集统一用 utf8mb4(支持表情符号),排序规则用 utf8mb4_general_ciutf8mb4_unicode_ci
posted @ 2026-07-05 19:26  喝杯咖啡  阅读(6)  评论(0)    收藏  举报