GUID 作为主键 - 离线 OLTP
我们正在致力于设计一个典型的 OLTP 应用程序(想想:采购系统)。 然而,这个特别需要一些用户处于离线状态,因此他们需要能够将数据库下载到他们的计算机上,对其进行处理,然后在连接到 LAN 后同步回来。
我想指出的是,我知道以前已经这样做过,我只是没有使用这个特定模型的经验。
我想到的一个想法是使用 GUID 作为表键。 例如,采购订单不会有数字(自动数字),而是有 GUID,这样每个离线客户端都可以生成这些数字,并且当我连接回数据库时不会发生冲突。
出于某种原因,这是一个坏主意吗? 通过GUID键访问这些表会不会很慢?
您有使用此类系统的经验吗? 你是如何解决这个问题的?
谢谢!
丹尼尔
We are working on designing an application that is typically OLTP (think: purchasing system). However, this one in particular has the need that some users will be offline, so they need to be able to download the DB to their machine, work on it, and then sync back once they're on the LAN.
I would like to note that I know this has been done before, I just don't have experience with this particular model.
One idea I thought about was using GUIDs as table keys. So for example, a Purchase Order would not have a number (auto-numeric) but a GUID instead, so that every offline client can generate those, and I don't have clashes when I connect back to the DB.
Is this a bad idea for some reason?
Will access to these tables through the GUID key be slow?
Have you had experience with these type of systems? How have you solved this problem?
Thanks!
Daniel
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

发布评论
评论(15)
我首先想到的是:MS不是设计了DataSet和DataAdapter模型来支持这样的场景吗?
我相信我读到 MS 将其 ADO 记录集模型更改为当前的 DataSet 模型,因此它在离线状态下也能很好地工作。 还有这个 ADO.NET 同步服务
我相信我有看到了利用 DataSet 模型的代码,该模型也使用外键,并且在使用 DataAdapter 时它们仍然完美同步。 虽然还没有尝试过同步服务,但我认为您也可以从中受益。
希望这可以帮助。
使用 Guid 作为主键是可以接受的,并且被认为是相当标准的做法,原因与您考虑使用它们的原因相同。 它们可能会被过度使用,这会使调试和管理变得有点乏味,因此如果可能的话,请尽量将它们排除在代码表和其他参考数据之外。
您必须关心的是人类可读的标识符。 人们无法交换指南 - 如果是指南,您能想象尝试通过电话确认您的订单号吗? 因此,在离线场景中,您可能仍然需要生成某些内容 - 例如发布者(工作站/用户)ID 和一些序列号,因此订单号可能是 123-5678 -。
然而,这可能无法满足具有序列号的业务需求。 事实上,监管要求可能会产生影响——一些法规(可能是 SOX)要求发票号码是连续的。 在这种情况下,可能需要生成一种形式编号,该形式编号稍后在系统同步时修复。 您可能会得到包含 OrderId (Guid)、OrderNo (int)、ProformaOrderNo (varchar) 的表 - 可能会出现一些复杂性。
至少将 guid 作为主键意味着您不必执行大量级联更新当同步最终发生时 - 您只需更新人类可读的数字即可。
我只是要向您指出Sequential Guid 相对于标准 Guid 的性能改进是什么?,其中涵盖了 GUID 讨论。
为了便于人类阅读,请考虑分配机器 ID,然后可以使用这些机器的序列号。 不过,这将需要管理机器 ID 的分配。 可以在一列或两列中完成。
不过,我个人很喜欢 SGUID 的答案。
为此我将开始考虑 SQL Server Compact Edition! 它有助于解决您的所有问题。
SQL Server 2005 Compact Edition 的数据存储架构
它专门设计用于
现场部队应用程序 (FFA)。 游离脂肪酸
通常共享一个或多个
以下属性它们允许用户执行他们的操作
断开连接时的工作职能
后端网络——现场
客户位置、在路上、在
机场,或从家里。FFA 通常设计用于
偶尔连接,这意味着
当用户运行客户端时
应用程序,他们不需要
任何类型的网络连接。 游离脂肪酸
经常涉及多个客户
可以同时访问和使用数据
来自后端数据库,都在
连接和断开模式。FFA 必须能够复制数据
从后台数据库到
用于离线支持的客户端数据库。
他们还需要能够复制
修改、添加或删除数据
客户端到服务器的记录
当应用程序能够
连接到网络
您是对的,这是一个老问题,并且它有两个规范的解决方案:
使用唯一标识符作为主键。 请注意,如果您担心可读性,您可以滚动自己的唯一标识符,而不是使用 GUID。 唯一标识符将使用有关日期和机器的信息来生成唯一值。
使用“Actor”+标识符的复合键。 每个用户都会获得一个数字参与者 ID,新插入行的键使用参与者 ID 以及下一个可用标识符。 因此,如果两个参与者都插入 ID 为“100”的新行,则不会违反主键约束。
就我个人而言,我更喜欢第一种方法,因为我认为复合键作为外键确实很乏味。 我认为对人类可读性的抱怨被夸大了——无论如何,最终用户不应该知道关于你的密钥的任何信息!
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
如果您的数据库足够小,可以下载到笔记本电脑并离线使用它,那么您可能不需要太担心 int 和 Guid 之间的性能差异。 但不要低估整数在系统开发和故障排除时的用处! 无论您是否使用 Guid,您可能都需要提出一些相当复杂的导入/同步逻辑,因此它们可能没有您想象的那么有帮助。
If your database is small enough to download to a laptop and work with it offline, you probably don't need to worry too much about the performance differences between ints and Guids. But do not underestimate how useful ints are when developing and troubleshooting a system! You will probably need to come up with some fairly complex import/synch logic regardless of whether or not you are using Guids, so they might not help as much as you think.