2

我们使用 GUID 作为主键(我们知道这不是一个好的选择,但现在不能更改)。众所周知,我们的索引很快就会碎片化。另一个用顺序 ID 替换 GUID 的好选择。为此,代码更改如下:

旧代码:

ObjectName.Id = Guid.NewGuid();

新代码:

ObjectName.Id = Sequential.NewGuid();

这里Sequential是我们的静态类,它使用“rpcrt4.dll”创建 Sequential GUID。但是我们的测试表明,这也不适用于索引,并且它们会变得支离破碎。

另一个有趣的发现是,如果我们将这个顺序 GUID 保存为数据库中的“字符串”,那么我们的索引就不会变得碎片化。

现在我有以下疑问/疑问:

  1. 当我们将相同的字符串保存为“String”和“GUID”时,为什么服务器的行为会有所不同?根据我到目前为止的理解,它在内部将所有内容保存为字符串。

  2. 有什么方法可以配置数据库来说明这一点,将我们的 GUID 视为字符串并平等对待它们?

以下是环境的一些细节:

  • 数据库:SQLExpress
  • 编码语言:C#
  • 不能依赖服务器生成密钥,我们必须从代码本身设置密钥。

即使不是确切的解决方案,也欢迎提供解决方案的指针。

4

2 回答 2

1

guid 不存储为字符串。它存储为 16 个字节的数据 - guid 中的字符是字节的十六进制表示,其中第一对是最低有效值。

当 RPCRT4 生成顺序 GUID 时,它似乎将字节 4 视为最不重要的。这可能是您的索引变得碎片化的原因。

尽管您的说法相反,我还是建议您使用 SQL Server 的 NewSequentialID 函数。

于 2013-10-18T07:48:04.123 回答
0

顺便提一句。- 您是否在大量计算机上生成顺序指南?由于 SQL 服务器主要按特定于源计算机的 guid 部分进行排序(详细回答这个问题 - 这可能对您有一些有价值的信息:Sequential GUIDs)。在这种情况下,您可能会通过将 Guid 转换为字节数组、交换其部分然后重新创建 Guid 来获得一些结果。

这种方法的另一种变体可能是将 guid 的机器识别部分替换为始终相同的静态值,并使用 Guid 的不同部分(但不是时间戳特定部分!)来区分机器 - 但这只有在你有非常需要生成 guid 的少量机器。

于 2013-10-23T07:28:55.967 回答