0

(不是Char(4) 作为主键或其他任何内容的副本。)

我正在为我的项目设计 SQL Server 表。到目前为止,我有两张桌子:DataRef.

Data结构体:

DataID    SomeData      SomeOtherData          RefID

Ref结构体:

RefID     UniqueData    AlmostNeverUsedData

UniqueData 包含唯一char(32)值,并且涉及Data. 大约 5% 的查询需要AlmostNeverUsedData。

我知道使用非数据、自动递增int字段作为主键几乎总是更好,尤其是在JOIN性能方面。但在这种情况下,使用 UniqueData 作为Ref主键可以让我避免使用JOIN95% 的时间,因为我需要的所有数据都已经在Data.

剩下的 5% 是否证明使用自动递增是合理的int,从而增加查询(以及因此应用程序逻辑)的复杂性?

4

1 回答 1

3

测试两种结构。这并不难。

将 Ref.UniqueData 声明为primary key nonclustered,并将其外键引用设置为on update cascade。用几百万行数据加载它,并测量性能。(加载它的数据比您预计五年后的数据还要多。)

从关系的角度来看,拥有一个 32 字节长的主键并没有错。从关系的角度来看,更新主键值并没有错。在关系模型中,所有值都是可更新的,并且“补偿引用操作”(级联更新和删除)也是模型的一部分。

从 SQL 的角度来看,拥有 32 字节长的主键并没有错。SQL 还允许更新键值,并且 SQL 支持级联更新和删除。

从 SQL Server 的角度来看,拥有一个 32 字节长的主键没有任何问题。SQL Server 支持更新键值,SQL Server 支持级联更新和删除。只是不要让它成为一个聚集的主键。

当我在上一份工作中设计生产数据库时,我构建了两个数据库——一个围绕代理键设计,一个围绕自然键设计。我写了两组我希望经常使用的查询。它们包括一些选择、插入、更新和删除语句。有很多这样的。两组在功能上是相同的。(我想我最初使用的是 PostgreSQL 8.4。PostgreSQL 没有实现集群键。)

我对每个数据库运行了测试查询。如果有记忆,大约 80% 的查询使用自然键更快。在某些情况下,单个 SELECT 语句的速度要快 35 到 40 倍。当使用自然键的查询速度较慢时,它们不会慢很多,并且对于用户来说仍然足够快。(我已经在 SO 和 DBA.stackexchange.com 上多次写过这些测试。)

我发现了一个临界点,代理键的性能开始超过自然键的性能。但据我估计,我们在 30 年内都不会达到那个临界点。并且有大量的调整选项和硬件改进使得我们不太可能需要使用代理键,即使 PostgreSQL 开发完全停止。

于 2013-06-05T10:50:06.693 回答