一、前言
上一篇我们已经完成了 CRUD。
但是你会发现一个问题:
用户的信息越来越多比如:
- 用户名
- 密码
- 手机号
- 邮箱
- 性别
- 生日
- 收货地址
- 默认地址
- 省市区
这时候很多初学者会这样干:
全部塞进 user 表最后 user 表会越来越臃肿。
所以这一篇,我们正式进入:
❗ 表结构设计(建模)
这一步,才是真正开始接近企业开发。
二、企业为什么不能只用一张 user 表?
很多人最开始会这样设计:
CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT, username VARCHAR(64), password VARCHAR(128), phone VARCHAR(20), email VARCHAR(100), real_name VARCHAR(50), province VARCHAR(50), city VARCHAR(50), detail_address VARCHAR(200) );看起来没问题。
但实际上:
账号信息
用户资料
收货地址
是三种完全不同的数据。
三、企业里的真实做法:拆表
所以企业里通常会拆成:
user 用户主表
user_detail 用户详情表
user_address 用户地址表
这样设计后:
- 结构更清晰
- 更容易扩展
- 更符合业务划分
- 查询性能更稳定
四、第一张表:user(用户主表)
1. 建表语句
CREATE TABLE user ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', username VARCHAR(64) NOT NULL UNIQUE COMMENT '用户名', password VARCHAR(128) NOT NULL COMMENT '密码', create_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time DATETIME NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' );2. 这张表存什么?
这一张表只存:
登录相关信息比如:
- 用户名
- 密码
- 时间
它是:
账号体系核心表五、重点字段讲解(企业必须懂)
1️⃣ id(主键)
id BIGINT PRIMARY KEY AUTO_INCREMENT含义:
每条数据唯一标识为什么用 BIGINT?
因为企业数据量可能很大。
INT 最大约 21 亿 BIGINT 更安全所以很多企业直接统一:
主键默认 BIGINTAUTO_INCREMENT 是什么?
表示:
主键自动增长插入第一条:
id = 1第二条:
id = 2数据库自动维护。
六、username 为什么 UNIQUE?
username VARCHAR(64) NOT NULL UNIQUE重点:
UNIQUE = 唯一索引意味着:
用户名不能重复比如:
zhangsan只能有一个。
否则会报错。
七、password 为什么 VARCHAR(128)?
很多人会问:
密码不是123456吗? 为什么128?因为企业里不会直接存明文密码。
而是:
加密后的字符串比如:
BCrypt MD5 SHA加密后长度会很长。
所以一般:
VARCHAR(128)甚至更大。
八、create_time 和 update_time(企业高频)
1️⃣ create_time
create_time DATETIME DEFAULT CURRENT_TIMESTAMP表示:
数据创建时间插入时自动生成。
2️⃣ update_time
update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP表示:
数据更新时间每次 UPDATE 自动刷新。
九、第二张表:user_detail(用户详情表)
1. 建表语句
CREATE TABLE user_detail ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', user_id BIGINT NOT NULL UNIQUE COMMENT '用户ID', real_name VARCHAR(50) COMMENT '真实姓名', phone VARCHAR(20) COMMENT '手机号', email VARCHAR(100) COMMENT '邮箱', gender TINYINT DEFAULT 0 COMMENT '性别:0-未知 1-男 2-女', birthday DATE COMMENT '生日', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间' );十、为什么拆出 user_detail?
因为:
用户资料 ≠ 登录信息很多业务里:
登录频率很高但是:
用户资料很少修改所以企业通常会拆表。
十一、这里最关键的字段:user_id
user_id BIGINT NOT NULL UNIQUE这个字段是:
❗ user_detail 属于哪个 user
为什么 UNIQUE?
因为:
一个用户只有一份详情所以:
user 1 —— 1 user_detail这就叫:
一对一关系十二、第三张表:user_address(用户地址表)
1. 建表语句
CREATE TABLE user_address ( id BIGINT PRIMARY KEY AUTO_INCREMENT COMMENT '主键ID', user_id BIGINT NOT NULL COMMENT '用户ID', receiver_name VARCHAR(50) NOT NULL COMMENT '收货人姓名', phone VARCHAR(20) NOT NULL COMMENT '收货人电话', province VARCHAR(50) NOT NULL COMMENT '省', city VARCHAR(50) NOT NULL COMMENT '市', district VARCHAR(50) NOT NULL COMMENT '区/县', detail_address VARCHAR(200) COMMENT '详细地址', is_default TINYINT DEFAULT 0 COMMENT '是否默认:0-否 1-是', create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '创建时间', update_time DATETIME DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间', INDEX idx_user_id (user_id) );十三、为什么 user_address 不加 UNIQUE?
因为:
一个用户可以有多个地址比如:
家 公司 父母家所以:
同一个 user_id 可以出现多次这就是:
一对多关系十四、为什么加索引?
INDEX idx_user_id (user_id)因为后面经常会这样查:
SELECT * FROM user_address WHERE user_id = 1;所以:
user_id 是高频查询字段企业里通常会加索引。
十五、三张表关系(核心)
最终关系:
user 和 user_detail 1对1
user 和 user_address 1对多
十六、核心
这一篇最重要的不是语法。
而是: 开始理解“为什么企业要拆表”
📌 数据库拆表规则(最终笔记版)
❗ 总原则:
一张表,只做一件事。
-----------------------------------
怎么判断一张表是不是“做了多件事”?
① 职责不同
账号、资料、地址不是一类数据。② 出现一对多
一个用户多个地址、多个订单。③ 字段太多
一张表几十上百字段,说明职责可能混乱。④ 修改频率不同
高频修改字段不要影响核心主表。⑤ 出现大字段
富文本、长内容、JSON 单独拆。⑥ 查询场景不同
登录、用户中心、收货页关注的数据不同。-----------------------------------
📌 最终本质:
拆表不是死记规则,而是判断:
这张表是不是还只做一件事?
-----------------------------------
📌 案例:
user
→ 账号登录user_detail
→ 用户资料user_address
→ 收货地址账号 ≠ 资料 ≠ 地址
所以拆表。
十七、一句话总结
企业数据库设计,本质是:
👉按业务职责拆表,而不是把所有字段塞进一张表。
下一篇
下一篇进入:
SQL 第三篇:表关系设计(user_id 到底是什么
真正讲透:
一对一 一对多 外键 user_id以及:
为什么 JOIN 能把表拼起来