I agree a lot with comments from @MDCCL:
You should analyze each particular case —that is, every particular table within its whole context, that is, the entire database structure— to define if it requires the appending of a system-generated surrogate column, as such an artifact is an additional aspect that requires its particular administration. Consistency with the way the rest of the tables look is irrelevant, from the logical and physical points of view
A few pointers from my side (the ones that come to my mind at the moment, and that probably are not all there is to it)
You need more space for everything: each row is wider, and you have an extra index to maintain. Every write will take (a little bit) more time, and so will every read, because you use more space to read and write the same real information. Let's say you have a log of the readings of several thermometers, one per second. You have one table
thermometers (thermometer_id PK, ...etc...) and one
readings (thermometer_id, reading_timestamp, value_read). Your readings table has a natural key:
(thermometer_id, reading_timestamp), because you cannot have two different readings at the same time. I would normally make this my PK, and forget about surrogates.
Using surrogate keys tend to obscure the real structure and meaning of your data. For instance, imagine you have a tables
books_liked_by_persons. This last table is a
m x n table, and most of the times contains only
(person_id, book_id) pairs. Adding a third
id is in such cases most probably meaningless and noisy.
In some very specific cases, you may want to have different tables with share one part of their structure (let's say, for instance, you want some of them to have always a
xxx_id) so that some application is easier to develop because the same pattern can be used to process different tables. [This tends to be rather uncommon, AFAIK, but is also possible.]
Using a surrogate key, even if there are some other alternative keys might help you save space (and probably, time). Imagine your natural key is a PGP key (note 1). It takes a
char(800) (approx.) to store it. Imagine you have several tables that reference this one. It will save (a lot of) space all around to have a surrogate integer key (8 or 16 bytes) on the original table, because the referencing tables will store 8 (or 16) bytes instead of 800. The accounting needs to be done for each specific case.
If you ever have to edit your data "by hand" (and, some day, you probably will), you don't want to look for keys which are really long. You prefer surrogates in that case.
Some databases (not PostgreSQL, at least as of now) will cluster the data of your tables using your primary key as a clustering index (or can do it by default unless you explicitly state the contrary). In such cases, it is normally advisable to have an always incrementing primary key; to avoid fragmentation.
So: every case needs analyzing, weighting and deciding. Sometimes consistency may be confused by flying on autopilot.
Side note: There are several different naming conventions. I prefer the one where
id is never used, and a
persons table has a
person_id column if needed.
Note 1: A PGP key looks more or less like: