是否有用于生成分布式密钥的 GUID 替代方法

本文关键字:GUID 方法 密钥 分布式 用于 是否 | 更新日期: 2023-09-27 18:35:36

我的情况是:

  1. 我有许多客户端应用程序,它们使用本地数据库(MS SQL,MS Access - 对不起,这是企业系统,我必须支持旧版......
  2. 我不知道客户之间的任何趋势 - 现在是~10,但可能会一年~100。
  3. 这些表中的数据来到我的中央服务器,并放入一个公共表中
  4. 有时现有(客户端)数据被更改 - 我必须执行更新/删除操作
  5. 我不想使用GUID(.NET类型System.Guid) - 很难简单地在MS Access上实现和支持。此外,这对性能不利
  6. 我需要快速搜索该公用表,因此最好使用 intlong int作为 PK

所以,我想要:

  1. 避免碰撞的独特东西(它将用作PK)
  2. 希望它应该是intlong int
  3. 在插入之前必须是可分配的客户端

我目前的解决方案是从以下项的串联中获取CRC:

  • 进程标识
  • 简历日期
  • 用户名(字符串、硬件''用户相关数据)
  • DateTime.Now (UNC)

目前它对我有用,但也许有更好的方法来实现我的目标?您自己有什么意见、建议、例子或经验吗?

更新:客户端和服务器之间的同步是定期操作,因此每天可以发生 2-3 次(它是配置变量)

是否有用于生成分布式密钥的 GUID 替代方法

如果来自多个表的数据来到一个中央表,并且您需要解决对这些记录的更改,那么我的建议是使用两列作为中央表的PK。一列可以是客户端的"标识"字段(非唯一),一列可以是分配给客户端应用的客户端代码(非唯一)。来自 ID 和客户端代码的聚合将是您的 PK

此解决方案的优点是不需要对客户端应用程序进行任何更改(也许可以将一些身份代码发送到您的中央服务器,您可以在其中用于某些安全措施)当然,如果客户群增长(希望如此),您需要为每个客户端保留一个集中的代码表。在中央表上进行搜索应该不是问题,因为您使用的是两个数字(或标识代码的短字符串)。

您始终可以只添加一个数字的 PK 列,并(取决于您使用的数据库)设置一个序列或标识来处理它。

您还可以在当前必须的多个列上创建索引,以帮助加快搜索速度。

您可以实现一个键表。

基本上,键表只是一个包含一条记录的表:下一个可用的整数键。当程序需要生成密钥时,它会递增密钥表中的密钥。它现在已保留以前可用的密钥。它可以将该密钥分配给它喜欢的任何内容,并且可以确保它不会与以相同方式提取的任何其他密钥发生冲突。这就是 光速 ORM 默认情况下的工作方式。与使用内置标识列相比,它的好处是您可以在将项 ID 插入数据库之前分配项 ID,从而可以在一次插入所有项之前定义项关系。

如果您担心冲突,可以在读取和递增下一个可用密钥之前锁定/解锁密钥表。如果您知道需要一次插入多个项目,则可以将键递增该键,而不是多次递增一个。如果您猜测在应用程序将来的某个时候需要一定数量的密钥,则可以保留一个顺序密钥块,并在内部跟踪它们。如果不分配所有密钥,这可能会浪费密钥,但可以防止对数据库的过度调用。

只需使用 int64 键,在客户端使用远离 0 的负递增数字(从 -1 开始),然后在同步后的服务器端使用正递增数字,当您将数据从客户端同步到服务器时,您只需返回新的正服务器端数字。我相信更新记录上的键非常简单,如果没有,只需删除旧的并插入带有值的新键即可。

这是一种非常简单的方法,可以拥有客户端唯一键和可更新数据,而无需真正担心由您的解决方案引起的问题,这些问题充其量只是随机冲突,具体取决于您的 crc 检查的大小。

如果您坚决反对使用 GUID(MSDN for System.Guid.NewGuid() 表示 MAC 地址作为值的一部分并使它们高度唯一),那么您的答案要么是复合键(而不是基于复合键的 crc!请不要错误地认为您的 CRC 解决方案比 GUID 发生冲突的可能性更小,除非您的熵比 128 位 GUID 多,您只会为自己做更多的工作。

正如我所指出的,int64 空间的整个负谱可以用来识别不同步的,因此是临时的唯一 ID 号。然后,您甚至可以在写入中央服务器时获得聚集索引的额外潜在好处。

因此,假设您的客户端数据密钥如下所示:

-5, -4, 76, 78, 79

这意味着需要将 -4 和 -5 插入到中心位置,然后将其 ID 更新为新值(在本例中可能是 8081)。

如果您想进一步了解 GUID 的独特性和发生碰撞的可能性,我建议您阅读 Eric Lippert 最近关于该主题的博客文章。至于访问方,您可以.ToString() 并将它们转换为文本键。但是由于我提供了一个适用于int/int64空间的解决方案,因此不需要。