Reputation: 2720
I'm trying to understand the best way to model the following relationship:
I have a table named Contact
that has records of contacts uniquely identified using a serial
field and other fields like name
, phone
, address
and so on.
I also have a table named ProductInfo
that has several fields including three fields named Author
, Distributor
and PointOfContact
that each can have 1..n contacts from table Contact
. So, in this way, this means that I can have two authors, 3 distributors and 1 point of contact to the same product.
I was thinking of storing this info in ProductInfo
table with arrays of contact_id
in each field, but this seems not to be the best approach.
Can you tell me what should I do?
Upvotes: 4
Views: 5476
Reputation: 656471
A proper model that allows everything you need while enforcing referential integrity could look like this:
CREATE TABLE contact (
contact_id serial PRIMARY KEY
, name text
, phone text
, ...
);
CREATE TABLE product (
product_id serial PRIMARY KEY
, ...
);
CREATE TABLE product_role (
role_id int PRIMARY KEY
, role text UNIQUE
);
CREATE TABLE product_contact (
product_id int REFERENCES product
, contact_id int REFERENCES contact
, role_id int REFERENCES product_role
, PRIMARY KEY (product_id, contact_id, role_id)
);
If the same contact can never act in more than one role for the same product, don't include the role in the PK:
, PRIMARY KEY (product_id, contact_id)
This allows to simply add a row to product_role
to allow and additional type of contact.
If there is only a hand full of distinct roles, the data type "char"
might be convenient for role_id
.
Basics:
Upvotes: 4
Reputation: 812
Using arrays is not the best practice, yet for simple task like this it works fine. Especially if table productinfo contains millions of records, this way you avoid heavy joins, simpler and faster searches, some simple indexing speeding up queries ...
you can use a third table "link", table with references to productioninfo table and contacts assigned to it
productInfo_contacts:
ID integer
productinfo_id integer
contacts_id integer
contact_type integer ( 1,2,3 - ... author, distributor, contact ... )
using second approach is better, because then you have ways and room to add additional contact types, like co-author, contributors, translator ... or whatever additional contacts you may need to add later. Just keep in mind, joins sometimes will be more complex and will impact query performance significantly when working with large datasets
Well, that's my poor opinion :)
Upvotes: 1