答案 0 :(得分:1)
我试图找出你想要实现的目标。我可以想象两件事,但它可能是别的东西。
首先,您要尝试仅代表地理数据(州内包含的城市,包含在国家/地区)。用户指向一个城市,然后该城市链接到州和国家。
第二个是你允许用户以3个精度等级中的任何一个给出他们的地址。即他们可以说他们住在哪个城市,或者说是哪个州,甚至是哪个国家。
如果你试图只做第一个,那么你应该摆脱用户 - >州和用户 - >国家关系,并将用户链接到城市。如果您需要知道用户所在的州和/或国家/地区,请从城市加入州和/或国家/地区。
如果你正在尝试做第二个,那么它看起来很像polymorphic association,所以我建议你阅读链接的帖子,看看你觉得哪个最适合你。
如果您尝试同时执行这两项操作,那么我认为您有两种选择。第一种是保持模式不变,但是通过业务逻辑强制执行用户的其中一个地址字段是非空的。这将避免用户可能指向的可能问题,例如一个处于不同状态的州和城市。
第二个是明确表示你有3种类型的地址(所有级别,只有国家+州,只有国家)。这在表格方面更昂贵,但更清楚地说明了进展情况,即约束并未隐藏在业务逻辑中。
对于第二个选项,您可以这样:
用户强>
@user_id
(删除地址字段)
<强>国家强>
@country_id
(其他领域)
<强>国家强>
@state_id
country_id(外键)
<强>城市强>
@city_id
state_id(外键)
<强> L1_Address 强>
@ l1_address_id
country_id(外键)
address_id(外键)
<强> L2_Address 强>
@ l2_address_id
state_id(外键)
address_id(外键)
<强> L3_Address 强>
@ l3_address_id
city_id(外键)
address_id(外键)
<强> UserAddress 强>
@user_Id
@address_id
答案 1 :(得分:1)
您没有任何循环引用。第一个图表中的功能依赖关系(不包括名称)是:
user_id -> city_id
user_id -> state_id
user_id -> country_id
city_id -> state_id
state_id -> country_id
问题在于,由于关系构成,这组FD是多余的。例如,user_id -> city_id
和city_id -> state_id
表示传递依赖user_id -> state_id
,您也可以明确记录。因此,从user_id
到state_id
有两条路径,从user_id
到country_id
有三条路径。这是可以理解的,因为你想支持不同级别的细节。
冗余数据是数据完整性的风险,因此如果我们能够降低风险,则冗余不会成为问题。根据您的DBMS,您可以强制执行包含空值的复合外键约束,即在(city_id, state_id)
中的users
引用(city_id, state_id)
中放cities
并让(state_id, country_id)
} users
中的(state_id, country_id)
引用states
。或者,您的DBMS可能支持检查约束。
答案 2 :(得分:0)
在您的数据库设计中,不需要关系Country - State - Cities。这是多余的。所以,我的建议是删除属性 country_id 表状态和 state_id 表CITIES。
更新:
如果你的设计做得好并且有充分的理由保证你提到循环参考,那么留下这样的参考没有问题。
我认为你有一个循环引用异常但在阅读@reaanb帖后,我同意他的看法。