views:

2176

answers:

4

I'm just getting started working with foreign keys for the first time and I'm wondering if there's a standard naming scheme to use for them?

Given these tables:

task (id, userid, title)
note (id, taskid, userid, note);
user (id, name)

Where Tasks have Notes, Tasks are owned by Users, and Users author Notes.

How would the three foreign keys be named in this situation? Or alternatively, does it even matter at all?

Update: This question is about foreign key names, not field names!

+2  A: 
how about FK_TABLENAME_COLUMNNAME?

Keep It Simple Stupid when ever possible

EvilTeach
+5  A: 

I usually just leave my PK named id, and then concatenate my table name and key column name when naming FKs in other tables. I never bother with camel-casing, because some databases discard case-sensitivity and simply return all upper or lower case names anyway. In any case, here's what my version of your tables would look like:

task (id, userid, title);
note (id, taskid, userid, note);
user (id, name);

Note that I also name my tables in the singular, because a row represents one of the objects I'm persisting. Many of these conventions are personal preference. I'd suggest that it's more important to choose a convention and always use it, than it is to adopt someone else's convention.

Steve Moyer
heh - this is the exact style I'm actually using (but with camelCase)- I thought I'd add a bit of extra description into the names for the purposes of illustrating their linkages.
nickf
So at least we can read each other's schemas;) ... what's embarassing is not being able to read your own after a couple years of absence. We use ERWin to diagram our schemas, but it's often convenient to have a text version and having a convention let's you find tables and fields easily.
Steve Moyer
+14  A: 

The standard convention in SQL Server is:

FK_ForeignKeyTable_PrimaryKeyTable

So, for example, the key between notes and tasks would be:

FK_note_task

And the key between tasks and users would be:

FK_task_user

This gives you an 'at a glance' view of which tables are involved in the key, so it makes it easy to see which tables a particular one (the first one named) depends on (the second one named). In this scenario the complete set of keys would be:

FK_task_user
FK_note_task
FK_note_user

So you can see that tasks depend on users, and notes depend on both tasks and users.

Greg Beech
excellent response. thanks.
nickf
How does that work when the foreign key points to an alternate key in the other table? It appears that naming method only works when the PK of second table is assumed to be the target of the foreign key? I also wonder why space is wasted for the current table's name in the relationship.
Steve Moyer
If the foreign key points to a candidate key on the second table rather than a primary key, then you'd probably use a third segment to the name to qualify this. It's an unusual situation to be in, and not one you'd typically design in from scratch, so I didn't include this in the response.
Greg Beech
You include the current table name in the key to keep it distinct. FK names are in the global namespace in SQL Server so you can't have two FKs named FK_PrimaryKeyTable attached to two different foreign key tables. The rules may be different for other database servers.
Greg Beech
Okay ... I have different namespaces for each table in Oracle, so I don't need the self reference.
Steve Moyer
+2  A: 

I use two underscore characters as delimiter i.e.

fk__ForeignKeyTable__PrimaryKeyTable

This is because table names will occasionally contain underscore characters themselves. This follows the naming convention for constraints generally because data elements' names will frequently contain underscore characters e.g.

CREATE TABLE NaturalPersons (
   ...
   person_death_date DATETIME, 
   person_death_reason VARCHAR(30) 
      CONSTRAINT person_death_reason__not_zero_length
         CHECK (DATALENGTH(person_death_reason) > 0), 
   CONSTRAINT person_death_date__person_death_reason__interaction
      CHECK ((person_death_date IS NULL AND person_death_reason IS NULL)
              OR (person_death_date IS NOT NULL AND person_death_reason IS NOT NULL))
        ...
onedaywhen