Enforce primary key on every table during dev?

Started by Jeremy Finzelabout 8 years ago59 messagesgeneral
Jump to latest
#1Jeremy Finzel
finzelj@gmail.com

We want to enforce a policy, partly just to protect those who might forget,
for every table in a particular schema to have a primary key. This can't
be done with event triggers as far as I can see, because it is quite
legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some
way to enforce that no transaction commits which added a table without a
primary key.

Any ideas?

Thanks,
Jeremy

#2Achilleas Mantzios
achill@matrix.gatewaynet.com
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

On 28/02/2018 15:34, Jeremy Finzel wrote:

We want to enforce a policy, partly just to protect those who might forget, for every table in a particular schema to have a primary key.  This can't be done with event triggers as far as I can see,
because it is quite legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some way to enforce that no transaction commits which added a table without a primary key.

Any ideas?

cron job to check for tables without PK ? Although for a short period the offending table would be there live without a PK.
But IMO every table, in addition to PK, should have also natural unique keys as much as possible.
Better safe than sorry.

Thanks,
Jeremy

--
Achilleas Mantzios
IT DEV Lead
IT DEPT
Dynacom Tankers Mgmt

#3John McKown
john.archie.mckown@gmail.com
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

On Wed, Feb 28, 2018 at 7:34 AM, Jeremy Finzel <finzelj@gmail.com> wrote:

We want to enforce a policy, partly just to protect those who might
forget, for every table in a particular schema to have a primary key. This
can't be done with event triggers as far as I can see, because it is quite
legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some
way to enforce that no transaction commits which added a table without a
primary key.

Any ideas?

Thanks,
Jeremy

​What stops somebody from doing:

CREATE TABLE foo (filler text primary key default null, realcol1 int,
realcol2 text);

And then just never bother to ever insert anything into the column FILLER?
It fulfills your stated requirement​ of every table having a primary key.
Of course, you could amend the policy to say a "non-NULL primary key".

--
I have a theory that it's impossible to prove anything, but I can't prove
it.

Maranatha! <><
John McKown

#4Adrian Klaver
adrian.klaver@aklaver.com
In reply to: John McKown (#3)
Re: Enforce primary key on every table during dev?

On 02/28/2018 05:52 AM, John McKown wrote:

On Wed, Feb 28, 2018 at 7:34 AM, Jeremy Finzel <finzelj@gmail.com
<mailto:finzelj@gmail.com>>wrote:

We want to enforce a policy, partly just to protect those who might
forget, for every table in a particular schema to have a primary
key.  This can't be done with event triggers as far as I can see,
because it is quite legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or
some way to enforce that no transaction commits which added a table
without a primary key.

Any ideas?

Thanks,
Jeremy

​What stops somebody from doing:

CREATE TABLE foo (filler text primary key default null, realcol1 int,
realcol2 text);

And then just never bother to ever insert anything into the column
FILLER? It fulfills your stated requirement​ of every table having a

Then you would get this:

test=# CREATE TABLE foo (filler text primary key default null, realcol1
int, realcol2 text);
CREATE TABLE
test=# insert into foo (realcol1, realcol2) values (1, 'test');
ERROR: null value in column "filler" violates not-null constraint
DETAIL: Failing row contains (null, 1, test).

primary key. Of course, you could amend the policy to say a "non-NULL
primary key".

--
I have a theory that it's impossible to prove anything, but I can't
prove it.

Maranatha! <><
John McKown

--
Adrian Klaver
adrian.klaver@aklaver.com

#5Melvin Davidson
melvin6925@gmail.com
In reply to: Adrian Klaver (#4)
Re: Enforce primary key on every table during dev?

On Wed, Feb 28, 2018 at 8:57 AM, Adrian Klaver <adrian.klaver@aklaver.com>
wrote:

On 02/28/2018 05:52 AM, John McKown wrote:

On Wed, Feb 28, 2018 at 7:34 AM, Jeremy Finzel <finzelj@gmail.com
<mailto:finzelj@gmail.com>>wrote:

We want to enforce a policy, partly just to protect those who might
forget, for every table in a particular schema to have a primary
key. This can't be done with event triggers as far as I can see,
because it is quite legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or
some way to enforce that no transaction commits which added a table
without a primary key.

Any ideas?

Thanks,
Jeremy

​What stops somebody from doing:

CREATE TABLE foo (filler text primary key default null, realcol1 int,
realcol2 text);

And then just never bother to ever insert anything into the column
FILLER? It fulfills your stated requirement​ of every table having a

Then you would get this:

test=# CREATE TABLE foo (filler text primary key default null, realcol1
int, realcol2 text);
CREATE TABLE
test=# insert into foo (realcol1, realcol2) values (1, 'test');
ERROR: null value in column "filler" violates not-null constraint
DETAIL: Failing row contains (null, 1, test).

