Country table
country_id,country_name
State table
state_id,state_name,state_country_id
City table
city_id,city_name,city_state_id
Product table
product_id,product_name,product_city_id
上述设计是否良好? 如果我想检索产品国家ID,那么我必须编写子查询或内部联接。
或者我可以修改产品表格如下吗?
Product table
product_id,product_name,product_city_id,product_state_id,product_country_id
答案 0 :(得分:3)
您的建议违反了3NF(假设您的候选键是明显的)。 3NF声明(给定wikipedias定义,http://en.wikipedia.org/wiki/Normal_forms#Normal_forms):
"每个非素数属性都不可传递地依赖于表中的每个候选键。从表中删除不对主键描述有贡献的属性。换句话说,不允许传递依赖。"
在您提议的修改中,product_id是候选键,但product_country_id过渡依赖于product_id
那说有些情况下你出于实际原因可能选择违反正常形式,但你应该知道你正在这样做,并采取额外的预防措施来防止更新异常。
附注:IMO最好使用标准标识符,例如country_code而不是country_id,请参阅ISO 3166(http://en.wikipedia.org/wiki/ISO_3166-1_alpha-3)
答案 1 :(得分:1)
第二种设计(单一表格)允许您针对处于完全无关状态的城市(即夏威夷莫斯科)创建产品记录。
因此第二种设计不好(未标准化)
您不应该避免在关系数据库中使用联接。这就是重点。