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:
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?
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 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.
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).
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.
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.
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
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With