主键:用于唯一标识一个表中一行数据。 外键:用于建立两个表之间的关系,A表中有一列是B表中的主键,那么A表中这列的数据就受到B表主键的约束。
那么关于主键应该如何设计呢,这里我说下优缺点:
- 用自动增长字段作为主键,这样的主键可以称之为 非业务主键(或逻辑主键、或代理主键),就是说这列与业务无关,仅仅是作为主键而设计。
- 优点:自增长字段往往是integer bigint类型,最多占8个字节。索引与外键 所占用的空间连带减少,增删改查 效率高。业务变化,不影响,不需要更新主键。
- 缺点:无法转移数据库,比如把表中的一批数据 转移 或 附带到 另一个表中,那么由于是自增长字段,那么会导致无法转移,因为另外一个表可能已经存在部分数据,会造成主键冲突。自增长字段的缺陷。
- 业务数据的完整性,无法保证。
- 用全球唯一标识符GUID,来做主键。依然是非业务主键。
- 优点:可以转移数据库。业务变化,不影响,不需要更新主键。
- 缺点:字符串较长,占用的空间较多,如果用于外键的话,会导致连带其它表占用的空间连带增多。A表中有一列是B表中的主键 ,那么A表中的这列也是需要有个索引的,即存储空间会连带增多。效率变低。
- 即除了正常业务字段外,还是弄个字符串字段来专一保存这个全球唯一标识符,造成存储浪费。业务数据的完整性,无法保证。
- 用业务字段做主键。
- 优点:可以转移数据库,最大化节省了空间,因为并没有 多增加一个非业务字段做主键。业务数据的完整性,可以保证。避免产生垃圾数据,银行就是用业务字段做主键的,虽然效率低,但是安全。
- 缺点:如果业务发生改变,有可能需要修改主键,举例:国家A表用身份证号做主键,然后其他很多表中的身份证号这列都是来自 身份证表A中的主键(即外键),那么如果身份证号升级,比如从1代升级到2代,那么连带的表的外键 的索引 通通都得发生变化,效率极低 因为会连带更新一串用到这个外键的表,可见用业务字段做主键的话,你得保证 主键不经常变化。
- 有些业务使用身份证作为主键
-
优点:可能就是能很好满足按照身份证号进行等值查询的需求,因为是主键所以就不需要回表。
-
缺点:就是索引长度过大,导致每次查询磁盘I/O增加,解决方案是可以采用倒序存储身份证ID,这样就可以进行前缀索引「正序无法满足前缀索引,比如,我们国家的身份证号,一共18位,其中前6位是地址码,所以同一个县的人的身份证号前6位一般会是相同的,这时候如果对身份证号做长度为6的前缀索引的话,这个索引的区分度就非常低了。MySQL前缀索引和索引的选择性
-
MySQL索引与回表 https://www.jianshu.com/p/8991cbca3854