10

我的情况是:

  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:

  • 进程ID
  • 简历日期
  • 用户名(字符串、硬件\用户相关数据)
  • 日期时间.Now (UNC)

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

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

4

4 回答 4

2

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

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

于 2012-05-29T21:14:58.100 回答
1

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

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

于 2012-05-29T20:28:44.037 回答
1

您可以实现一个键表

基本上,键表只是一个有一条记录的表:下一个可用的整数键。当您的程序需要生成密钥时,它会递增密钥表中的密钥。它现在保留了以前可用的密钥。它可以将该密钥分配给它喜欢的任何东西,并确保它不会与以相同方式拉出的任何其他密钥冲突。这就是LightSpeed ORM默认的工作方式。与使用内置标识列相比,它的好处是您可以在将项目 ID 插入数据库之前分配它们,因此可以在一次插入所有项目之前定义项目关系。

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

于 2012-05-29T20:40:05.977 回答
1

只需使用 int64 键,在客户端使用从 0 开始的负递增数字(从 -1 开始),然后在同步后在服务器端使用正递增数字,当您将数据从客户端同步到服务器时,您只需返回新的正服务器端号码。我相信更新记录上的键很简单,如果不是那么只需删除旧的并插入一个带有值的新键。

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

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

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

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

-5, -4, 76, 78, 79

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

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

于 2012-05-29T21:07:34.253 回答