通過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 –