我了解代理/人工密钥的一个好处 - 它们不会改变,而且非常方便。无论它们是单场还是多场,都是如此——只要它们是“人造的”。
但是,有时将自动递增的整数字段作为每个表的主键似乎是一个策略问题。拥有这样一个单字段键是否总是最好的主意,为什么(或为什么不)?
需要明确的是,这个问题不是关于人工 vs 自然的——而是关于是否所有人工键都应该是单字段的
我是代理键的粉丝。我的发现存在确认偏倚的风险。
我在这里和http://stackoverflow.com 上看到的许多问题都使用自然键而不是基于IDENTITY()
值的代理键。
我的计算机系统背景告诉我,对整数执行任何比较运算都比比较字符串快。
这个评论让我怀疑我的信念,所以我想我会创建一个系统来研究我的论点,即整数比字符串更快,用作 SQL Server 中的键。
由于小数据集可能几乎没有可辨别的差异,我立即想到了一个两表设置,其中主表有 1,000,000 行,而辅助表在主表中的每一行有 10 行,总共有 10,000,000 行。次要表。我的测试的前提是创建两组这样的表,一组使用自然键,一组使用整数键,并在简单的查询上运行计时测试,例如:
SELECT *
FROM Table1
INNER JOIN Table2 ON Table1.Key = Table2.Key;
Run Code Online (Sandbox Code Playgroud)
以下是我作为测试台创建的代码:
USE Master;
IF (SELECT COUNT(database_id) FROM sys.databases d WHERE d.name = 'NaturalKeyTest') = 1
BEGIN
ALTER DATABASE NaturalKeyTest SET SINGLE_USER WITH ROLLBACK IMMEDIATE;
DROP DATABASE NaturalKeyTest;
END
GO
CREATE DATABASE NaturalKeyTest
ON (NAME = 'NaturalKeyTest', FILENAME =
'C:\SQLServer\Data\NaturalKeyTest.mdf', SIZE=8GB, FILEGROWTH=1GB)
LOG ON (NAME='NaturalKeyTestLog', FILENAME =
'C:\SQLServer\Logs\NaturalKeyTest.mdf', SIZE=256MB, FILEGROWTH=128MB); …
Run Code Online (Sandbox Code Playgroud) performance sql-server sql-server-2012 surrogate-key natural-key performance-testing
我从这里复制了这段代码:
CREATE TABLE records(
email TEXT REFERENCES users(email),
lat DECIMAL,
lon DECIMAL,
depth TEXT,
upload_date TIMESTAMP,
comment TEXT,
PRIMARY KEY (upload_date,email)
);
CREATE TABLE samples(
date_taken TIMESTAMP,
temp DECIMAL,
intensity DECIMAL,
upload_date TIMESTAMP,
email TEXT,
PRIMARY KEY(date_taken,upload_date,email),
FOREIGN KEY (upload_date,email) REFERENCES records(upload_date,email)
);
Run Code Online (Sandbox Code Playgroud)
引起我注意的第一件事是使用自然复合键作为两个表的主键。
我能够从这段代码中提取 3 件事:
users
表(此处未显示)email
用作text
..类型的主键。records
表使用复合键text
+ timestamp
。samples
表使用 3 个类型为text
+ timestamp
+ 的字段的复合键timestamp
。现在在这种情况下,代理键不是更好的识别吗?我的意思是性能明智的索引 anint
应该比索引 a …
performance index database-design best-practices primary-key