primary key. Of course, you could amend the policy to say a "non-NULL

primary key".

--
I have a theory that it's impossible to prove anything, but I can't prove
it.

Maranatha! <><
John McKown

--
Adrian Klaver
adrian.klaver@aklaver.com

As Adrian pointed out, by definition, PK's create a constraint which are
NOT NULLABLE;

Here is the SQL to check for tables with no primary key.

*SELECT n.nspname, c.relname as table,
c.reltuples::bigint FROM pg_class c JOIN pg_namespace n ON (n.oid
=c.relnamespace ) WHERE relkind = 'r' AND relhaspkey =
FALSEORDER BY n.nspname, c.relname;*

--
*Melvin Davidson*
*Maj. Database & Exploration Specialist*
*Universe Exploration Command – UXC*
Employment by invitation only!

#6John McKown
john.archie.mckown@gmail.com
In reply to: Adrian Klaver (#4)
Re: Enforce primary key on every table during dev?

On Wed, Feb 28, 2018 at 7:57 AM, Adrian Klaver <adrian.klaver@aklaver.com>
wrote:

On 02/28/2018 05:52 AM, John McKown wrote:

On Wed, Feb 28, 2018 at 7:34 AM, Jeremy Finzel <finzelj@gmail.com
<mailto:finzelj@gmail.com>>wrote:

We want to enforce a policy, partly just to protect those who might
forget, for every table in a particular schema to have a primary
key. This can't be done with event triggers as far as I can see,
because it is quite legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or
some way to enforce that no transaction commits which added a table
without a primary key.

Any ideas?

Thanks,
Jeremy

​What stops somebody from doing:

CREATE TABLE foo (filler text primary key default null, realcol1 int,
realcol2 text);

And then just never bother to ever insert anything into the column
FILLER? It fulfills your stated requirement​ of every table having a

Then you would get this:

test=# CREATE TABLE foo (filler text primary key default null, realcol1
int, realcol2 text);
CREATE TABLE
test=# insert into foo (realcol1, realcol2) values (1, 'test');
ERROR: null value in column "filler" violates not-null constraint
DETAIL: Failing row contains (null, 1, test).

​Hum, it's been so long, I totally forgot. Which makes me wonder why the
parser doesn't "know" that a default of NULL for a primary key is going to
fail anyway and flag it at CREATE time. Oh, well. Thanks.​

primary key. Of course, you could amend the policy to say a "non-NULL

primary key".

--
I have a theory that it's impossible to prove anything, but I can't prove
it.

Maranatha! <><
John McKown

--
Adrian Klaver
adrian.klaver@aklaver.com

--
I have a theory that it's impossible to prove anything, but I can't prove
it.

Maranatha! <><
John McKown

#7David G. Johnston
david.g.johnston@gmail.com
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

On Wed, Feb 28, 2018 at 6:34 AM, Jeremy Finzel <finzelj@gmail.com> wrote:

We want to enforce a policy, partly just to protect those who might
forget, for every table in a particular schema to have a primary key. This
can't be done with event triggers as far as I can see, because it is quite
legitimate to do:

​Add a query to your test suite that queries the catalogs and fails if this
policy is violated. There is nothing in a running PostgreSQL server
instance that is going to enforce this for you.

David J.

#8Tim Cross
theophilusx@gmail.com
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

Jeremy Finzel <finzelj@gmail.com> writes:

We want to enforce a policy, partly just to protect those who might forget,
for every table in a particular schema to have a primary key. This can't
be done with event triggers as far as I can see, because it is quite
legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some
way to enforce that no transaction commits which added a table without a
primary key.

I think you would be better off having an automated report which alerts
you to tables lacking a primary key and deal with that policy through
other means. Using triggers in this way often leads to unexpected
behaviour and difficult to identify bugs. The policy is a management
policy and probably should be dealt with via management channels rather
than technical ones. Besides, the likely outcome will be your developers
will just adopt the practice of adding a serial column to every table,
which in itself doesn't really add any value.

