In a previous post I have written about tables as data types in PostgreSQL. In addition to that, PostgreSQL has a feature similar to the inheritance mechanism of data types in object-oriented programming: table inheritance.
Table inheritance allows you to create a hierarchical relationship between tables. With this feature you define a parent table, and child tables inherit columns and some constraints (like CHECK constraints and NOT NULL constraints) from it.
How it works
To begin, we create the parent table products using the following SQL code:
CREATE TABLE products (
id SERIAL PRIMARY KEY,
name TEXT NOT NULL,
price DECIMAL(10, 2) NOT NULL
);
Next, let’s create child tables that inherit from the products table. We will create two product categories: electronics and clothing. Each child table will have its own specific columns in addition to the inherited columns. To set up the inheritance relation we use the INHERITS keyword:
CREATE TABLE electronics (
warranty_period INT,
power_consumption INT
) INHERITS (products);
CREATE TABLE clothing (
size TEXT,
color TEXT
) INHERITS (products);
Now we insert some rows into the child tables:
INSERT INTO electronics
(name, price, warranty_period, power_consumption)
VALUES ('Laptop', 1439.0, 2, 536);
INSERT INTO clothing
(name, price, size, color)
VALUES ('T-Shirt', 5.99, 'L', 'red');
When we query each child table individually, we only get the rows we inserted into it, as expected. However, when we query the parent table, we get all the products from the child the tables:
SELECT * FROM products;
id name price
--------------------
1 Laptop 1439.00
2 T-Shirt 5.99
Note that you can also insert rows into the parent table:
INSERT INTO products
(name, price)
VALUES ('Milk', 1.15);
This row will not show up in the child tables, only when querying the parent table. If you are asking yourself now if there is an equivalent to an “abstract class”, there isn’t one. Just don’t insert into the parent table if it doesn’t make sense in your domain.
If you want to query rows only from the parent table you can use the ONLY keyword:
SELECT name, price FROM ONLY products;
This keyword works also with other commands like UPDATE and DELETE.
On a final note, you can also remove the inheritance relationship from a child table with the NO INHERIT clause:
ALTER TABLE clothing NO INHERIT products;