多主键(Primary Key)格式规范及企业数据库模型主键设计咨询
关于数据库主键设计的两个问题解答
一、多主键(复合主键)的设计格式
首先明确:你说的“多个主键”其实是复合主键——用多个字段共同构成表的主键,以此唯一标识每条记录。
设计格式与实现
在SQL语法里,复合主键的定义很直观,举个关联表的例子(比如订单详情表,需要订单ID+产品ID来唯一确定一条明细):
CREATE TABLE OrderDetails ( OrderID INT, ProductID INT, Quantity INT, PRIMARY KEY (OrderID, ProductID) );
这里OrderID和ProductID组合起来就是这张表的复合主键,能确保不会出现重复的订单+产品组合记录。
适用场景与注意事项
- 适合场景:多用于多对多关系的中间表(比如学生选课表的学生ID+课程ID),或是业务逻辑上必须多个字段组合才能唯一标识的表。
- 避坑提醒:别把太多字段塞进复合主键(比如超过2-3个),否则后续表关联、索引查询会变得繁琐,还会增加存储和维护成本。如果复合字段过多,不如考虑用独立的代理主键(比如自增数字ID)替代,再把原复合字段设为唯一约束。
二、纯数字主键的位数规划:是否需要每个表用不同长度?
你的老师提到“优质主键仅由数字构成”是合理的——数字主键(比如INT、BIGINT类型)索引效率更高、存储占用更小,比字符串主键更易维护。但关于“20个表要设计不同位数主键”,可以分两种情况分析:
如果是业务主键(带实际业务含义)
比如Employee Key是员工工号、Customer Key是客户编号,这类主键本身有业务意义,那确实可以根据业务最大预期量设定位数:
- 员工最多100万:7位数字(9999999)足够覆盖
- 客户最多1000万:8位数字(99999999)刚好
- 以此类推,预留未来3-5年的业务增长空间,避免后续出现位数不足需要扩容的麻烦。
如果是代理主键(无业务意义,仅用于标识)
如果主键只是用来唯一标识记录,没有实际业务含义(比如自增ID),那完全没必要给每个表设置不同位数!直接用BIGINT类型(支持超宽数字范围),每个表用自增数字主键即可——这种方式简单省心,既满足老师“纯数字主键”的要求,也不用担心位数不够的问题。
总结建议
- 若业务有明确编号规则(比如工号、客户号必须固定位数),按你设想的方式设计没问题;
- 若只是需要纯数字的唯一标识,优先用统一的代理主键(比如自增BIGINT),不用纠结不同表的位数差异,反而能减少设计和维护的工作量。
内容的提问来源于stack exchange,提问作者Paul Shan




