在某些情况下,在表中使用外键的情况是FK与另一个表具有父关系或子关系,如下所示:
工作人员:
Id | Name | CityId |
-------------------------
1001 | John | 1 |
1002 | Mary | 2 |
1003 | Bill | 3 |
1004 | Jose | 4 |
1005 | Anna | 5 |
城市:
Id | Name | CountryId |
----------------------------
1 | NY | 101 |
2 | Paris | 102 |
3 | London | 103 |
4 | Rome | 104 |
5 | Tokyo | 105 |
国家/地区:
Id | Name |
---------------
101 | USA |
102 | France |
103 | UK |
104 | Italy |
105 | Japan |
我的问题是:我们应该在Staff实体中仅使用CityId作为FK,还是最好在Staff实体中包含CityId及其父CountryId?当然,将FK及其父级作为FK似乎是多余的,但是我想澄清一下,当使用这种级联关系之王时是否存在某些情况或要求?应该使用哪一个?
答案 0 :(得分:1)
我将避免破坏规范化,因为没有简单的方法可以强制要求职员的Country参考和City的Country参考保持同步。例如,某个工作人员可能将“城市”设置为“多伦多”,而“国家/地区”设置为“加拿大”,但是随后某处将城市更新为“波士顿”,但没有更新“工作人员。国家/地区”。工作人员说国家是“加拿大”,而城市则是国家“美国”。谁被信任为真理之源?
在显示有关员工的信息时,请使用“视图模型”拼合相关细节。如果要显示带有国家(地区)名称的职员详细信息,而没有关于城市的其他信息,则视图模型可以基于从实体中选择的数据来显示该细节。例如:
var staffViewModels = context.Staff
.Select(x => new StaffViewModel
{
StaffId = x.Id,
Name = x.Name,
Country = x.City.Country.Name
}).ToList();
即使结构引入了一个由与国家相关的城市组成的工作人员地址:
var staffViewModels = context.Staff
.Select(x => new StaffViewModel
{
StaffId = x.Id,
Name = x.Name,
Country = x.Address.City.Country.Name
}).ToList();
该实体可以保持规范化并生成SQL以有效访问相关数据。