Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Database design - Multiple "Contact information" for different tables

I have a database with tables "person", "company", "shop", etc. Many of these tables must have "contact information". The possibility to design this was asked in Database design - Similar Contact Information for multiple entities Now, in my database I leave a possibility to have a multiple addresses, multiple phones and multiple emails to each contact data. This is my database schema:

database contact information

So, I make an intermediate table "contact" as a simplest way to link a "contact information" to each table.
My question: is it a good practice to do this and to have a table with only one row?

like image 337
nb.ag Avatar asked Oct 28 '13 17:10

nb.ag


People also ask

Can one database have multiple tables?

The majority of databases you'll work with as a developer will have more than one table, and those tables will be connected together in various ways to form table relationships.

What do you call a database with multiple tables which are linked together?

What is a relational database? A relational database organizes data into rows and columns, which collectively form a table. Data is typically structured across multiple tables, which can be joined together via a primary key or a foreign key.

Why are databases designed with multiple tables?

If the data is one-to-many (each user has thousands of rows of usage info), then it should be split into separate tables to reduce duplicate data (duplicate data wastes storage space, cache space, and makes the database harder to maintain).


3 Answers

This is how I would design your database:

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.

In North America phone numbers look like this: CC-AAA-EEE-SSSS-XXXXXXX where CC is the country code, AAA is the area code, EEE is the exchange, SSSS is the station and XXXXX is the extension.

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

See 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) // [email protected], 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)

See 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.
like image 149
Benny Hill Avatar answered Oct 17 '22 03:10

Benny Hill


My question: is it a good practice to do this and to have a table with only one row?

Not really. Looking at your diagram, I have to ask : can a contact really be linked to an arbitrary number of persons ? If not, you should use 'person' as your parent table and make the other tables link to it.

like image 25
AurelienT Avatar answered Oct 17 '22 03:10

AurelienT


Personaly, i don't like realy this method because we need to create any Entity for each table and a lot of associative tables. I propose one table for contact informations and another one for addresses.

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

And

addresses
- id
- address1
- address2
- district
- postcode
- idcity
- idcompany
- idcontact
like image 27
Youssef El Montaser Avatar answered Oct 17 '22 03:10

Youssef El Montaser