Partitioned tables help organize large data by splitting it into smaller parts. This makes searching and managing data faster and easier.
Creating partitioned tables in PostgreSQL
Start learning this pattern below
Jump into concepts and practice - no test required
CREATE TABLE table_name ( column1 datatype, column2 datatype, ... ) PARTITION BY partition_method (column_name);
partition_method can be RANGE, LIST, or HASH depending on how you want to split the data.
You must create partitions (child tables) after creating the main partitioned table.
CREATE TABLE sales ( id SERIAL PRIMARY KEY, sale_date DATE NOT NULL, amount NUMERIC ) PARTITION BY RANGE (sale_date);
CREATE TABLE employees ( id SERIAL PRIMARY KEY, name TEXT, department TEXT ) PARTITION BY LIST (department);
CREATE TABLE logs ( id SERIAL PRIMARY KEY, event_time TIMESTAMP, event_type TEXT ) PARTITION BY HASH (id);
This example creates a partitioned table for orders by year. It adds two partitions for 2023 and 2024. Then it inserts orders into each partition and selects all orders sorted by date.
CREATE TABLE orders ( order_id SERIAL PRIMARY KEY, order_date DATE NOT NULL, customer_id INT, amount NUMERIC ) PARTITION BY RANGE (order_date); CREATE TABLE orders_2023 PARTITION OF orders FOR VALUES FROM ('2023-01-01') TO ('2024-01-01'); CREATE TABLE orders_2024 PARTITION OF orders FOR VALUES FROM ('2024-01-01') TO ('2025-01-01'); INSERT INTO orders (order_date, customer_id, amount) VALUES ('2023-06-15', 1, 100.50), ('2024-03-20', 2, 200.75); SELECT * FROM orders ORDER BY order_date;
Each partition is a separate table that holds a subset of data.
You must define partitions that cover all possible values to avoid errors on insert.
Partitioning improves performance but adds some complexity in setup.
Partitioned tables split large tables into smaller parts for better performance.
You choose how to split data: by range, list, or hash.
After creating the main table, create partitions for each data segment.
Practice
Solution
Step 1: Understand partitioning concept
Partitioned tables divide a big table into smaller parts based on a column value, improving management and query performance.Step 2: Compare options
Backup, merging several tables, and encryption are not related to partitioning.Final Answer:
To split a large table into smaller, manageable parts based on a column -> Option AQuick Check:
Partitioned tables split big tables = A [OK]
- Confusing partitioning with backup or encryption
- Thinking partitioning merges tables instead of splitting
- Assuming partitioning duplicates data
created_date?Solution
Step 1: Recall partition syntax
PostgreSQL usesPARTITION BY RANGE (column)to create range partitions.Step 2: Check options
CREATE TABLE orders PARTITION BY RANGE (created_date);uses correct syntax.CREATE TABLE orders PARTITION ON RANGE (created_date);uses wrong keyword 'PARTITION ON'.PARTITION BY LISTandPARTITION BY HASHuse different partition types.Final Answer:
CREATE TABLE orders PARTITION BY RANGE (created_date); -> Option DQuick Check:
Correct syntax uses PARTITION BY RANGE [OK]
- Using PARTITION ON instead of PARTITION BY
- Mixing partition types (LIST or HASH) when RANGE is needed
- Omitting parentheses around column name
SELECT * FROM sales WHERE sale_year = 2023;?
CREATE TABLE sales ( id INT, sale_year INT, amount NUMERIC ) PARTITION BY LIST (sale_year); CREATE TABLE sales_2022 PARTITION OF sales FOR VALUES IN (2022); CREATE TABLE sales_2023 PARTITION OF sales FOR VALUES IN (2023); INSERT INTO sales VALUES (1, 2022, 100), (2, 2023, 200), (3, 2023, 300);
Solution
Step 1: Understand partitioning by LIST on sale_year
Tablesalesis partitioned by sale_year with partitions for 2022 and 2023.Step 2: Analyze inserted data and query
Rows with sale_year 2023 have ids 2 and 3. Query filters sale_year = 2023, so these rows are returned.Final Answer:
Rows with id 2 and 3 will be returned -> Option AQuick Check:
Query filters sale_year=2023, returns matching rows [OK]
- Assuming all rows return regardless of partition
- Confusing partition column with other columns
- Forgetting to insert data into partitions
CREATE TABLE logs (
id SERIAL,
log_date DATE
) PARTITION BY RANGE (log_date);
CREATE TABLE logs_2023 PARTITION OF logs FOR VALUES FROM ('2023-01-01') TO ('2024-01-01');Solution
Step 1: Check RANGE partition boundaries
RANGE partitions include values from FROM (inclusive) up to TO (exclusive). To cover all 2023 dates, TO must be '2024-01-01'.Step 2: Analyze given TO value
TO is '2023-12-31', which excludes that date and any after. This causes missing data for 2023-12-31.Final Answer:
The TO value should be '2024-01-01' to include all 2023 dates -> Option CQuick Check:
RANGE TO is exclusive, so use next day [OK]
- Using inclusive TO value in RANGE partitions
- Thinking RANGE partitioning disallows DATE columns
- Confusing LIST and RANGE partition syntax
events partitioned by HASH on user_id with 4 partitions. Which set of commands correctly creates the table and its partitions?Solution
Step 1: Understand HASH partition syntax
HASH partitions requireFOR VALUES WITH (MODULUS n, REMAINDER r)to define partitions.Step 2: Check each option
CREATE TABLE events (id INT, user_id INT) PARTITION BY HASH (user_id); CREATE TABLE events_p0 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 0); CREATE TABLE events_p1 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 1); CREATE TABLE events_p2 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 2); CREATE TABLE events_p3 PARTITION OF events FOR VALUES WITH (MODULUS 4, REMAINDER 3); correctly uses HASH partitioning with modulus 4 and remainders 0 to 3. CREATE TABLE events (id INT, user_id INT) PARTITION BY HASH (user_id); CREATE TABLE events_p0 PARTITION OF events FOR VALUES IN (0); CREATE TABLE events_p1 PARTITION OF events FOR VALUES IN (1); CREATE TABLE events_p2 PARTITION OF events FOR VALUES IN (2); CREATE TABLE events_p3 PARTITION OF events FOR VALUES IN (3); uses LIST syntax incorrectly. CREATE TABLE events (id INT, user_id INT) PARTITION BY LIST (user_id); CREATE TABLE events_p0 PARTITION OF events FOR VALUES IN (0); CREATE TABLE events_p1 PARTITION OF events FOR VALUES IN (1); CREATE TABLE events_p2 PARTITION OF events FOR VALUES IN (2); CREATE TABLE events_p3 PARTITION OF events FOR VALUES IN (3); uses LIST partitioning, not HASH. CREATE TABLE events (id INT, user_id INT) PARTITION BY RANGE (user_id); CREATE TABLE events_p0 PARTITION OF events FOR VALUES FROM (0) TO (1); CREATE TABLE events_p1 PARTITION OF events FOR VALUES FROM (1) TO (2); CREATE TABLE events_p2 PARTITION OF events FOR VALUES FROM (2) TO (3); CREATE TABLE events_p3 PARTITION OF events FOR VALUES FROM (3) TO (4); uses RANGE partitioning, not HASH.Final Answer:
The commands using PARTITION BY HASH (user_id) with FOR VALUES WITH (MODULUS 4, REMAINDER 0-3) -> Option BQuick Check:
HASH partitions use MODULUS and REMAINDER [OK]
- Using FOR VALUES IN instead of FOR VALUES WITH for HASH
- Mixing partition types (LIST or RANGE) with HASH
- Omitting modulus or remainder values
