我想建立一个分布式系统。我需要将数据存储在数据库中,使用UUID或GUID作为某些表上的主键会很有帮助。由于UUID / GUID很大,而且几乎是随机的,因此我认为这种设计有缺点。另一种选择是使用自动递增的INT或LONG。

使用UUID或GUID作为表的主键有什么缺点?

我可能会使用Derby / JavaDB(在客户端上)和PostgreSQL(在服务器上)作为DBMS。

评论

为什么会有帮助?您最关注的缺点是什么?对于每个含糊不清的数据库问题,答案都是“取决于”。您能给我们更多细节吗?您对读取或写入性能最感兴趣吗?我们在谈论什么级别的分配?

@Brian:分布式系统中的UUID很有帮助,因为您可以在客户端上创建主键,然后将数据异步上传到服务器。我主要是在考虑读取性能的缺点。在UUID上使用许多JOIN可能不是很好吗?在示例中,客户将一个项目(UUID,名称,供应商,创建者)添加到库存系统,然后本地数据库与服务器上的中央数据库同步。

我认为,对此没有更多澄清的意见,最多只能是“取决于”。没有这些,我将去VtC。

有一篇文章讨论了GUID与非GUID对SQL Server中的聚集索引的影响,即使与另一种SQL产品相关,您也可能会发现它很有趣:x.co/Twpp

我注意到Derby doc并未将UUID列为数据类型。您可能需要考虑使用诸如H2数据库引擎(像Derby这样的纯Java数据库)之类的替代方案,它确实列出了UUID数据类型。当然,Postgres确实对有效存储,建立索引和生成UUID值提供了出色的支持。

#1 楼

这取决于您的生成函数和最终表的大小

GUID旨在成为全局唯一标识符。正如Postgres 8.3文档中所讨论的,没有普遍适用于生成这些标识符的方法,但是postgreSQL确实附带了一些更有用的候选方法。

从问题的范围以及对脱机写入,除了GUID之外,您已经整齐地使用了其他任何内容,因此其他方案没有补偿优势。

从功能的角度来看,密钥长度通常不是问题在任何现代系统上,取决于读取次数和表的大小。作为一种替代方法,脱机客户端可以在没有主键的情况下批处理新记录,并在重新连接时仅插入它们。由于postgreSQL提供了“ Serial”数据类型,因此如果客户端可以执行对数据库的简单写入,则它们将永远不需要确定ID。

评论


该死的你睡了,你走了,让Brian回答问题。是的,对“离线更新”的要求完全改变了整个概念。

– jcolebrand♦
2011年1月6日12:34

啊哈哈哈哈! ::邪恶地旋转胡子::

–布赖恩·鲍尔森-斯坦顿(Brian Ballsun-Stanton)
2011年1月6日,12:47

即使使用脱机写入,也可以使用INT。例如。使用两列{Node_ID,Item_ID},其中每个节点都有一个Node_ID,并且每个节点都有一个自动递增的Item_ID。

–乔纳斯(Jonas)
2011年1月6日15:16

@Jonas〜是的,这是可行的。但是,大多数人甚至考虑使用GUID的原因之一是将内容全局复制到其他数据库。我的意思是这个词本身在那儿是QED。

– jcolebrand♦
2011年1月7日,0:17

对于主/从体系结构或稀疏连接客户端+主服务器体系结构,在主服务器上使用global_id(SERIAL),在从服务器上使用global_id(BIGINT)+ local_id(SERIAL)是否可行。从站使用local_id进行本地工作,并在可以向主站发送时提交,主站接收数据并将其授予global_id,并返回给从站,从站更新global_id字段(供与服务器或其他服务器通信时参考)奴隶)。

– Mihai Stancu
2012年5月20日在21:55

#2 楼

还有一个建议-切勿将GUID用作聚集索引的一部分。
GUID不是顺序的,因此,如果它们是聚集索引的一部分,则每次插入新记录时,数据库都需要重新排列其所有内存页以查找正确的插入位置,以防int(bigint)自动递增,它将只是最后一页。

现在,如果我们看一下一些数据库实现:
1。)MySQL-primary键是群集的,没有任何选择可以改变行为-建议此处完全不使用GUID
2。)Postgres,MS-SQL-您可以取消将GUID用作主键,而将另一个字段用作群集索引,例如autoincrement int。

评论


您为Postgres提出的建议也可以在MySQL中完成,其结构略有不同-auto_increment PK(集群键),具有唯一索引的GUID(集群)。

–超立方体ᵀᴹ
2012年4月29日23:34



并非总是如此。根据磁盘系统的吞吐量,同步访问最后一页可能是您的瓶颈。 blog.kejser.org/2011/10/05/…

– mwilson
2013年1月7日在6:14

“与Microsoft SQL Server不同,在PostgreSQL中的索引上群集不会维护该顺序。您必须重新应用CLUSTER进程才能维护该顺序。” CLUSTER ON如何改善索引性能

–巴托洛-奥特里
15年6月16日在10:06

@ bartolo-otrit信息的更精简版本链接到:stackoverflow.com/a/4796685/1394393。这个答案对我来说似乎并不重要,因为这个问题与PG有关,并且似乎假定与SQL Server和MySQL不存在相似之处。

– jpmc26
2015年10月29日在18:11



数据库将需要重新排列其所有内存页以找到正确的插入位置=>我认为Postgres并不是这种情况,因为集群是可选的,新行的存储是无序的。

–调味
16 Mar 17 '16 at 12:33

#3 楼

这要视情况而定。

认真地讲,到目前为止,您已经拥有了尽可能多的内容。

为什么使用UUID会有帮助?为什么不使用INT?您为什么以后不能仅在UUID上建立索引?您是否了解使用UUID键排序列表并在几百万行之后插入随机(非顺序)UUID是什么意思?

它将在什么平台上运行?多少个磁盘?有多少用户?多少条记录?

评论


如我在评论中所写,如果我使用UUID,则客户端可以在不连接服务器的情况下向数据库添加行,然后与服务器同步。如果我将INT用作主键,则无法做到这一点,因为多个客户端可能会将同一主键用于不同的项目。好吧,在UUID列上对列表进行排序是没有用的,在timestamp列上对列表进行排序会更有用。不,我不知道在几百万行之后插入随机的非顺序UUID是什么意思,这就是为什么我问这个问题。

–乔纳斯(Jonas)
2011年1月6日10:10



该应用程序将使用Java编写,而客户端则使用Windows,Mac或Linux。客户端将使用通常具有一个磁盘的普通台式计算机。用户数和记录数取决于我获得的客户数量,但每个客户和客户大约为5000。

–乔纳斯(Jonas)
2011年1月6日上午10:13

离线评论改变了一切。看到更多细节了吗?

– jcolebrand♦
2011年1月6日,12:35