2008-09-02 61 views
5

我们正在设计一个典型为OLTP的应用程序(请考虑购买系统)。但是,这个特别需要一些用户脱机,因此他们需要能够将数据库下载到他们的机器上,然后在局域网上进行同步。作为主键的GUID - 离线OLTP

我想说明的是,我知道这已经完成,我只是没有这种特定模型的经验。

我想过的一个想法是使用GUID作为表键。因此,例如,采购订单不会有一个数字(自动数字),而是一个GUID,以便每个离线客户端都可以生成这些数据,并且当我连接回数据库时没有冲突。

由于某种原因,这是一个坏主意吗? 通过GUID键访问这些表会慢吗?

您是否有过使用这类系统的经验?你怎么解决这个问题?

谢谢!
Daniel

回答

8

将Guid用作主键是可以接受的,并且出于与您考虑相同的原因而被认为是相当标准的做法他们。它们可能会被过度使用,从而使调试和管理变得乏味,因此尽可能地尽量避免使用代码表和其他参考数据。

你必须关心的是人类可读的标识符。 Guids不能被人交换 - 你能想象如果它是一个guid,试图通过电话确认你的订单号吗?因此,在离线情况下,您可能仍需要生成,这与发布商(工作站/用户)ID和某个序列号相似,因此订单号可能为123-5678。

但是,这可能无法满足具有序号的业务要求。实际上监管要求可能是和影响 - 一些规定(SOX也许)要求发票号码是连续的。在这种情况下,可能需要生成一种形式编号,稍后在系统同步时进行修正。你可能会遇到有OrderId(Guid),OrderNo(int),ProformaOrderNo(varchar)的表 - 一些复杂性可能会蔓延进来。

至少有guid作为主键意味着你不必做一个整体当同步最终发生时,很多级联更新 - 您只需更新人类可读的编号。

+0

我会添加一件事:基础64编码您的GUID照顾大部分的可读性问题。 – NotMe 2008-12-12 00:18:21

0

Guid肯定会比标准整数键慢(但使用更多内存),但是否这是一个问题将取决于您的系统将看到的负载类型。根据您的后端数据库,索引guid字段可能存在问题。

使用GUID简化了一整类问题,但您付出的一部分将会提高性能和可调试性 - 在这些测试查询中键入GUID将会变得非常快速!

1

这是一个非常好用的GUID。唯一的缺点是在处理INT上的GUID时稍微复杂一点,并且尺寸差别很小(16字节vs 4字节)。

我不认为这些都是大问题。

0

后端将是SQL Server 2005中
前端/应用逻辑将.NET

另外的GUID,你可以想其他办法来解决“合并”当这种情况发生的脱机计算机同步的新数据回到中央数据库?
我的意思是,如果键是INT,我将不得不在重新编号时重新编号。 GUID会免除我的这一点。

0

当我们必须将两个数据库合并为一个时,使用GUID节省了大量工作。

0

如果您的数据库足够小,可以下载到笔记本电脑并脱机使用,那么您可能不必过多担心ints和guids之间的性能差异。但是,不要低估在开发和排除系统故障时整数的有用性!无论您是否使用Guids,您可能都需要提出一些相当复杂的导入/同步逻辑,因此它们可能没有您想象的那么大。

1

通过 来访问这些表的GUID键会慢吗?

还有其他问题的GUID,你看到GUID是不连续的,所以刀片将分散各地的地方,这会导致页面拆分和索引碎片

在SQL Server 2005 MS推出NEWSEQUENTIALID()要解决这个问题,唯一的问题可能是您只能在表中使用NEWSEQUENTIALID作为默认值

+0

你和波特曼有效点。 GUIDS是一把非常尖锐的两刃剑。 – Namphibian 2013-01-03 08:00:44

0

@Simon,

你提出了很好的观点。我已经在考虑离线时会产生的“临时”“人类可读”数字,我会重新进行同步。但我想避免与外键等

0

我会开始看这SQL Server精简版!它有助于解决所有问题。

Data Storage Architecture with SQL Server 2005 Compact Edition

它专为

场力的应用程序(游离脂肪酸)而设计的。游离脂肪酸 通常共享一个或多个 以下属性

它们允许用户从 履行 工作职能,同时断开的后端网络现场在 客户端位置,在路上,在一个 机场,或从家里。

FFA通常是专为 偶尔连接,这意味着 当用户运行的客户端应用程序 ,他们并不需要有 任何类型的网络连接。 FFAs 通常涉及多个客户端,这些客户端可以同时访问和使用来自后端数据库的数据 ,两者都处于连接和断开连接模式。

FFA必须能够将数据从后端数据库 复制到 客户端数据库用于脱机支持。 他们还需要能够复制 修改,添加,或从客户机到服务器 删除的数据 记录的应用程序能够 当连接到网络

0

想到的首先想到的: MS没有设计DataSet和DataAdapter模型来支持这种情况吗?

我相信我读到MS将他们的ADO记录集模型更改为当前的DataSet模型,因此它也可以很好地离线工作。也有这Sync Services for ADO.NET

我相信我已经看到利用DataSet模型,也使用外键的代码,他们仍然完美同步使用DataAdapter时。虽然没有尝试同步服务,但我认为你也可以从中受益。

希望这会有所帮助。

3

@SqlMenace

还有其他问题的GUID,你看到GUID是不连续的,所以刀片将分散各地的地方,这会导致页面拆分和索引碎片

不正确。主键!=聚簇索引。

如果聚簇索引是另一列(“插入_”出现在脑海中),那么插入将是连续的,并且不会发生页面拆分或过度分段。

1

你是正确的,这是一个老问题,它有两个典型的解决方案:

  • 使用唯一标识符作为主键。请注意,如果您担心可读性,则可以使用自己的唯一标识符来代替使用GUID。唯一标识符将使用有关日期和机器的信息来生成唯一值。

  • 使用'Actor'+标识符组合键。每个用户都获得一个数字参与者ID,新插入的行的键使用参与者ID以及下一个可用标识符。所以如果两个参与者都插入一个ID为“100”的新行,主键约束不会被违反。

就个人而言,我更喜欢第一种方法,因为我认为复合键作为外键非常繁琐。我认为人的可读性投诉被夸大了 - 反正最终用户不需要知道任何关于你的密钥的信息!

0

@Portman默认情况下,PK == Clustered Index,创建一个主键约束将自动创建一个聚簇索引,如果你不想聚簇索引,你需要指定非聚簇索引。

1

确保使用guid.comb - 照顾索引的东西。如果您在此之后处理性能问题,那么您将在短期内成为缩放专家。

另一个原因是使用的GUID是使数据库重构。假设您决定将多态性或继承或其他用途应用于您的客户实体。您现在希望客户和员工从Person派生并让他们共享一个表。拥有真正独特的标识符使数据迁移变得简单没有序列或整数身份字段与之战斗。