Dav*_*key 4 database-design sql-server data-integrity
假设我们有以下 3 个表:
tUsers (ID, name, countryID, regionID)
------
1 | Joe | 1 | 1
2 | Sue | NULL | 2
3 | Bob | 2 | NULL
4 | Amy | NULL | NULL
tCountries (ID, name, regionID)
------
1 | USA | 1
2 | China | 3
tRegions (ID, name)
------
1 | North America
2 | Central America
3 | East Asia
4 | Europe
Run Code Online (Sandbox Code Playgroud)
DB 是否有一种方法可以防止用户在国家/地区不匹配的同时仍然允许一个或两个为 NULL?例如,查询UPDATE tUsers SET regionID=4 WHERE ID = 3
将失败,因为 Bob 的国家是中国而不是欧洲地区。
3个外键版本
create table tRegions (
ID int not null primary key,
name varchar(20)
);
create table tCountries (
ID int not null primary key,
name varchar(20),
regionID int,
--any superset of PK is undoubtly UNIQUE
constraint cu1 unique (ID, regionID),
foreign key (regionID) references tRegions(ID)
);
create table tUsers (
ID int not null primary key,
name varchar(20),
countryID int ,
regionID int,
foreign key (regionID) references tRegions(ID),
foreign key (countryID) references tCountries(ID),
foreign key (countryID,regionID) references tCountries(ID,regionID )
)
insert tRegions (ID, name)
values
(1,'North America'),
(2,'Central America'),
(3,'East Asia'),
(4,'Europe')
insert tCountries(ID, name, regionId)
values
(1,'USA',1),
(2,'China',3)
insert tUsers (ID, name, countryID, regionId)
values
(1,'Joe', 1 ,1),
(2,'Sue',NULL,2),
(3,'Bob', 2 ,NULL),
(4,'Amy',NULL,NULL)
go
--OK
update tUsers set RegionId=3
where ID=3
select * from tUsers
go
--fails
update tUsers set CountryId=2
where ID=2
select * from tUsers
Run Code Online (Sandbox Code Playgroud)