views:

177

answers:

8

I have a name table with (id,first_name,middle_name,last_name,sex) and an email table with (id_fk,email_add)

Infact I will be having similar tables of the second kind, like a phone table (id_fk,phone_no), where id_fk is the foreign key referring to the id in the name table.

Is it required or rather is there a good reason to have a primary key in the second and third tables? Or other similar tables? Or would you suggest a different schema?

PS: The tables are for a contact storing app

+4  A: 

In the cases you describe, the primary key is the whole table (id_fk, phone_no) since the rows are not otherwise shared, represent an unordered collection and have only value rather than any sort of identity of their own.

Jeffrey Hantin
Yes I realised that too. However, after sipwiz' answer regarding the problem of changing pk later, i am half inclined to use a seperate pk.
Sujoy
+1  A: 

There is a primary key for the phone table. Each (id_fk, phone_no) pair uniquely defines every entry so, in this case, the primary key is a composite one.

http://weblogs.sqlteam.com/jeffs/archive/2007/08/23/composite_primary_keys.aspx

Sinan Ünür
+1  A: 

You are almost always better off using a primary key. Even if you think it's not needed now as your database grows and gets more complicated you will quickly run into issues without one.

Personally I'd also recommend using a data agnostic column for your primary key something such as a guid/uuid/serial. By using a field that does not contain usable data you will never be in a situation where you have to update the primary key which can be another messy operation once your database grows.

sipwiz
The reason I asked the question is that while I have studied database, I have no real world experience (project) that uses one."as your database grows and gets more complicated you will quickly run into issues without one."could you give me an example kindly? like what issues i may have.Though your advice is sound and I am inclined to use a generated pk for all the tables.
Sujoy
In your third table (id_fk,phone_no) your primary key is a composite key of id_fk and phone_no that means when (not if) you need to change the phone_no you will be changing the primary key. In addition if later on you have enhance your application and have something like work, mobile and home numbers and a user enters the same number for all 3 your insert will fail with a duplicate primary key error.
sipwiz
In that case, the phone number table should have a third column called 'type' and the composite primary key should be (id_fk, phone_no, type).
Sinan Ünür
+1  A: 

You could make (foreign key, phone number) a composite primary key.

Personally I favour the use of strictly technical primary keys, typically meaning an auto number ID column. One of the advantages is it'll make it easier to update and delete records by using the ID rather than remembering the old value in HTML forms and so on.

cletus
+2  A: 

I'd add a simple auto-incrementing "id" primary key to each of those tables, it costs very little and makes it easier to reference specific rows later.

It might also be a good idea to look at a different naming scheme for your foreign keys, "id_fk" could be a bit confusing as it provides no indication of which table's "id" it is referring to, something like "name_id" might be a better choice.

Tobias Cohen
I concur with Tobias comment about naming the foreign key column. Using the naming convention `parent_id` (where parent is the name of the referenced table) is a good idea. Use the `fk` to give a name to the foreign key CONSTRAINT, not the column.
spencer7593
+1  A: 

You should definitely have a primary key for all of your tables. In the case of the (id_fk, phone_no) you could either use a composite key consisting of both columns, or you could add another column to be the primary key. I would recommend the latter as it will ultimately reduce the complexity of everything and will be much more accommodating if you are using an ORM.

Gordon
A: 

Why do you need separate tables for email addresses and telephone numbers? Storing them all in the same table is much more efficient. Your schema could look like this:

(Pseudo SQL)

Create table ContactName (
       CONTACT_ID integer not null default auto_increment,
       etc
       )

CREATE TABLE TELECOM_CLASSES (
    CLASS_ID INTEGER NOT NULL DEFAULT AUTO_INCREMENT,
    CLASS_NAME VARCHAR(200) NOT NULL 
              CHECK (CLASS_NAME  IN ('email','tel','fax',etc)),
    etc
     );

CREATE TABLE CONTACT_TELECOMS (
    TELECOM_ID INTEGER NOT NULL DEFAULT AUTO_INCREMENT,
    CONTACT_ID INTEGER NOT NULL REFERENCES CONTACTNAME (CONTACT_ID),
    CLASS_ID INTEGER NOT NULL REFERENCES TELECOMS_CLASSES (CLASS_ID),
    TELECOM VARCHAR(200) NOT NULL,
    etc

);
Vincent Buck
so if CLASS_ID is email then TELECOM has an email address. hmm i get the idea but not sure how this is more eficient since with two separate tables when i need email i can just query against the email table without bothering about any CLASS_ID
Sujoy
This allows you to add another entity to track like Post Office Boxes. Also makes it easier to query everything for a user and list it out without having to Union all the tables. What you lose is the ability to control the format of your phone numbers and email addresses at the database level. I guess a trigger with appropriate logic could handle it.
Jeff O
Notice the convention where some table names are _SINGULAR_ and some are _PLURAL_. Name the class. Name what ONE row in the table represents.
spencer7593
+2  A: 

My design philosophy is that every table always has a single int identity pk column.

This seems to be a controversial decision, as previous comments on SO have shown, but it's also very convenient.

devio
Writing ad hoc queries on databases with a bunch of compound keys just makes them go on and on and on.
Jeff O
There are benfits and drawbacks to the practice you describe. This space is too cramped to discuss those benefits and drawbacks thoroughly, or to compare with other design practices. I'd like to pursue the issue elsewhere, if it can be done without controversy degenerating into acrimony and insult.
Walter Mitty