news 2026/5/7 2:17:32

SQL 第二篇:表结构设计(为什么企业要拆成 3 张表)

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
SQL 第二篇:表结构设计(为什么企业要拆成 3 张表)

一、前言

上一篇我们已经完成了 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 更安全

所以很多企业直接统一:

主键默认 BIGINT

AUTO_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 能把表拼起来
版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/5/7 2:16:43

TMS320F2803x/6x CLA实战:手把手教你用C语言实现ADC采样与PWM相位联动控制

TMS320F2803x/6x CLA实战:C语言实现ADC采样与PWM相位联动控制 在电力电子和电机控制领域,实时性往往是系统设计的核心挑战。当我们需要在微秒级时间内完成信号采集、算法处理和控制输出时,传统单核处理器的性能瓶颈就会显现。德州仪器&#x…

作者头像 李华
网站建设 2026/5/7 2:02:10

构建自进化AI记忆系统:Engram架构、部署与智能体集成实战

1. 项目概述:构建一个会自我进化的AI记忆系统最近在折腾AI智能体项目,一个绕不开的痛点就是“记忆”。无论是构建一个能长期对话的聊天机器人,还是一个能自主学习和决策的智能体,你很快会发现,给它们装上一个简单的“记…

作者头像 李华
网站建设 2026/5/7 1:54:27

ScintillaNET:终极.NET代码编辑组件深度解析与实战指南

ScintillaNET:终极.NET代码编辑组件深度解析与实战指南 【免费下载链接】ScintillaNET A Windows Forms control, wrapper, and bindings for the Scintilla text editor. 项目地址: https://gitcode.com/gh_mirrors/sc/ScintillaNET ScintillaNET是一个专业…

作者头像 李华
网站建设 2026/5/7 1:48:27

LocalAI:开源本地大模型推理服务器,兼容OpenAI API的私有化部署方案

1. 项目概述:当大模型遇见本地化 最近几个月,我身边不少搞开发的朋友都在讨论一个事儿:怎么才能在自己电脑上,或者公司内网里,低成本、安全地跑起来那些动辄几十上百亿参数的大语言模型?无论是想做个内部知…

作者头像 李华
网站建设 2026/5/7 1:44:55

AI多智能体协作开发:构建自动化软件团队的架构与实践

1. 项目概述:一个能自动运转的AI开发团队如果你和我一样,曾经尝试过用各种AI工具来辅助开发,那你一定经历过这种痛苦:为了完成一个简单的登录功能,你得先打开一个聊天窗口,扮演“产品经理”去分析需求&…

作者头像 李华
网站建设 2026/5/7 1:41:28

2026 代际领先:纯视觉无感定位引擎,室外数字孪生实时坐标生成

2026 代际领先:纯视觉无感定位引擎,室外数字孪生实时坐标生成2026年,空间智能进入代际分水岭。室外场景长期受制于GPS遮挡、标签依赖、基站昂贵、跨镜断联、虚实脱节五大瓶颈,传统定位与孪生方案已无法支撑“动态可计算、全域可掌…

作者头像 李华