哪种设计客户和主地址所在的“客户”和“地址”表的更好方法?

时间:2019-06-28 19:31:01

标签: database-design

一个客户端可能在数据库中记录了两个地址,一个地址是主要地址,另一个地址是次要地址,本文旨在确定解决此问题的更好设计。

我确定了以下解决方案,您还有其他方法吗?

解决方案1:

Table Clients
+ name
+ surname
Table Addresses
+ line1
+ city
+ country
+ postcode
+ flag_primary

解决方案2:

Table Clients
+ name
+ surname
+ primary_address_id

Table Addresses
+ line1
+ city
+ country
+ postcode

解决方案3:

Table Clients
+ id
+ name
+ surname

Table Addresses
+ id
+ user_id
+ line1
+ city
+ country
+ postcode

Table User_Settings
+ user_id
+ address_id

请说明为什么您认为您的建议是正确的。

3 个答案:

答案 0 :(得分:1)

很显然,请执行解决方案2。

逻辑:当客户更改其主要地址时,不会更改地址。这反映在数据库模式中

腐败:拥有一个具有两个主地址的客户端,您的数据库绝不会变得奇怪。解决方案1可以有两个布尔标志为true。

简单性:更改客户端地址时,只需一次更新即可完成。对于解决方案1,您需要进行2次更新...也许是在一个棘手的SQL查询中进行的,但这是两次更新!

可扩展性:如果有一天,您希望地址是“可共享的”,例如不为居住在同一地方的两个人存储相同的地址,则不会破坏您的“ primary_address”功能,因为它已存储在用户中。在解决方案1上,将需要重构。

符合所有“版本”系统:客户更改其主要地址? =>客户端已更新=>存储该客户端的旧版本或更新的行。 使用解决方案1,您将打破它或不得不自己更改默认行为。

编辑:好吧,如果您在回答问题后对其进行编辑,这会使我们的答案看起来很愚蠢。

如果您现在打算每个客户拥有多个地址,但仍然是主要地址,请告诉您

client
    primary_address (fk to address(id))

address
    client (fk to client(id))

答案 1 :(得分:0)

因为有两个实体-客户和地址

仅当且仅当客户端存在该地址时,该地址才会存在。因此, Address 实体与 Client 实体具有依赖性,因此您可以将address实体中的client_id作为外键。

你可以有这样的东西:

Table Clients
+ client_id
+ name
+ surname

Table Addresses
+ line1
+ city
+ country
+ postcode
+ flag_primary
+ client_id [FOREIGN_KEY]

答案 2 :(得分:0)

在现实世界中,一个客户将有多个地址,并且一个地址可以由多个客户共享(例如,公司的邮政地址)。

我会在客户端和地址之间建立多对多关系,并带有一个标志,指示哪个地址是主要地址。甚至是一种类型(“邮政”,“访问”,...)

client

  • id(PK)
  • first_name
  • last_name

address

  • id(PK)
  • line1
  • city
  • postcode
  • ....

client_address

  • address_id(从FK到address
  • client_id(从FK到client
  • is_primary(布尔值,是/否)

根据实际的数据库产品,可以在client_address表上通过唯一约束来强制执行“每个客户端只有一个主地址”