我知道它被多次询问过,但我想解释一下我的场景,看看使用Identity列作为主键而不是使用复合主键有什么好处。
我目前正在阅读两个文本文件:File1包含Make&汽车模型,而File2有制造,模型,汽车年。 Make,File2中的模型组合将始终位于File1中。
所以我创建了由MakeId(identity),Make
和Model
列组成的表[Car]。表[Car]的数据如下所示。 [Car]中的数据是File1:
[MakeId] [Make] [Model]
1 HONDA ACCORD
2 HONDA CIVIC
3 FORD FOCUS
4 FORD ESCORT
对于File2,我创建了包含CarYearId
(标识),Make
,Model
,Year
列的表[CarYear]。 [CarYear]中的数据是File2的精确复制品:
[CarYearId] [Make] [Model] [Year]
1 HONDA ACCORD 2002
2 HONDA ACCORD 2001
3 HONDA ACCORD 2004
4 HONDA CIVIC 1998
5 FORD FOCUS 1998
6 FORD ESCORT 2001
7 FORD ESCORT 2002
我有什么理由不使用Make,为复合主键建模?鉴于我的情况,因为我有Make&在两个表中建模,我可以轻松地直接搜索第二个表而不必进行内连接。
答案 0 :(得分:2)
File1有Make&汽车模型。 。
所以感兴趣的数据看起来像这样。
make model -- HONDA ACCORD HONDA CIVIC FORD FOCUS FORD ESCORT
列“make”显然不是候选键。从这个数据样本中可以看出,“model”看起来像<候选键。几年前我实际上不得不研究这个问题,我发现只有几个模型由多个制造商制造,而且这些模型都不是最新的。但这并不重要。
这里的候选键是{make,model}还是{model},这个表是6NF。 1 如果我们假设唯一的候选键是{make,model},我可能会在标准SQL中实现它。
create table car_models (
make varchar(15) not null,
model varchar(15) not null,
primary key (make, model)
);
File2有Make,Model,Car of Year。
所以感兴趣的数据看起来像这样。
make model year -- HONDA ACCORD 2002 HONDA ACCORD 2001 HONDA ACCORD 2004 HONDA CIVIC 1998 FORD FOCUS 1998 FORD ESCORT 2001 FORD ESCORT 2002
根据上表中关键字的假设,该表只有一个候选键,并且只有一个附加属性。它也是6NF。 SQL版本可能如下所示。
create table car_model_years (
make varchar(15) not null,
model varchar(15) not null,
model_year integer not null
check (model_year between 1886 and 2099),
primary key (make, model, model_year),
foreign key (make, model) references car_models (make, model)
);
这些表包含 no 冗余数据。您不能在不破坏语义或损害数据完整性的情况下删除任何列。外键在“car_model_years”的行中重复,但这并不是多余的 - 完全
我有什么理由不使用Make,为复合主键建模? 作为理论(关系)问题,不,没有。如果从6NF开始,则添加代理ID号非规范化该表。 (6NF需要单个候选键。)即使你做添加代理ID号,你仍然必须声明{make,model}为 作为一个实际问题,不是理论(关系)问题,这些6NF表可能比使用代理ID号更好地执行它们。例如,基于make和model的“car_model_years”查询通常会使用仅索引扫描 - 它们根本不必读取基表。 另一个实际问题是,除了id号之外,某些应用程序框架与任何密钥的处理都很差。恕我直言,这证明使用更好的框架是合理的,但不会损害数据库的结构。
not null unique
。未能声明该约束使得表格最终看起来像这样。model_id make model
--
1 Honda Accord
2 Honda Accord
3 Honda Accord