云计算百科
云计算领域专业知识百科平台

主键id的作用以及为什么主键id不适合运用到业务中

先澄清一个概念:主键 id 本身当然可以作为数据库主键。通常说“id 不能用到业务中”,意思是:不要让数据库的技术主键 id 直接承担业务含义,或不要把业务字段当主键。也就是要把“技术主键”和“业务标识”分开。

一、设计表时,主键 id 的作用

  • 唯一标识一行数据
    每行记录都有一个稳定、唯一的身份,避免靠多个字段组合才能定位。

  • 保证实体完整性
    主键非空、唯一,数据库层面防止重复记录。

  • 作为外键关联依据
    子表通过 user_id、order_id 关联父表,保持引用完整性。

  • 提高查询和更新效率
    WHERE id = ? 能快速定位记录。InnoDB 中主键还是聚簇索引,决定数据物理组织方式。

  • 影响索引和存储性能
    二级索引通常存储主键值。主键越短、越有序,索引越小,插入越稳定。自增 bigint 通常比 UUID 更适合做 InnoDB 主键。

  • 支撑 ORM、分页、复制、分片、迁移
    ORM 映射、游标分页、数据同步、分库分表、数据合并都需要一个稳定的唯一 ID。

  • 隔离业务变化
    业务字段会变,技术主键不变。业务规则调整时,不影响表之间的关联。

  • 二、为什么 id 不适合“运用到业务中”

    这里的 id 通常指自增主键、数据库内部 ID。它适合做技术主键,但不适合直接当业务标识。

  • 没有业务含义
    用户看到订单 id 1001,不知道它代表什么。业务需要的是订单号、用户编号、学号这类可读、可校验的标识。

  • 容易被枚举和攻击
    自增 id 可预测,/orders/1001 改成 /orders/1002 就能遍历。容易造成数据泄露、越权访问,即 IDOR 漏洞。

  • 数据库迁移或分库分表时会变/冲突
    单库自增 id 在多库、多服务、数据合并时可能重复。业务不能依赖这种可能变化的内部 ID。

  • 业务字段做主键不稳定
    手机号会换绑,身份证会升位,邮箱会变,订单号格式可能调整。主键一旦更新,所有外键、索引都要跟着变,代价很大。

  • 性能和存储问题
    如果用手机号、身份证、UUID 等长业务字段做主键,InnoDB 二级索引会变大,插入可能随机,导致页分裂和查询变慢。

  • 隐私和合规风险
    身份证、手机号、邮箱做主键,会把这些敏感信息扩散到大量关联表和索引中,泄露风险高,也不利于匿名化。

  • 业务唯一性范围不同
    业务字段可能只是“租户内唯一”“机构内唯一”,而主键通常要求全表甚至全局唯一。

  • 插入前拿不到 id,不利于幂等
    自增 id 由数据库生成,插入前不知道。业务幂等通常需要业务请求号、订单号等提前生成的业务键。

  • 三、正确做法

    通常采用:

    • 技术主键:id bigint unsigned auto_increment 或雪花 ID、UUID,无业务含义。
    • 业务唯一键:如 order_no、user_no、phone,加唯一索引。
    • 对外展示:用业务编号、UUID、加密 ID,不直接暴露自增 id。
    • 内部关联:外键仍用 id,保证效率和稳定。

    示例:

    CREATE TABLE orders (
    id BIGINT UNSIGNED AUTO_INCREMENT PRIMARY KEY, — 技术主键
    order_no VARCHAR(32) NOT NULL, — 业务编号
    user_id BIGINT UNSIGNED NOT NULL,
    amount DECIMAL(10,2),
    UNIQUE KEY uk_order_no (order_no),
    KEY idx_user_id (user_id)
    );

    对外用 order_no,内部关联用 id。

    总结:主键 id 的职责是稳定、唯一、高效地标识数据库内部记录;业务标识的职责是可读、可校验、可展示、可变更。两者最好分开。 不是 id 不能做主键,而是不要让数据库主键 id 直接承担业务含义。

    赞(0)
    未经允许不得转载:网硕互联帮助中心 » 主键id的作用以及为什么主键id不适合运用到业务中
    分享到: 更多 (0)

    评论 抢沙发

    评论前必须登录!