我在数据库中收集了地理对象:
有四个表:
Countries
Regions
Provinces
Cities
城市除其他外包括ProvinceCode 各省还有regionCode 区域尤其包括CountryCode
还有第五个表:描述
ObjectCode
ObjectType(country, region, province, city)
Description.
如何从描述表中获取来自确定国家/地区的对象的所有描述?
答案 0 :(得分:2)
放下肥皂盒,这是一个实际的解决方案:
select Countries.code as country_code
, count_d.description as country_desc
, Regions.code as region_code
, reg_d.description as region_desc
, Provinces.code as province_code
, prov_d.description as province_desc
, Cities.code as city_code
, city_d.description as city_desc
from Countries
join Descriptions count_d
on ( count_d.ObjectCode = Countries.code
and count_d.ObjectType = 'COUNTRY' )
join Regions
on ( Regions.CountryCode = Countries.code )
join Descriptions reg_d
on ( region_d.ObjectCode = Regions.code
and count_d.ObjectType = 'REGION' )
join Provinces
on ( Provinces.RegionCode = Regions.code )
join Descriptions prov_d
on ( prov_d.ObjectCode = Provinces.code
and count_d.ObjectType = 'PROVINCE' )
join Cities
on ( Cities.ProvinceCode = Provinces.code )
join Descriptions city_d
on ( city_d.ObjectCode = Cities.code
and count_d.ObjectType = 'CITY' )
where Countries.whatever = 'DONDESTAHN'
/
未经过实际测试,请注意拼写错误!它们对Cut'N'Paste Driven Development来说是一个特别的危险。
答案 1 :(得分:0)
如果他读到这个,我可以看到我的DBA畏缩......如果重新分解/正常化是一个选项,我会
a)将描述栏放在每张桌子上...... 要么 b)为每个对象创建单独的表格,即
国家 CountryDescriptions 地区 RegionDescriptions等......
如果那不是一个选项
如果您创建了一些视图来进行封装,则可能更容易管理。
CREATE VIEW vCountryDescriptions
AS
SELECT * FROM Countries c
JOIN Descriptions d ON c.ObjectCode = d.ObjectCode
AND d.ObjectType = 'Country'
对每个实体重复。
然后加入你的4个观点。
答案 2 :(得分:0)
我怀疑@zerkms不是唯一一个不了解这个数据模型有什么问题的人,所以值得研究它的缺点。
<强> 1。它没有关系完整性
描述的主键可能是(ObjectCode,ObjectType)。这不会映射到任何父键,因此无法强制执行Description必须属于某个对象的规则。即使ObjectCode在所有表中都是唯一的(比如它是生成的UUID),因此描述的主键可能是(ObjectCode),我们仍然无法强制执行外键约束,因为一个子键不能引用多个父键。
相反,我们也无法强制执行Country必须具有Description的规则,因为外键不能以这种方式工作。
<强> 2。表现将受到影响
检索单个数据集的每个查询现在都是一个连接。加入并不是一件坏事 - 这就是RDBMS产品的意图 - 但现在我们有一个小表国家加入了更大的表描述。因此,检索所有国家及其描述的查询效率会低很多,因为它需要知道其他类型的所有描述。
同样,6NF有一个好处,因为它比发布的实现更好地扩展。
第3。方式太多表
新要求:我们需要为所有这些对象保留ABBREVIATION。这不是Description的属性,因此我们无法将其存储在该表中。但我们不能在国家,地区等上放置人口列,因为会不一致。所以我们需要另一个表缩写。哦,用户也希望持有人口。和AREA,如果你不介意。在你知道它之前,select * from countries
已成为一个五表联接。
这是6NF发生故障的地方。需要的表格数量迅速转变为令人难以置信的比例模式。
这就是为什么大多数明智的人会停留在BCNF,或至少3NF。