直接回答:单机优先用与业务无关的自增 BIGINT 主键;分布式场景需要不依赖单点发号时用雪花 ID(snowflake);UUID 一般不推荐直接做主键。
展开解析:InnoDB 表按主键组织成聚簇索引,数据页按主键有序排列。自增 ID 写入是顺序追加到 B+ 树最右侧页,几乎不触发页分裂,碎片少、缓存友好;UUID 是随机的,插入位置随机,导致频繁页分裂、随机 I/O 和碎片,且 36 字符的字符串主键会膨胀所有二级索引——二级索引的叶子节点存的是主键值,主键越长,每个二级索引越大。如果没有显式主键,InnoDB 会选第一个非空唯一索引,都没有就生成 6 字节隐藏 rowid,浪费空间且不可控,所以主键必须显式指定。雪花 ID 是 64 位趋势递增整数(时间戳+机器位+序列号),兼顾有序性和去中心化发号,适合分库分表;要注意时钟回拨问题。必须用 UUID 时可存 BINARY(16),MySQL 8.0 用 UUID_TO_BIN(uuid, 1) 交换时间位使其近似有序。
实践要点:业务唯一字段(如订单号)应建唯一索引而非当主键;分库分表后数据库自增 ID 不再全局唯一,需雪花 ID 或号段模式(leaf-segment)。
追问方向:雪花 ID 的位结构和时钟回拨怎么处理?自增主键在高并发下有什么锁竞争(AUTO-INC 锁)?主键长度如何影响二级索引大小? (约 378 字)