【问题标题】:Database design - Multiple "Contact information" for different tables数据库设计 - 不同表的多个“联系信息”
【发布时间】:2014-05-15 07:49:41
【问题描述】:

我有一个包含“person”、“company”、“shop”等表的数据库。其中许多表必须包含“contact information”。在Database design - Similar Contact Information for multiple entities 中询问了设计这个的可能性 现在,在我的数据库中我可以为每个联系人数据提供多个地址、多个电话和多个电子邮件。这是我的数据库架构:

所以,我制作了一个中间表“联系人”,作为将“联系人信息”链接到每个表的最简单方法。
我的问题:这样做并有一个只有一行的表?

【问题讨论】:

  • 只有一行还是只有一列?

标签: database database-design relational-database contacts


【解决方案1】:

这就是我设计你的数据库的方式:

address_types
    id              unsigned int(P)
    description     varchar(10) // Mailing, Physical, etc.

addresses
    id              unsigned int(P)
    line1           varchar(50) // 123 Main Street, etc.
    line2           varchar(50) // Default NULL
    city_id         unsigned int(F cities.id)
    zip             varchar(6) // 12345, A1A 1A1, etc.
    zip4            char(4) // Default NULL
    lat             decimal(10,8) // 13.12345678, etc.
    lon             decimal(11,8) // 110.12345678, etc.

cities
    id              unsigned int(P)
    state_id        unsigned int(F states.id)
    name            varchar(50) // Omaha, Detroit, Tampa, etc.

companies
    id              unsigned int(P)
    name            varchar(75) // IBM, Microsoft, RedHat, etc.
    ...

companies_addresses
    id                  unsigned int(P)
    company_id          unsigned int(F companies.id)
    address_id          unsigned int(F addresses.id)
    address_type_id     unsigned int(F address_types.id)

companies_contacts
    id                  unsigned int(P)
    company_id          unsigned int(F companies.id)
    contact_id          unsigned int(F contacts.id)
    contact_type_id     unsigned int(F contact_types.id)

companies_emails
    id                  unsigned int(P)
    company_id          unsigned int(F companies.id)
    email_id            unsigned int(F emails.id)
    email_type_id       unsigned int(F email_types.id)

contact_types
    id              unsigned int(P)
    description     varchar(10) // Home phone, Mobile phone, FAX, etc.

在北美,电话号码如下所示:CC-AAA-EEE-SSSS-XXXXXXX,其中 CC 是国家代码,AAA 是区号,EEE 是交换机,SSSS 是电台,XXXXX 是分机号。

contacts
    id              unsigned int(P)
    country_code    varchar(3)
    area_code       varchar(3)
    exchange        varchar(3)
    station         varchar(4)
    extension       varchar(10) // Default NULL

ISO 3166-1

countries
    id              char(2) // ca, mx, us, etc.
    iso3            char(3) // can, mex, usa, etc.
    iso_num         char(3)
    name            varchar(44) // Canada, Mexico, United States, etc.

email_types
    id              unsigned int(P)
    description     varchar(10) // Personal, Work, etc.

emails
    id              unsigned int(P)
    address         varchar(255) // support@ibm.com, etc.

shops
    id              unsigned int(P)
    name            varchar(45) // Shop A, Shop B, etc.
    ...

shops_addresses
    id                  unsigned int(P)
    shop_id             unsigned int(F shops.id)
    address_id          unsigned int(F addresses.id)
    address_type_id     unsigned int(F address_types.id)

shops_contacts
    id                  unsigned int(P)
    shop_id             unsigned int(F shops.id)
    contact_id          unsigned int(F contacts.id)
    contact_type_id     unsigned int(F contact_types.id)

shops_emails
    id                      unsigned int(P)
    shop_id                 unsigned int(F shops.id)
    email_id                unsigned int(F emails.id)
    email_type_id           unsigned int(F email_types.id)

ISO 3166-2

states
    id              unsigned int(P)
    country_id      char(2)(F countries.id)
    code            varchar(2) // AL, NF, NL, etc.
    name            varchar(50) // Alabama, Newfoundland, Nuevo León, etc.

【讨论】:

  • 好的,我明白你的意思了。您提出了与此处stackoverflow.com/questions/3636061/… 相同的解决方案(方法1)。但这里有一个同样的缺点——“创建很多关联表”。还有其他方法吗?
  • 真的不是缺点,归一化是好事。只要您正确索引事物,RDBMS 就擅长连接表。
  • 我知道这已经 2 岁了,但我想知道你的想法是什么?每封电子邮件都有一个类型。我正在设计类似的东西并得出与您类似的设计(除了没有将电话号码分成尽可能多的列),除了我打算将 email_type_id 放在电子邮件表上。
  • @kralco626 - 两年后我会设计这个稍微不同。我会按照您的建议将email_type_id 放在emails 表中,但我也会从shops_addressesshops_contactsshops_emails 表中删除id 列。我会将它们各自的主键更改为shop_idaddress_id 的组合; shop_idcontact_id;和shop_idemail_id
【解决方案2】:

我的问题:这样做并有一个只有一行的表是一个好习惯吗?

不是真的。看着你的图表,我不得不问:一个联系人真的可以链接到任意数量的人吗?如果没有,您应该使用 'person' 作为父表,并让其他表链接到它。

【讨论】:

  • 其实是的,我可以拥有一千个人、公司和商店。如果我很好理解您的建议,我必须将电子邮件、电话和地址直接链接到我的所有实体(个人、公司、商店)吗?所以我会有这样的东西:email -> idemail, mail, idperson, idcompany, idshop真的更好吗?
  • 不,在您的情况下,您实际上应该使用下面 Benny Hill 建议的关联表。可以不这样做,但确保数据保持一致会非常烦人且不值得。
  • 还将国家地址链接到城市,因为不同国家和/或州/省/县的城市可能具有相同的名称
【解决方案3】:

就个人而言,我不喜欢这种方法,因为我们需要为每个表和许多关联表创建任何实体。我建议一张表用于联系信息,另一张用于地址。

informations
- id INT
- name VARCHAR
- value VARCHAR
- type ENUM(phone, email, url, custom)
- idcompany INT NULL
- idcontact INT NULL

addresses
- id
- address1
- address2
- district
- postcode
- idcity
- idcompany
- idcontact

【讨论】:

    猜你喜欢
    • 2011-09-01
    • 1970-01-01
    • 1970-01-01
    • 2011-03-15
    • 1970-01-01
    • 1970-01-01
    • 2015-06-29
    • 1970-01-01
    • 2017-12-28
    相关资源
    最近更新 更多