数据表设计之主键自增、UUID或联合主键

最近在做数据库设计的时候(以MySQL为主),遇到不少困惑,因为之前做数据库表设计,基本上主键都是使用自增的形式,最近因为这种做法,被领导指出存在一些不足,于是我想搞明白哪里不足。

一、MySQL为什么建议使用自增?

通过网上查阅资料,得出一个这样的结论:
表的主键一般都要使用自增 id,不建议使用业务id ,是因为使用自增id可以避免页分裂。

按照我过去的实践:
选择使用自增可以避免很多麻烦,主要体现是数据的唯一性(从1到xxx,肯定不会重复的)。

1.什么是页分裂?

这块我没看太明白,我主要参考如下链接:
一看就懂的:MySQL数据页以及页分裂机制

为什么?mysql不推荐使用uuid或者雪花id作为主键?

二、UUID作为主键的优劣势是什么?以及它的应用场景是什么?

1.UUID和自增int型作为主键的比较,有哪些优势和劣势?

(1)优势

  • UUID值在不同的表、数据库、甚至是服务器中都是全局唯一的,所以你可以合并来自不同数据库,甚至是不同服务器上不同数据库上的数据行;
  • UUID值不会在URL中暴露你的数据信息。例如,一个客户可以通过 id10来访问他的账号地址 http://www.example.com/c/10/ ,他可以很轻松地猜到会有 id 11, 12等等的客户,这可能被拖库,或被别人猜到你的用户量;
  • UUID值生成的时候不需要查一遍数据库,并且它还简化了应用层的逻辑。例如,当你要给父表和子表插入数据时,一般你要先把数据插到父表里,然后才能插到子表里。但是如果你用UUID的话,你可以直接生成父表的主键,然后在一个事务里同时把数据插到父表和子表里。
专业名词解释

拖库:指黑客通过各种社工手段、技术手段将数据库中敏感信息非法获取,一般这些敏感信息包括用户的账号信息如用户名、密码;身份信息如真实姓名、证件号码;通讯信息如电子邮箱、电话、住址等。

(2)劣势

  • 存储UUID值(16字节)需要的存储空间比INT型(4字节)甚至是 BIGINT型(8字节)都要大;
  • 调试起来会更难一些,你可以想象一下平时你只需要 WHERE id = 10 现在你要写 WHERE id = ‘df3b7cb7-6a95-11e7-8846-b05adad3f0ae’;
  • UUID 值通常会因为它的大小和未被排序的问题导致性能问题。

参考链接:
MySQL主键应该用UUID还是INT类型

一分钟让你了解拖库、洗库和撞库

2.哪些应用场景应该使用UUID作为主键?

简要概括UUID的适用场景:主要适合用在大型项目微服务架构中,保证全局ID唯一性(大型项目微服务架构集成各式各样的子系统,避免ID冲突)。

起初我在数据表设计的时候就与项目经理争论过,挺类似这个链接的对话:UUID与数字ID的区别与适用场景

三、什么是联合主键?联合主键的适用场景又是什么?

1.什么是联合主键

指用2个或者是2个以上的字段组成的主键,用这个主键包含的字段作为主键,这个组合在数据表中是唯一,且附加上了主键索引。

2.联合主键的适用场景是什么?

我能想到一个用户信息,针对某个一个区域如果用用户ID或用户ID+用户姓名作为主键,难以保持数据的唯一性,因为这一个地区不仅仅是有一个小马哥,可能有七八个人,如此,前面提到的用户ID或用户ID+用户姓名显然是行不通的,这时可以把身份证加入主键,变成了用户ID+用户姓名+身份证(形成了一个联合主键),这样一来该用户数据的唯一性得到了验证。当然了,联合主键的场景不仅仅是这个,关键看业务场景。

四、数据表设计心得分享

从外包公司->创业公司->教育公司->现在所在公司,回过头来看过去我的数据表设计方面,存在的一个最大不足,即着重考虑技术实现难易层面,而轻视业务场景适用性、扩展性、稳定性等。

文章目录
  1. 1. 一、MySQL为什么建议使用自增?
    1. 1.1. 1.什么是页分裂?
  2. 2. 二、UUID作为主键的优劣势是什么?以及它的应用场景是什么?
    1. 2.1. 1.UUID和自增int型作为主键的比较,有哪些优势和劣势?
      1. 2.1.1. (1)优势
        1. 2.1.1.1. 专业名词解释
      2. 2.1.2. (2)劣势
  3. 3. 2.哪些应用场景应该使用UUID作为主键?
  4. 4. 三、什么是联合主键?联合主键的适用场景又是什么?
    1. 4.1. 1.什么是联合主键
    2. 4.2. 2.联合主键的适用场景是什么?
  5. 5. 四、数据表设计心得分享