With my recent selection of Planet Argon as my hosting provider for the rails app I’ve been working on I had two choices: use Postgresql or subject myself to ridicule and public humilition from the PA guys by sticking with MySQL. Fortunately I decided to take the opportunity to start learning about postgres, and I’m glad I have.
One of the unforeseen benefits I stumbled upon was using the inherits functionality of postgres to factor out some of the common columns that rails uses. For instance, everybody knows that adding the “lock_version”, “created_at” and “updated_at” columns gives you free optimistic locking and auto-timestamping, respectively. This is great, but adding these columns to every table definition in your SQL scripts is somewhat tedious. Enter “inherits”.
Instead of specifying these columns for every table like one would normally do:
create table users (
id integer primary key default nextval('users_id_seq'),
username varchar(255) not null unique,
password varchar(255) not null,
<b>created_at timestamp not null default now(),
updated_at timestamp not null default now(),
lock_version integer not null default 0</b>
);
create table documents (
id integer primary key default nextval('documents_id_seq'),
title varchar(255) not null unique,
body text not null,
<b>created_at timestamp not null default now(),
updated_at timestamp not null default now(),
lock_version integer not null default 0</b>
);
we can factor out the three common columns into their own table that the other tables can inherit from. For the purposes of this demo I’ve called this table “traceable”:
<b>create table traceable (
created_at timestamp not null default now(),
updated_at timestamp not null default now(),
lock_version integer not null default 0
);</b>
create table users (
id integer primary key default nextval('users_id_seq'),
username varchar(255) not null unique,
password varchar(255) not null
) <b>inherits(traceable);</b>
create table documents (
id integer primary key default nextval('documents_id_seq'),
title varchar(255) not null unique,
body text not null
) <b>inherits(traceable);</b>
Just as we can factor out common attributes of an object model into an abstract or super class, postgres allows us to do the same with our table model.
I like it when architectural layers synch up like this, and postgres makes it easy to do so. The only question I have is if this structure will lead to a performance hit that negates its convenience. I would imagine it is similar to using a view, although that is a largely uneducated guess.
