I was wondering peoples opinions on the naming of ID columns in database tables.
If I have a table called Invoices with a primary key of an identity column I would c
I personally prefer (as it has been stated above) the Table.ID for the PK and TableID for the FK. Even (please don't shoot me) Microsoft Access recommends this.
HOWEVER, I ALSO know for a fact that some generating tools favor the TableID for PK because they tend to link all column name that contain 'ID' in the word, INCLUDING ID!!!
Even the query designer does this on Microsoft SQL Server (and for each query you create, you end up ripping off all the unnecessary newly created relationships on all tables on column ID)
THUS as Much as my internal OCD hates it, I roll with the TableID convention. Let's remember that it's called a Data BASE, as it will be the base for hopefully many many many applications to come. And all technologies Should benefit of a well normalized with clear description Schema.
It goes without saying that I DO draw my line when people start using TableName, TableDescription and such. In My opinion, conventions should do the following:
Table alias: Full table Name, singularized. Ex.
SELECT Employee.*, eMail.Address
FROM Employees AS Employee LEFT JOIN eMails as eMail on Employee.eMailID = eMail.eMailID -- I would sure like it to just have the eMail.ID here.... but oh well
[Update]
Also, there are some valid posts in this thread about duplicated columns due of the "kind of relationship" or role. Example, if a Store has an EmployeeID, that tells me squat. So I sometimes do something like Store.EmployeeID_Manager. Sure it's a bit larger but at leas people won't go crazy trying to find table ManagerID, or what EmployeeID is doing there. When querying is WHERE I would simplify it as: SELECT EmployeeID_Manager as ManagerID FROM Store
What I do to keep things consistent for myself (where a table has a single column primary key used as the ID) is to name the primary key of the table Table_pk
. Anywhere I have a foreign key pointing to that tables primary key, I call the column PrimaryKeyTable_fk
. That way I know that if I have a Customer_pk
in my Customer table and a Customer_fk
in my Order table, I know that the Order table is referring to an entry in the Customer table.
To me, this makes sense especially for joins where I think it reads easier.
SELECT *
FROM Customer AS c
INNER JOIN Order AS c ON c.Customer_pk = o.Customer_fk
FWIW, our new standard (which changes, uh, I mean "evolves", with every new project) is:
pk_
prefix means primary key_id
suffix means an integer, auto-increment IDfk_
prefix means foreign key (no suffix necessary)_VW
suffix for viewsis_
prefix for booleansSo, a table named NAMES might have the fields pk_name_id, first_name, last_name, is_alive,
and fk_company
and a view called LIVING_CUSTOMERS_VW
, defined like:
SELECT first_name, last_name FROM CONTACT.NAMES WHERE (is_alive = 'True')
As others have said, though, just about any scheme will work as long as it is consistent and doesn't unnecessarily obfuscate your meanings.
For the column name in the database, I'd use "InvoiceID".
If I copy the fields into a unnamed struct via LINQ, I may name it "ID" there, if it's the only ID in the structure.
If the column is NOT going to be used in a foreign key, so that it's only used to uniquely identify a row for edit editing or deletion, I'll name it "PK".
Coming at this from the perspective of a formal data dictionary, I would name the data element invoice_ID
. Generally, a data element name will be unique in the data dictionary and ideally will have the same name throughout, though sometimes additional qualifying terms may be required based on context e.g. the data element named employee_ID
could be used twice in the org chart and therefore qualified as supervisor_employee_ID
and subordinate_employee_ID
respectively.
Obviously, naming conventions are subjective and a matter of style. I've find ISO/IEC 11179 guidelines to be a useful starting point.
For the DBMS, I see tables as collections of entites (except those that only ever contain one row e.g. cofig table, table of constants, etc) e.g. the table where my employee_ID
is the key would be named Personnel
. So straight away the TableNameID
convention doesn't work for me.
I've seen the TableName.ID=PK TableNameID=FK
style used on large data models and have to say I find it slightly confusing: I much prefer an identifier's name be the same throughout i.e. does not change name based on which table it happens to appear in. Something to note is the aforementioned style seems to be used in the shops which add an IDENTITY
(auto-increment) column to every table while shunning natural and compound keys in foreign keys. Those shops tend not to have formal data dictionaries nor build from data models. Again, this is merely a question of style and one to which I don't personally subscribe. So ultimately, it's not for me.
All that said, I can see a case for sometimes dropping the qualifier from the column name when the table's name provides a context for doing so e.g. the element named employee_last_name
may become simply last_name
in the Personnel
table. The rationale here is that the domain is 'people's last names' and is more likely to be UNION
ed with last_name
columns from other tables rather than be used as a foreign key in another table, but then again... I might just change my mind, sometimes you can never tell. That's the thing: data modelling is part art, part science.
I do hate the plain id name. I strongly prefer to always use the invoice_id or a variant thereof. I always know which table is the authoritative table for the id when I need to, but this confuses me
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.InvoiceID = inv.ID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.ID = inv.InvoiceLineID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.ID = inv.InvoiceID
SELECT * from Invoice inv, InvoiceLine inv_l where
inv_l.InvoiceLineID = inv.ID
What's worst of all is the mix you mention, totally confusing. I've had to work with a database where almost always it was foo_id except in one of the most used ids. That was total hell.