Given an OO language in which the naming convention for object properties is camelCased, and an example object like this:
{
id: 667,
firstName: "Vladimir",
lastName: "Horowitz",
canPlayPiano: true
}
How should I model this structure in a PostgreSQL table? Options:
- unquoted camelCase column names
- quoted camelCase column names
- unquoted (lowercase) names with underscores
Each have drawbacks:
-
Unquoted identifiers fold to lowercase. You can create a table with a
canPlayPianocolumn, but the mixed case never reaches the database. The column will show up ascanplaypianoin psql, pgAdmin, explain results, error messages, everwhere. -
Quoted identifiers keep their case, but once you create them like that you will always have to quote them. If you create a table with a
"canPlayPiano"column, aSELECT canPlayPiano ...will fail. This adds noise to all SQL statements. -
Lowercase names with underscores are unambiguous but they don’t map to the names the application language is using. You will have to remember to use different names for storage (
can_play_piano) and code (canPlayPiano). It also prevents certain types of code automation where properties and database columns need to be named the same.
Whatever I do, some part is going to feel awkward. I’ve been using option 3, but keep hoping for a better solution. The case folding and the need for quotes is coming from the SQL standard (PostgreSQL’s adaptation of the standard). I know how it works; I’m more interested in best practices than explanations about how PostgreSQL handles identifiers.
Given that PostgreSQL uses case-insensitive identifiers with underscores, should you change all your identifiers in your application to do the same? Clearly not. So why do you think the reverse is a reasonable choice?
The convention in PostgreSQL has come about through a mix of standards compliance and long-term experience of its users. Stick with it.
If translating between column-names and identifiers gets tedious, have the computer do it – they’re good at things like that. I’m guessing almost all of the 9-million database abstraction libraries out there can do that. If you have a dynamic language it’ll take you all of two lines of code to swap column-names to identifiers in CamelCase.