(不是Char(4) as Primary key或任何副本。)
我正在为我的项目设计SQL Server表。到目前为止,我有两张表:Data
和Ref
。
Data
结构:
DataID SomeData SomeOtherData RefID
Ref
结构:
RefID UniqueData AlmostNeverUsedData
UniqueData包含唯一的char(32)
值,并且涉及Data
上的每个查询。
<5%的查询需要AlmostNeverUsedData。
我知道使用非数据,自动递增int
字段,因为主键几乎总是更好,尤其是关于JOIN
表现。但是在这个的情况下,使用UniqueData作为Ref
的主键,我可以避免使用JOIN
95%的时间,因为我需要的所有数据都已经在Data
上。
剩余的5%是否使用自动递增int
来证明,增加了查询(以及应用程序逻辑的复杂性)?
答案 0 :(得分:3)
测试两种结构。这并不难。
将Ref.UniqueData声明为primary key nonclustered
,并将其外键引用设置为on update cascade
。加载数百万行数据,并衡量性能。 (加载的数据超过了你预测的五年内的数据。)
从关系的角度来看,拥有32字节长的主键没有错。从关系的角度来看,更新主键值没有任何问题。在关系模型中,所有值都是可更新的,“补偿引用操作”(级联更新和删除)也是模型的一部分。
从SQL的角度来看,拥有32字节长的主键没有任何问题。 SQL还允许更新键值,SQL支持级联更新和删除。
从SQL Server的角度来看,使用32字节长的主键没有任何问题。 SQL Server支持更新键值,SQL Server支持级联更新和删除。只是不要使它成为集群主键。
当我在之前的工作中设计生产数据库时,我构建了两个数据库 - 一个围绕代理键设计,另一个围绕自然键设计。我写了两组我希望经常使用的查询。它们包括一些select,insert,update和delete语句。这些中有很多。这两套在功能上是相同的。 (我想我最初使用的是PostgreSQL 8.4.PostgreSQL没有实现集群密钥。)
我针对每个数据库运行了测试查询。如果内存服务,大约80%的查询使用自然键更快。在某些情况下,单个SELECT语句的速度提高了35到40倍。当使用自然键的查询速度较慢时,它们的速度并不是很慢,而且它们对于用户来说仍然足够快。 (我在SO和DBA.stackexchange.com上多次写过这些测试。)
我发现了一个引爆点,代理键的性能开始超过自然键的性能。但根据我的估计,我们不会达到30年的转折点。并且有大量的调优选项和硬件改进使得我们永远不太可能需要使用代理键,即使PostgreSQL开发完全停止。