1

I have three tables. Two basic tables listing objects and a third table logging changes in database. Here is an example.

create table individual (ind_id integer, age integer, name varchar);
create table organisation (org_id integer, city varchar, name varchar);
create TABLE log_table (log_id integer, object_id integer, table_name varchar, information json, log_date date);

I want to ensure that any row in the log_table corresponds to an existing object in either the individual table or the organisation table. This means that the insertion

insert into log_table (object_id,table_name,information,log_date) values (13,'organisation','{"some":"interesting","information":"on the changes"}','2017-11-09');

is valid only if the table organisation contains a record with the ID 13.

How can I do that in PostgreSQL ? If this is not possible, then I suppose I will have to create one column for the individual table and one for the organisation table in the log_table.

Clodoaldo Neto
  • 118,695
  • 26
  • 233
  • 260

3 Answers3

0

You need an entity table:

create table entity (
    entity_id serial primary key,
    entity_type text check (entity_type in ('individual','organization'))
)
create table individual (
    ind_id integer primary key references entity (entity_id), 
    age integer, name varchar
);
create table organisation (
    org_id integer primary key references entity (entity_id), 
    city varchar, name varchar
);
create TABLE log_table (
    log_id integer primary key, 
    entity_id integer references entity (entity_id), 
    information json, log_date date
);
Clodoaldo Neto
  • 118,695
  • 26
  • 233
  • 260
0

You could also use triggers to solve this problem . Seperate triggers can be made on individual and organisation table which could be on before update ,after update , after insert actions .

You could add one column in log table which would correspond to action performed in base table i.e update or insert .

Also you could add unique constraint on table name and object id .

This would eventually lead to logging every possible operation in table without changing in application code .

Hope this helps !

yathartha
  • 472
  • 5
  • 8
0

Starting from your current design you can enforce what you want declaratively by adding to each entity table a constant checked or computed/virtual table/type variant/tag column and a FK (foreign key) (id, table) to the log table.

You have two kinds/types of logged entities. Google sql/database subtypes/polymorphism/inheritance. Or (anti-pattern) 2/many/multiple FKs to 2/many/multiple tables.

philipxy
  • 14,867
  • 6
  • 39
  • 83