Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jquery/78.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 这是否违反了3NF?_Database_Normalization - Fatal编程技术网

Database 这是否违反了3NF?

Database 这是否违反了3NF?,database,normalization,Database,Normalization,我需要将发货地址、发货邮政编码、账单地址和账单邮政编码放在一个客户表中 这是否违反了3NF 这是否违反了3NF 严格地说:是的 实际上,没有 如果你没有计划: 在数据库中有专用的“地址”实体(即:当地址只是附加到客户记录的自由文本时) 每个客户拥有可变数量的地址(但仅限于两个) 要为每个要选择的地址写入左联接 …然后坚持你的设计 将地址规范化为单独的表与将名字和姓氏规范化为单独的表一样合理,因为它们往往重复。不要这样做 考虑“实用” vs“完全正常化” 另外,后一种系统使您在理论上能够为每

我需要将
发货地址
发货邮政编码
账单地址
账单邮政编码
放在一个
客户
表中

这是否违反了3NF

这是否违反了3NF

严格地说:是的

实际上,没有

如果你没有计划:

  • 在数据库中有专用的“地址”实体(即:当地址只是附加到客户记录的自由文本时)
  • 每个客户拥有可变数量的地址(但仅限于两个)
  • 要为每个要选择的地址写入左联接
…然后坚持你的设计

将地址规范化为单独的表与将名字和姓氏规范化为单独的表一样合理,因为它们往往重复。不要这样做


考虑“实用”

vs“完全正常化”

另外,后一种系统使您在理论上能够为每个客户提供多个配送地址


后一种系统的最大好处是:如果他们更改街道名称,您只需更新一条记录即可。换句话说:没有好处。

是的,因为您将使用这些地址创建冗余,或者您需要在数据库中使用空值(例如,当发货地址和账单地址相同时),这是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     |
....

现在,您可以通过join获得地址,但如果他需要为一个客户存储多个地址,他需要至少将其分为3个表。。。所以最好现在就做,就像later@reox如果他需要第三个地址,那么他可以添加几列。每个客户几乎没有超过三个地址;将其正常化没有任何好处。-然而。如果这是一个基于位置的服务,而地址是系统的关键实体,那么在一个单独的表中维护它们并规范每个客户的地址(即“签入”)将是正确的做法。但在这种情况下不是这样。
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
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     |
....