我需要将Shipping address
,Shipping postcode
,Billing Address
和Billing Postcode
放入一个Customer
表格。
这是否违反了3NF?
答案 0 :(得分:1)
这是否违反了3NF?
非常严格来说:是的。
实际上说:不。
如果您不计划:
......然后坚持你的设计。
将地址规范化为单独的表与将名字和姓氏标准化为单独的表一样明智,因为它们往往会重复。不要这样做。
考虑“实用”
SELECT
CustomerId
CustomerName,
COALESCE(BillingAddress, ShippingAddress) AS BillingAddress,
COALESCE(BillingPostcode, ShippingPostcode) AS BillingPostcode
FROM
Customer
VS。 “完全正常化”
SELECT
c.CustomerId
c.CustomerName,
COALESCE(bill.Address, ship.Address) AS BillingAddress,
COALESCE(bill.Postcode, ship.Postcode) AS BillingPostcode
FROM
Customer AS c
-- join customer-to-address-resolution for billing
LEFT JOIN CustomerAddress AS custAddrB ON custAddrB.CustomerId = c.CustomerId
AND custAddrB.AddressType = "Billing"
LEFT JOIN Address AS bill ON bill.AddressId = custAddrB.AddressId
-- join customer-to-address-resolution for shipping
LEFT JOIN CustomerAddress AS custAddrS ON custAddrS.CustomerId = c.CustomerId
AND custAddrS.AddressType = "Shipping"
LEFT JOIN Address AS ship ON ship.AddressId = custAddrS.AddressId
另外,后一种系统为您提供了每个客户拥有多个送货地址的头痛理论能力。
后一种系统的最大好处是:如果他们改变了街道的名称,你需要做的就是更新一条记录。换句话说:没有任何好处。
答案 1 :(得分:1)
是的,因为您将使用这些地址创建冗余,或者您需要在数据库中具有NULL值(例如,当运送和计费地址相同时),3NF禁止这些值。更好地使用这样的东西:
table customer
... | ... | shipping_address_id | billing_address_id |
----+-----+---------------------+--------------------+
x | y | 23 | 24 |
x | y | 25 | 25 |
...
table address
id | address | postcode | city | country |
---+---------+----------+------+---------+
23 | aaaa | 1234 | foo | bar |
24 | sdfsd | 2345 | sdf | sdf |
....
现在您可以通过加入
获取地址