docs/content/v2025.1/explore/ysql-language-features/advanced-features/inheritance.md
YSQL supports table inheritance using the INHERITS keyword, which is a PostgreSQL feature that allows you to create child tables that inherit columns and certain constraints from one or more parent tables.
To illustrate with a basic example, create the following tables:
-- Columns common to all account types
CREATE TABLE accounts (
account_id INTEGER PRIMARY KEY,
balance NUMERIC NOT NULL CHECK (balance >= 0),
profit NUMERIC DEFAULT 0
);
-- Child table for investment accounts
CREATE TABLE investment_accounts (
investment_type TEXT NOT NULL CHECK (investment_type IN ('stocks', 'bonds', 'funds')),
CHECK (balance >= 5000),
PRIMARY KEY (account_id, investment_type)
) INHERITS (accounts);
-- Child table for savings accounts
CREATE TABLE savings_accounts (
interest_rate NUMERIC NOT NULL CHECK (interest_rate >= 0 AND interest_rate <= 0.1),
CHECK (balance >= 100),
PRIMARY KEY (account_id)
) INHERITS (accounts);
testdb=# \d investment_accounts
Table "public.investment_accounts"
Column | Type | Collation | Nullable | Default
-----------------+---------+-----------+----------+---------
account_id | integer | | not null |
balance | numeric | | not null |
profit | numeric | | | 0
investment_type | text | | not null |
Indexes:
"investment_accounts_pkey" PRIMARY KEY, lsm (account_id HASH, investment_type ASC)
Check constraints:
"accounts_balance_check" CHECK (balance >= 0::numeric)
"investment_accounts_balance_check" CHECK (balance >= 5000::numeric)
"investment_accounts_investment_type_check" CHECK (investment_type = ANY (ARRAY['stocks'::text, 'bonds'::text, 'funds'::text]))
Inherits: accounts
This schema allows for certain queries to be performed over all accounts while still preserving features unique to each account type. For example:
SELECT SUM(balance) FROM accounts WHERE account_id = 10;
Any columns added to or dropped from the parent accounts table are propagated to child tables so that such queries on the parent accounts table are always well formed.
However, there are certain caveats to keep in mind:
accounts may have its own rows that are not part of any child tables.account_id on the parent accounts table does not propagate to children and has to be redefined for each child table. This is also the behavior for foreign key constraints and non-primary key unique constraints. You need to take special care to maintain such constraints across parent-child hierarchies.Table inheritance can lead to complex hierarchies similar to class inheritance in object-oriented programming because a specific table can inherit from multiple parent tables and can itself be a parent table for other child tables.
SELECT and UPDATE queries on the parent table operate on a union of the parent and all child tables in the hierarchy. To restrict queries to just the specific table, use the ONLY keyword:
SELECT SUM(balance) FROM ONLY accounts WHERE account_id = 10;
UPDATE ONLY accounts SET balance = balance + 100 WHERE account_id = 1;
ONLY keyword can be used to restrict the schema change to just the parent table. For example, ALTER TABLE ONLY accounts DROP COLUMN profit drops the column from the parent table alone while leaving it on the child tables.Table inheritance is {{<tags/feature/tp idea="2158">}} - report any problems using issue {{<issue 27949>}}.
For an up-to-date list, see issue {{<issue 27949>}}.