Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/69.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Mysql 在使用UUID时,我是否也应该使用自动增量?_Mysql_Sql_Sqlite_Auto Increment_Uuid - Fatal编程技术网

Mysql 在使用UUID时,我是否也应该使用自动增量?

Mysql 在使用UUID时,我是否也应该使用自动增量?,mysql,sql,sqlite,auto-increment,uuid,Mysql,Sql,Sqlite,Auto Increment,Uuid,我们正在构建一个新的网络应用程序,该应用程序将在许多本地设备上具有离线的iPad/Android应用程序版本,这些设备将涉及新数据的插入。因此,我们需要使用UUID来允许与主数据库进行必要的双向同步。为此,我们将UUID存储为二进制(16)主键 我在研究后了解到的问题是,非顺序主键插入所需的时间将随着时间的推移而增加,这些插入将导致碎片(如所回答的)。AUTO_INCREMENT的好处是新行通常只会添加到表的末尾,因此不会遇到UUID的速度问题 我的问题是,使用AUTO_INCREMENT列作为

我们正在构建一个新的网络应用程序,该应用程序将在许多本地设备上具有离线的iPad/Android应用程序版本,这些设备将涉及新数据的插入。因此,我们需要使用UUID来允许与主数据库进行必要的双向同步。为此,我们将UUID存储为
二进制(16)
主键

我在研究后了解到的问题是,非顺序主键插入所需的时间将随着时间的推移而增加,这些插入将导致碎片(如所回答的)。
AUTO_INCREMENT
的好处是新行通常只会添加到表的末尾,因此不会遇到UUID的速度问题

我的问题是,使用
AUTO_INCREMENT
列作为主键,然后将UUID列作为非空唯一索引是否更好?这可能具有顺序插入的速度优势,同时保留同步分布式数据库所需的UUID

我可以看到的一个问题是,UUID需要用作其他表的参考(使用外键约束)(即附加到检查的问题列表,该列表又附加到站点,所有问题都涉及到插入,因此所有问题都需要UUID)。从语义上讲,主键作为引用更有意义,但作为一个分布式系统,我们不能使用
AUTO_INCREMENTS
。对于这些引用(当然还有随附的
JOIN
s),使用(非空)唯一索引而不是主键是否有缺点

还值得注意的是,主(在线)数据库使用MySQL(InnoDB),分布式(离线)数据库使用SQLite

编辑:


考虑到将UUID作为主键可能更好(从语义上讲,它就是主键),如果我将UUID设置为主键,并将
AUTO_INCREMENT
列设置为非空的唯一索引,我会获得顺序插入的好处吗?或者,在确定插入新行的位置时,只有主键才是相关的吗?

使用autoincrements作为主键加上uuid列是一种有效的模式,但您仍然需要解决autoincrements带来的一些问题,这完全取决于您如何进行同步

不管怎么说,我一直在使用uuid作为主键(我当前的数据库有50万条记录),它仍然非常快,只是插入的速度慢了一点,但是除非你每天都有大量的插入,否则它不会吓到你


如果您使用Sql Server,另一种解决方案是顺序UUID,它的冲突几率比普通UUID稍大,但绝对冲突几率仍然很低,因为它们是部分顺序的,可以解决碎片问题。

您可以使用复合主键,由脱机客户端分配的自动递增的bigint ID值加上分配给客户端的bigint ID组成。所以在客户机1235上输入15


客户机最好在进行第一次编辑之前从服务器请求其ID,例如,当它第一次检索服务器的主数据时。

一旦您拥有一个大型分布式数据仓库,如果您使用UUID或GUID作为唯一密钥,并在以后的联接中使用它,这是不好的

请在主数据库或数据管道中创建顺序代理密钥,而不是使用UUID或GUID

分享我们的项目经验作为参考。我们在并行数据仓库中保存了3000亿条记录,在我们的系统中,甚至不支持自动增量密钥。我们使用8字节的bigint作为主键(实际上我们的系统中也不支持唯一键,但这并不影响逻辑唯一性),当我们处理文件和加载文件时,我们使用3字节生成文件ID,即2^24个文件,我们每天需要加载约2000个文件,因此,如果没有错误,2^24可以支持大约25年

我们使用剩余的4个字节作为行id,即40亿行,我们在任何文件中都没有40亿行。我们保留1字节。在ETL处理过程中,我们只需要跟踪主数据库中的文件ID,主数据库支持自动增量ID,当我们在处理文件时需要生成记录ID时,我们结合FileID+reserve 1 byte+4 bytes rowID

来自

UUID

专业人士

  • 全球独一无二
  • 无状态,可以动态生成
  • 安全,因为恶意用户无法猜测ID
  • 版本1 UUID存储时间戳信息,有时可能很有用
缺点

  • 不可读
  • 对于MySQL、Oracle等使用集群主键的数据库,如果将版本4随机生成的UUID用作主键,则会影响插入性能。这是因为它需要对行重新排序,以便将新插入的行放置在聚集索引中的正确位置。另一方面,PostgreSQL使用堆而不是集群主键,因此使用UUID作为主键不会影响PostgreSQL的插入性能
自动递增整数/序列

专业人士

  • 可读的。如果我们将其暴露在外部,这是特别有价值的。考虑到问题id,显然,问题123比问题b1e92c3b-a44a-4856-9fe3-925444ac4c23更具可读性
缺点

  • 它不能在分布式系统中使用,因为不同的主机很可能产生完全相同的数量
  • 它不能动态生成。相反,我们必须查阅数据库,找出下一个可用的PK
  • 某些业务数据可能会被公开,因为最新的ID可能会