Tim

--
Tim Cross

#9Berend Tober
btober@broadstripe.net
In reply to: Tim Cross (#8)
Re: Enforce primary key on every table during dev?

----- Original Message -----

From: "Tim Cross" <theophilusx@gmail.com>
Sent: Wednesday, February 28, 2018 4:07:43 PM

Jeremy Finzel <finzelj@gmail.com> writes:

We want to enforce a policy, partly just to protect those who might forget,
for every table in a particular schema to have a primary key. This can't
be done with event triggers as far as I can see, because it is quite
legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some
way to enforce that no transaction commits which added a table without a
primary key.

I think you would be better off having an automated report which alerts
you to tables lacking a primary key and deal with that policy through
other means. Using triggers in this way often leads to unexpected
behaviour and difficult to identify bugs. The policy is a management
policy and probably should be dealt with via management channels rather
than technical ones. Besides, the likely outcome will be your developers
will just adopt the practice of adding a serial column to every table,
which in itself doesn't really add any value.

I concur with other respondents that suggest this is more of a policy issue. In fact, you yourself identify it right there in the first sentence as a policy issue!

One tool that changed my life (as a PostgreSQL enthusiast) forever is David Wheeler's pgTAP (http://pgtap.org/) tool. It includes a suite of functionality to assess the database schema via automated testing. Part of a rigorous development environment might include using this tool so that any application/database changes be driven by tests, and then your code review process would assure that the appropriate tests are added to the pgTAP script to confirm that changes meet a policy standard such as what you are demanding. I can't imagine doing PostgreSQL development without it now.

Same guy also produced a related tool called Sqitch (http://sqitch.org/) for data base change management. Use these tools together, so that before a developer is allowed to check in a feature branch, your teams' code review process maintains rigorous oversight of modifications.

-- B

#10Melvin Davidson
melvin6925@gmail.com
In reply to: Tim Cross (#8)
Re: Enforce primary key on every table during dev?

On Wed, Feb 28, 2018 at 4:07 PM, Tim Cross <theophilusx@gmail.com> wrote:

Jeremy Finzel <finzelj@gmail.com> writes:

We want to enforce a policy, partly just to protect those who might

forget,

for every table in a particular schema to have a primary key. This can't
be done with event triggers as far as I can see, because it is quite
legitimate to do:

BEGIN;
CREATE TABLE foo (id int);
ALTER TABLE foo ADD PRIMARY KEY (id);
COMMIT;

It would be nice to have some kind of "deferrable event trigger" or some
way to enforce that no transaction commits which added a table without a
primary key.

I think you would be better off having an automated report which alerts
you to tables lacking a primary key and deal with that policy through
other means. Using triggers in this way often leads to unexpected
behaviour and difficult to identify bugs. The policy is a management
policy and probably should be dealt with via management channels rather
than technical ones. Besides, the likely outcome will be your developers
will just adopt the practice of adding a serial column to every table,
which in itself doesn't really add any value.

Tim

--
Tim Cross

*> I think you would be better off having an automated report which
alerts>you to tables lacking a primary key and deal with that policy
through>other means. Perhaps a better solution is to have a meeting with
the developers and explain to them WHY the policy of enforcing a primary
key is important. Also, explain the purpose ofprimary keys and why it is
not always suitable to just use an integer or serial as the key,but rather
why natural unique (even multi column) keys are better. But this begs the
question, why are "developers" allowed to design database tables? That
should be the job of the DBA! Atthe very minimum, the DBA should be
reviewing and have the authority to approve of disapprove of table/schema
designs/changes .*

--
*Melvin Davidson*
*Maj. Database & Exploration Specialist*
*Universe Exploration Command – UXC*
Employment by invitation only!

#11Alban Hertroys
haramrae@gmail.com
In reply to: Melvin Davidson (#10)
Re: Enforce primary key on every table during dev?

On 1 Mar 2018, at 1:47, Melvin Davidson <melvin6925@gmail.com> wrote:

I think you would be better off having an automated report which alerts
you to tables lacking a primary key and deal with that policy through
other means.

Perhaps a better solution is to have a meeting with the developers and explain to them
WHY the policy of enforcing a primary key is important. Also, explain the purpose of
primary keys and why it is not always suitable to just use an integer or serial as the key,
but rather why natural unique (even multi column) keys are better. But this begs the question,
why are "developers" allowed to design database tables? That should be the job of the DBA! At
the very minimum, the DBA should be reviewing and have the authority to approve of disapprove
of table/schema designs/changes .

Not to mention that not all types of tables necessarily have suitable candidates for a primary key. You could add a surrogate key based on a serial type, but in such cases that may not serve any purpose other than to have some arbitrary primary key.

An example of such tables is a monetary transaction table that contains records for deposits and withdrawals to accounts. It will have lots of foreign key references to other tables, but rows containing the same values are probably not duplicates.
Adding a surrogate key to such a table just adds overhead, although that could be useful in case specific rows need updating or deleting without also modifying the other rows with that same data - normally, only insertions and selections happen on such tables though, and updates or deletes are absolutely forbidden - corrections happen by inserting rows with an opposite transaction.

Regards,

Alban Hertroys
--
If you can't see the forest for the trees,
cut the trees and you'll find there is no forest.

#12Ron Johnson
ron.l.johnson@cox.net
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

On 03/01/2018 02:20 AM, Alban Hertroys wrote:
[snip]

Not to mention that not all types of tables necessarily have suitable candidates for a primary key. You could add a surrogate key based on a serial type, but in such cases that may not serve any purpose other than to have some arbitrary primary key.

An example of such tables is a monetary transaction table that contains records for deposits and withdrawals to accounts. It will have lots of foreign key references to other tables, but rows containing the same values are probably not duplicates.
Adding a surrogate key to such a table just adds overhead, although that could be useful in case specific rows need updating or deleting without also modifying the other rows with that same data - normally, only insertions and selections happen on such tables though, and updates or deletes are absolutely forbidden - corrections happen by inserting rows with an opposite transaction.

Wouldn't the natural pk of such a table be timestamp+seqno, just as the
natural pk of a transaction_detail table be transaction_no+seqno?

--
Angular momentum makes the world go 'round.

#13Rakesh Kumar
rakeshkumar464@aol.com
In reply to: Alban Hertroys (#11)
Re: Enforce primary key on every table during dev?

Adding a surrogate key to such a table just adds overhead, although that could be useful
in case specific rows need updating or deleting without also modifying the other rows with
that same data - normally, only insertions and selections happen on such tables though,
and updates or deletes are absolutely forbidden - corrections happen by inserting rows with
an opposite transaction.

I routinely add surrogate keys like serial col to a table already having a nice candidate keys
to make it easy to join tables. SQL starts looking ungainly when you have a 3 col primary
key and need to join it with child tables.

#14Steven Lembark
lembark@wrkhors.com
In reply to: Ron Johnson (#12)
Re: Enforce primary key on every table during dev?

On 03/01/2018 02:20 AM, Alban Hertroys wrote:
[snip]

Not to mention that not all types of tables necessarily have
suitable candidates for a primary key. You could add a surrogate
key based on a serial type, but in such cases that may not serve
any purpose other than to have some arbitrary primary key.

An example of such tables is a monetary transaction table that
contains records for deposits and withdrawals to accounts. It will
have lots of foreign key references to other tables, but rows
containing the same values are probably not duplicates. Adding a
surrogate key to such a table just adds overhead, although that
could be useful in case specific rows need updating or deleting
without also modifying the other rows with that same data -
normally, only insertions and selections happen on such tables
though, and updates or deletes are absolutely forbidden -
corrections happen by inserting rows with an opposite transaction.

Wouldn't the natural pk of such a table be timestamp+seqno, just as
the natural pk of a transaction_detail table be transaction_no+seqno?

Start with Date's notion that a database exists to correclty represent
data about the real world. Storing un-identified data breaks this
since we have no idea what the data means or have any good way of
getting it back out. Net result is that any workable relational
database will have at least one candidate key for any table in it.

If you can say that "rows containing the same values are not
duplicates" then you have a database that cannot be queried, audited,
or managed effectively. The problem is that you cannot identify the
rows, and thus cannot select related ones, update them (e.g., to
expire outdated records), or validate the content against any external
values (e.g., audit POS tapes using the database).

In the case of a monitary transaction you need a transaction
table, which will have most of the FK's, and a ledger for the
transaction amounts.

A minimum candidate key for the transaction table would be account,
timestamp, authorizing customer id, and channel. This allows two
people to, say, make deposits at the same time or the same authorizing
account (e.g., a credit card number) to be processed at the same time
in two places.

The data for a transaction would include things like the final status,
in-house authorizing agent, completion time.

The ledger entries would include the transaction SK, sequence within
the transaction, amount, and account. The ledger's candidate key is
a transaction SK + sequence number -- the amount and account don't
work because you may end up, say, making multiple deposits of $10
to your checking account on the same transaction.

The ledger's sequence value can be problematic, requiring external
code or moderately messy triggers to manage. Timestamps don't always
work and are subject to clock-skew. One way to avoid this is require
that a single transaction contain only unique amounts and accounts.
At that point the ledger becomes a degenerate table of transaction id,
amount, account (i.e., the entire table is nothing but a unique index).

This might require generating multiple database transactions for a
single external process (e.g., a customer walking up to the teller)
but does simplify processing quite a bit.

In both cases, having an SK on the ledger is useful for audit queries,
which might have to process a large number of ledger entries in code.
Extracting the ledger SK's in one query and walking down them using
a unique index can be more effecient than having to extract the values.

Either way, you can identify all of the transactions as unique and
all of the ledger entries for that transaction. At that point the
database can be queried for data, updated as necessary, audited
against external data.

If you have a design with un-identified data it means that you havn't
normalized it properly: something is missing from the table with
un-identifiable rows.

--
Steven Lembark 1505 National Ave
Workhorse Computing Rockford, IL 61103
lembark@wrkhors.com +1 888 359 3508

#15Alban Hertroys
haramrae@gmail.com
In reply to: Steven Lembark (#14)
Re: Enforce primary key on every table during dev?

On 1 March 2018 at 17:22, Steven Lembark <lembark@wrkhors.com> wrote:

On 03/01/2018 02:20 AM, Alban Hertroys wrote:
[snip]

Not to mention that not all types of tables necessarily have
suitable candidates for a primary key. You could add a surrogate
key based on a serial type, but in such cases that may not serve
any purpose other than to have some arbitrary primary key.

An example of such tables is a monetary transaction table that
contains records for deposits and withdrawals to accounts.

(...)

Start with Date's notion that a database exists to correclty represent
data about the real world. Storing un-identified data breaks this
since we have no idea what the data means or have any good way of
getting it back out. Net result is that any workable relational
database will have at least one candidate key for any table in it.

(...)

If you have a design with un-identified data it means that you havn't
normalized it properly: something is missing from the table with
un-identifiable rows.

While that holds true for a relational model, in reporting for
example, it is common practice to denormalize data without a
requirement to be able to identify a single record. The use case for
such tables is providing quick aggregates on the data. Often this
deals with derived data. It's not that uncommon to not have a primary
or even a uniquely identifiable key on such tables.

I do not disagree that having a primary key on a table is a bad thing,
but I do disagree that a primary key is a requirement for all tables.

More generally: For every rule there are exceptions. Even for this one.
--
If you can't see the forest for the trees,
Cut the trees and you'll see there is no forest.

#16Melvin Davidson
melvin6925@gmail.com
In reply to: Alban Hertroys (#15)
Re: Enforce primary key on every table during dev?

On Thu, Mar 1, 2018 at 11:43 AM, Alban Hertroys <haramrae@gmail.com> wrote:

On 1 March 2018 at 17:22, Steven Lembark <lembark@wrkhors.com> wrote:

On 03/01/2018 02:20 AM, Alban Hertroys wrote:
[snip]

Not to mention that not all types of tables necessarily have
suitable candidates for a primary key. You could add a surrogate
key based on a serial type, but in such cases that may not serve
any purpose other than to have some arbitrary primary key.

An example of such tables is a monetary transaction table that
contains records for deposits and withdrawals to accounts.

(...)

Start with Date's notion that a database exists to correclty represent
data about the real world. Storing un-identified data breaks this
since we have no idea what the data means or have any good way of
getting it back out. Net result is that any workable relational
database will have at least one candidate key for any table in it.

(...)

If you have a design with un-identified data it means that you havn't
normalized it properly: something is missing from the table with
un-identifiable rows.

While that holds true for a relational model, in reporting for
example, it is common practice to denormalize data without a
requirement to be able to identify a single record. The use case for
such tables is providing quick aggregates on the data. Often this
deals with derived data. It's not that uncommon to not have a primary
or even a uniquely identifiable key on such tables.

I do not disagree that having a primary key on a table is a bad thing,
but I do disagree that a primary key is a requirement for all tables.

More generally: For every rule there are exceptions. Even for this one.
--
If you can't see the forest for the trees,
Cut the trees and you'll see there is no forest.

*> it is common practice to denormalize data without a>requirement to be
able to identify a single record *

*You may perceive that to be "common practice", but in reality it is not,
and in fact a bad one. As was previously stated, PosgreSQL is a
_relational_ database,*
*and breaking that premise will eventually land you in very big trouble.
There is no solid reason not to a primary key for every table.*

--
*Melvin Davidson*
*Maj. Database & Exploration Specialist*
*Universe Exploration Command – UXC*
Employment by invitation only!

#17Steve Atkins
steve@blighty.com
In reply to: Melvin Davidson (#16)
Re: Enforce primary key on every table during dev?

(Melvin's mail doesn't quote properly; I've tried to fix it but may have broken something)

On Mar 1, 2018, at 8:50 AM, Melvin Davidson <melvin6925@gmail.com> wrote:

On Thu, Mar 1, 2018 at 11:43 AM, Alban Hertroys <haramrae@gmail.com> wrote:

On 1 March 2018 at 17:22, Steven Lembark <lembark@wrkhors.com> wrote:

If you have a design with un-identified data it means that you havn't
normalized it properly: something is missing from the table with
un-identifiable rows.

While that holds true for a relational model, in reporting for
example, it is common practice to denormalize data without a
requirement to be able to identify a single record. The use case for
such tables is providing quick aggregates on the data. Often this
deals with derived data. It's not that uncommon to not have a primary
or even a uniquely identifiable key on such tables.

I do not disagree that having a primary key on a table is a bad thing,
but I do disagree that a primary key is a requirement for all tables.

More generally: For every rule there are exceptions. Even for this one.

You may perceive that to be "common practice", but in reality it is not, and in fact a bad one. As was previously stated, PosgreSQL is a _relational_ database,
and breaking that premise will eventually land you in very big trouble. There is no solid reason not to a primary key for every table.

Sure there is. It's an additional index and significant additional insert / update overhead.
If you're never going to retrieve single rows, nor join in such a way that uniqueness
on this side is required there's no need for a unique identifier.

It's a rare case that you won't want a primary key, and I'll often add
a surrogate one for convenience even when it's not actually needed,
but there are cases where it's appropriate not to have one, even in
OLTP work. Log tables, for example.

"Every table should have a primary key, whether natural or surrogate"
is a great guideline, and everyone should follow it until they understand
when they shouldn't.

More generally: For every rule there are exceptions. Even for this one.

Cheers,
Steve

#18Ron Johnson
ron.l.johnson@cox.net
In reply to: Jeremy Finzel (#1)
Re: Enforce primary key on every table during dev?

On 03/01/2018 11:07 AM, Steve Atkins wrote:
[snip]

"Every table should have a primary key, whether natural or surrogate"
is a great guideline, and everyone should follow it until they understand
when they shouldn't.

Most people think they know, but they don't.

--
Angular momentum makes the world go 'round.

#19Daevor The Devoted
dollien@gmail.com
In reply to: Rakesh Kumar (#13)
Re: Enforce primary key on every table during dev?

On Thu, Mar 1, 2018 at 2:07 PM, Rakesh Kumar <rakeshkumar464@aol.com> wrote:

Adding a surrogate key to such a table just adds overhead, although that

could be useful

in case specific rows need updating or deleting without also modifying

the other rows with

that same data - normally, only insertions and selections happen on such

tables though,

and updates or deletes are absolutely forbidden - corrections happen by

inserting rows with

an opposite transaction.

I routinely add surrogate keys like serial col to a table already having a
nice candidate keys
to make it easy to join tables. SQL starts looking ungainly when you have
a 3 col primary
key and need to join it with child tables.

I was always of the opinion that a mandatory surrogate key (as you
describe) is good practice.
Sure there may be a unique key according to business logic (which may be
consist of those "ungainly" multiple columns), but guess what, business
logic changes, and then you're screwed! So using a primary key whose sole
purpose is to be a primary key makes perfect sense to me.

#20Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
Re: Enforce primary key on every table during dev?

On 03/01/2018 11:47 AM, Daevor The Devoted wrote:

On Thu, Mar 1, 2018 at 2:07 PM, Rakesh Kumar <rakeshkumar464@aol.com
<mailto:rakeshkumar464@aol.com>> wrote:

Adding a surrogate key to such a table just adds overhead, although

that could be useful

in case specific rows need updating or deleting without also

modifying the other rows with

that same data - normally, only insertions and selections happen on

such tables though,

and updates or deletes are absolutely forbidden - corrections happen

by inserting rows with

an opposite transaction.

I routinely add surrogate keys like serial col to a table already
having a nice candidate keys
to make it easy to join tables.  SQL starts looking ungainly when you
have a 3 col primary
key and need to join it with child tables.

I was always of the opinion that a mandatory surrogate key (as you
describe) is good practice.
Sure there may be a unique key according to business logic (which may be
consist of those "ungainly" multiple columns), but guess what, business
logic changes, and then you're screwed!

And so you drop the existing index and build a new one.  I've done it
before, and I'll do it again.

So using a primary key whose sole purpose is to be a primary key makes
perfect sense to me.

I can't stand synthetic keys.  By their very nature, they're so
purposelessly arbitrary, and allow you to insert garbage into the table.

--
Angular momentum makes the world go 'round.

#21Francisco Olarte
folarte@peoplecall.com
In reply to: Melvin Davidson (#10)
#22Martin Moore
martin.moore@avbrief.com
In reply to: Ron Johnson (#20)
#23Francisco Olarte
folarte@peoplecall.com
In reply to: Alban Hertroys (#11)
#24Daevor The Devoted
dollien@gmail.com
In reply to: Ron Johnson (#20)
#25Francisco Olarte
folarte@peoplecall.com
In reply to: Rakesh Kumar (#13)
#26Francisco Olarte
folarte@peoplecall.com
In reply to: Steven Lembark (#14)
#27David G. Johnston
david.g.johnston@gmail.com
In reply to: Daevor The Devoted (#24)
#28Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#29Melvin Davidson
melvin6925@gmail.com
In reply to: Ron Johnson (#28)
#30marcelo
marcelo.nicolet@gmail.com
In reply to: Ron Johnson (#28)
#31Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#32Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#33Daevor The Devoted
dollien@gmail.com
In reply to: David G. Johnston (#27)
#34marcelo
marcelo.nicolet@gmail.com
In reply to: Ron Johnson (#32)
#35Daevor The Devoted
dollien@gmail.com
In reply to: Ron Johnson (#28)
#36David G. Johnston
david.g.johnston@gmail.com
In reply to: Daevor The Devoted (#33)
#37Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#38Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#39David G. Johnston
david.g.johnston@gmail.com
In reply to: Ron Johnson (#38)
#40marcelo
marcelo.nicolet@gmail.com
In reply to: Ron Johnson (#37)
#41David G. Johnston
david.g.johnston@gmail.com
In reply to: marcelo (#40)
#42Rakesh Kumar
rakeshkumar464@aol.com
In reply to: Daevor The Devoted (#19)
#43Daevor The Devoted
dollien@gmail.com
In reply to: David G. Johnston (#39)
#44Daevor The Devoted
dollien@gmail.com
In reply to: David G. Johnston (#41)
#45marcelo
marcelo.nicolet@gmail.com
In reply to: David G. Johnston (#39)
#46Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#47Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#48geoff hoffman
geoff@rxmg.com
In reply to: marcelo (#45)
#49Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#50Tim Cross
theophilusx@gmail.com
In reply to: Ron Johnson (#37)
#51Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Ron Johnson (#49)
#52David G. Johnston
david.g.johnston@gmail.com
In reply to: Tim Cross (#50)
#53Ron Johnson
ron.l.johnson@cox.net
In reply to: Alban Hertroys (#11)
#54Adrian Klaver
adrian.klaver@aklaver.com
In reply to: Ron Johnson (#53)
#55Gavin Flower
GavinFlower@archidevsys.co.nz
In reply to: Daevor The Devoted (#19)
#56marcelo
marcelo.nicolet@gmail.com
In reply to: Adrian Klaver (#54)
#57marcelo
marcelo.nicolet@gmail.com
In reply to: Gavin Flower (#55)
#58Daevor The Devoted
dollien@gmail.com
In reply to: Gavin Flower (#55)
#59marcelo
marcelo.nicolet@gmail.com
In reply to: Daevor The Devoted (#58)