通过BCNF规范化基于功能依赖性。什么 是像这样的数据的功能依赖?什么是 候选键?
Cities
State County City
--
Alabama Pike Troy
Arkansas Pike Delight
Florida Bay Springfield
Maine Penobscot Springfield
这里只有一个(简单)函数依赖,只有一个 候选键。唯一的FD是州,县,市 - >州,县, 市。唯一的候选关键是{州,县,城市}。这个关系 至少在5NF。
您无法改善这种关系,但你可以提高的 数据库。该数据库并不知道阿拉巴马州没有任何名为“Los Angeles”的县。所以它会让你插入这个无效的行。
Cities
State County City
--
Alabama Los Angeles Troy
要解决是问题,添加包含所有有效 县的关系,并设置一个外键引用。
Counties
State
--
Alabama Autauga
Alabama Baldwin
...
Alabama Pike
...
California Los Angeles
...
的关系,“县”为所有键,它没有非黄金 属性。 “县”也至少在5NF。
数据库仍然不知道它不应该允许这样的行。
Cities
State County City
--
Wales Pike Troy
有没有名为威尔士在美国的状态。解决这个问题的方法与上一个问题相同。
States
--
Alabama
Arkansas
...
California
...
并设置县的国家的外键引用。
下面是它在标准SQL中的样子,除了我没有 供应所有50个州或全部3000+个县。
create table states (
state varchar(100) primary key
);
insert into states values
('Alabama'), ('Arkansas'), ('California'), ('Florida'),
('Maine'); -- and more . . .
create table counties (
county varchar(100) not null,
state varchar(100) not null,
primary key (county, state),
foreign key (state) references states (state)
on update restrict on delete restrict
);
insert into counties values
('Autauga', 'Alabama'), ('Baldwin', 'Alabama'), ('Pike', 'Alabama'),
('Pike', 'Arkansas'),
('Los Angeles', 'California'),
('Bay', 'Florida'),
('Penobscot', 'Maine'); -- and more . . .
create table cities (
city varchar(100) not null,
county varchar(100) not null,
state varchar(100) not null,
primary key (city, county, state),
foreign key (county, state) references counties (county, state)
on update restrict on delete restrict
);
insert into cities values
('Troy', 'Pike', 'Alabama'),
('Delight', 'Pike', 'Arkansas'),
('Springfield', 'Penobscot', 'Maine'),
('Springfield', 'Bay', 'Florida'); -- and more . . .
现在你会发现,这是不可能插入无效元组 {特洛伊,洛杉矶,阿拉巴马}和{特洛伊,派克,威尔士}。
使用代理ID号码而不是自然键不会更改 正常形式。但它确实更改数据库的工作方式。而不是 必然在一个很好的方式。
使用上面的SQL表,此更新将失败。
update states
set state = 'Wibble'
where state = 'Alabama';
而这是一件好事。
让我们用代理ID号代替这些表。
create table states (
state_id integer primary key,
state varchar(100) not null unique
);
insert into states values
(1, 'Alabama'), (2, 'Arkansas'), (3, 'California'), (4, 'Florida'),
(5, 'Maine'); -- and more . . .
create table counties (
county_id integer not null,
county varchar(100) not null,
state_id integer not null,
foreign key (state_id) references states (state_id)
on update restrict on delete restrict,
primary key (county_id, state_id),
unique (county, state_id)
);
insert into counties values
(1, 'Autauga', 1), (2, 'Baldwin', 1), (3, 'Pike', 1),
(4, 'Pike', 2),
(5, 'Los Angeles', 3),
(6, 'Bay', 4),
(7, 'Penobscot', 5); -- and more . . .
create table cities (
city_id integer not null,
city varchar(100) not null,
county_id integer not null,
state_id integer not null,
foreign key (county_id, state_id) references counties (county_id, state_id)
on update restrict on delete restrict,
primary key (city_id, county_id, state_id),
unique (city, county_id, state_id)
);
insert into cities values
(1, 'Troy', 3, 1),
(2, 'Delight', 4, 2),
(3, 'Springfield', 7, 5),
(4, 'Springfield', 6, 4); -- and more . . .
所有这三张表仍然在至少5NF。但是这个 (无效)更新现在会成功。
update states
set state = 'Wibble'
where state = 'Alabama';
这是一件坏事。
使用代理ID号码使得每个外键引用 具有与声明它们on update cascade
相同的行为。要恢复的一部分on update restrict
的语义,必须采取 额外的,不直观的步骤来撤销对 引用表的更新权限。
差不多没有人获得该部分的权利。
有这证明,才能有你可以跟着恢复原始 关系的路径分离主键 没有realtional原则。换句话说,没有关系原则 有理由改变这个...
Cities
city_id city county_id state_id
--
1 Troy 3 2
...这一点。
Cities
city_id city county_id
--
1 Troy 3
Counties
county_id county state_id
--
3 Pike 1
不仅有证明有理由分裂 主键没有关系的原则,它产生的问题一个旨在解决 数据的关系模型。查找“IMS”,这是一个分层数据库管理系统,需要用户按照路径通过 数据文件。
这个Area字段是做什么用的?您可能错过了由ID字段和AreaName字段组成的TblArea。你应该在TblProvince表中添加一个Area_Id –