search

Home  >  Q&A  >  body text

php - uuid作为主键,还是用自增呢?

我在网上找了好久,有的人说uuid比较好,就是在分库分表,合并数据什么的比较容易,也有的人说自增好,到了表的数据多的时候,性能比uuid好得多,到底那种比较好呢?有没有在真实生产环境的大神,来给出一个完整的解答?

阿神阿神2896 days ago679

reply all(12)I'll reply

  • 天蓬老师

    天蓬老师2017-04-10 17:33:59

    首先UUID的性能并不比自增ID差很多,这取决于UUID的生成算法。举个例子MongoDB所采用的ObjectId就是一个比较优秀的UUID策略,其组成是时间戳+机器码+进程码+自增数,其中机器码和进程码都可以一次性生成,这样得到一个ObjectId仅仅之比自增ID多了一个时间戳的获取。另外考虑到自增ID都要做主键唯一索引,而UUID可以只做索引,不做唯一索引(利用其特性,可以不考虑唯一性过滤),其性能可以说并不比自增ID差。

    至于使用UUID还是自增ID主要还是看项目是否足够庞大,数据量是否足够多。从使用方便性上来说自增ID使用简单,不需要额外支持,而UUID相对麻烦一些,涉及到UUID算法的选取、程序的嵌入等等。而从应对庞大系统的效果上来说,UUID就比自增ID显得优秀得多。怎么选择就是看自己的实际情况,按需选择。

    reply
    0
  • PHPz

    PHPz2017-04-10 17:33:59

    Oracle环境下(其他数据库没有使用经验):
    长远来说,自增Number的占用空间比UUID(raw(16)占用32字节)更大,但一般表的数据量在数百亿以内时number占用的空间还是更少;
    UUID使用没有number方便,UUID存储为raw(16)时查询条件需要使用HEXTORAW转换;
    相同行数情况下,基于UUID的索引占用空间比number更大,数据量上去了读取磁盘次数肯定就更多了;
    并发或者rac集群环境下,因为热块现象UUID的性能高于number(建立反向索引可解决这个问题);
    UUID使用于前台展示时更安全,Number可以猜测

    reply
    0
  • PHPz

    PHPz2017-04-10 17:33:59

    1. 如果这个 id 会暴露给用户的话(URL的一部分),那么自增ID 更友好。

    2. 性能方面 2 个差距不太大

    3. 开发方便性的话,UUID 比 自增ID 要方便的多

      • UUID 可以解决分布式ID不冲突,数据库自增ID不支持。

      • UUID 可以在提交数据库之前就获取,不需要多一个 select 语句

      • 不是所有数据库都支持自增ID

    4. UUID可以不采用标准的36位长度,可以用base64压缩到12-16位长度。

    5. 优先采用UUID方案,如果需要更友好的 URL,也应该采用 sequence 代替自增ID

    reply
    0
  • 黄舟

    黄舟2017-04-10 17:33:59

    上面大部分答案从开发人员角度比较uuid生成效率,而对数据库的存取效率案例看,用InnoDB或TokuDB的话,答案就是自增主键,看看Oracle ACE的这篇解答:
    为什么InnoDB表要建议用自增列做主键

    reply
    0
  • 巴扎黑

    巴扎黑2017-04-10 17:33:59

    按需所取,具体问题具体分析,简单的说,一般 32字节的UUID 可以通用

    reply
    0
  • 迷茫

    迷茫2017-04-10 17:33:59

    自增在索引上有优势(整型的比较比字符串比较要快),但优势有限。两者的区别最主要在于id是在client端/server端生成。 相对于mysql来说,java程序就是一个client端。uuid可以保证client端生成一个唯一且不重复的id,这在分布式系统中非常重要。

    如果你摸不准的话,我建议你使用uuid.

    reply
    0
  • 黄舟

    黄舟2017-04-10 17:33:59

    这个要看你底层存储的选型,Oracle我不熟,他底层使用rowid来完成,所以不发表评论。其他类似MongoDB等都有自己特殊性,所以用UUID倒反合适。

    但如果你的底层存储用MySQL,而且存储引擎又恰好是Innodb,那我是非常推荐你使用唯一自增的数字来作为你的PK;

    首先不去探讨UUID和long这两个数据在CPU进行计算时分别对应多少个指令和CPU计算周期,最重要的是Innodb的底层存储是B+Tree,需要按照一个聚集索引,所有的数据查询操作都是基于聚集索引来完成(如果表设计了PK,则聚集索引默认选用就是这个PK)

    如果InnoDB表的数据写入顺序能和B+树索引的叶子节点顺序一致的话,这时候存取效率是最高的。

    当然了,如果你的系统不追求性能的极限,那随便玩

    reply
    0
  • 高洛峰

    高洛峰2017-04-10 17:33:59

    为什么不定制自己的主键策略呢?

    reply
    0
  • PHPz

    PHPz2017-04-10 17:33:59

    mysql的使用自增的,不然innodb也要自己维护主键索引的。

    reply
    0
  • 阿神

    阿神2017-04-10 17:33:59

    如果是单机, 推荐使用mysql的自增id.

    如果是分布式环境, 想要保持全局的唯一id, 自增和uuid都不行。
    这个时候就需要自已定制一套id生成机机制了

    reply
    0
  • Cancelreply