我们聊聊数据库设计那些事儿,怎么才能不踩坑又实用呢
- 问答
- 2026-01-19 10:36:59
- 1
想清楚再动手,别急着敲代码
这可能是最重要的一条了,很多人一接到需求,脑子里立刻浮现出几个表的名字,然后打开软件就开始建表了,这就像盖房子不打地基,后面肯定要出问题,你得先花时间搞清楚,这个系统到底要干什么?它的核心“东西”是什么?你要做一个博客系统,核心就是“文章”;做一个电商网站,核心就是“商品”和“订单”。
把这些核心的东西找出来,每个核心东西就是一个“实体”,它通常就会成为一张表,然后围着这些核心,去想它们有哪些属性,文章”有标题、内容、发布时间;“用户”有名字、邮箱,这些属性就是表的字段,这个阶段,拿张纸笔画画关系图,比直接对着电脑发呆要强一百倍。
给每张表找个“身份证”
你得确保表里的每一条记录都是独一无二的,不然就乱套了,这个“身份证”就是主键,最好是用一个和业务没啥关系的、纯粹的数字(比如自增长的ID)来当主键,为什么这么说呢?这是很多人踩过坑的,比如你用用户名当主键,后来业务要求用户名还能修改,那就麻烦了,因为所有关联到这个名字的地方都得改,但如果你用一个独立的ID,用户名随便改,ID不变,就一点事儿没有,这个ID就像你的身份证号,名字可以改,但身份证号一辈子就那一个。

第三,处理好“关系”是避免混乱的关键
世界上的事物都不是孤立的,数据也一样,常见的关系就三种:
- 一对一:比如一个用户对应一个详细的档案资料,这种情况,你可以把档案资料的所有字段都放在用户表里,但如果资料信息特别多、不常用,单独建一张表用相同的ID关联起来,会让主表更清爽。
- 一对多:这是最常见的,比如一个用户可以写多篇文章,这时候,你就在“多”的那张表(文章表)里,加一个字段,比如叫
user_id,来存放“一”的那张表(用户表)的主键,这样就知道文章是谁写的了。 - 多对多:比如一篇文章可以有多个标签,一个标签也可以被多篇文章使用,这时候你直接在哪张表里加字段都不合适,诀窍就是引入一张中间表,这个中间表很简单,通常就两个字段:
article_id和tag_id,它就像一个记录本,专门记下哪篇文章和哪个标签有关系,想找某篇文章的所有标签,或者某个标签下的所有文章,通过这个中间表一查就清楚了,试图不用中间表,把标签用逗号隔开塞进一个字段里,是初学者最容易踩的大坑,会导致查询极其困难,效率低下,这其实就是《SQL反模式》里提到的“乱穿马路”反模式。
第四,别太追求“完美”,适度冗余换效率
理论上,数据库设计要符合“范式”,目标是减少数据重复,但有时候,死板地遵守范式会让查询变得非常慢,订单表里需要显示收货人的姓名和地址,如果严格按范式,订单表里只存一个用户ID,每次显示订单都要去关联用户表查姓名地址,当订单量巨大时,这会很慢。

一个实用的做法是,在订单表里适度冗余地存上收货人姓名和地址的快照,即使后来用户修改了他的收货地址,但这个订单的地址是不会变的,因为它记录的是下单那一刻的信息,这种用空间(多存一点数据)换时间(查询更快)的做法,在实际项目中非常普遍,关键是要想清楚,这些冗余的数据是不是“历史快照”,会不会引起逻辑混乱。
第五,名字要取得让人能看懂
命名是门艺术,表名、字段名最好用英文(这是编程世界的惯例),要能清晰地表达出它是干什么的,别用缩写,除非这个缩写是全公司公认的,叫 user_name 就比叫 usr_nm 要好懂得多,叫 created_at(创建时间)就比 crt_dt 清晰,好的命名本身就是文档,后来维护的人一看就明白,能省下很多沟通成本。
第六,考虑未来,但别过度设计

设计的时候要有一点前瞻性,想想业务可能怎么发展,用户以后会不会有手机号?表结构能不能比较容易地加字段?但不能因为“可能”需要,现在就加入一大堆永远用不上的字段,这叫“过度设计”,会把简单问题复杂化,最好的设计是能满足当前需求,同时又易于扩展的设计。“加个字段”这种改动成本并不高。
安全意识和性能从小处着手
像密码这种敏感信息,绝对不能明文存储,必须经过加密(比如哈希加盐),这也是一个基本原则性的坑,千万不能踩。
性能方面,给经常用于搜索和关联条件的字段(比如上面提到的各种 _id,还有用户名、商品编号等)加上索引,就像给书加上目录,能极大提高查询速度,但索引也不是越多越好,因为它会影响数据插入和更新的速度。
数据库设计没有唯一的标准答案,它是一个权衡的艺术,核心就是:理解业务,理清关系,保持简单,适度优化,多思考,多画图,多从未来的使用场景出发,就能避开大多数常见的坑,设计出既结实又实用的数据库。
本文由雪和泽于2026-01-19发表在笙亿网络策划,如有疑问,请联系我们。
本文链接:https://www.haoid.cn/wenda/83615.html
