Use this file to discover all available pages before exploring further.
Tables are the fundamental building blocks of relational databases. They store your data in rows and columns, similar to spreadsheets but with powerful querying and relationship capabilities.
create table movies ( id bigint generated by default as identity primary key, name text not null, description text, release_year integer, rating numeric(3,1), created_at timestamptz default now());
create table if not exists movies ( id bigint generated always as identity primary key, name text not null, description text, release_year integer check (release_year > 1800), rating numeric(3,1) check (rating >= 0 and rating <= 10), created_at timestamptz default now());
-- Create the parent tablecreate table categories ( id bigint generated always as identity primary key, name text not null);-- Create the child table with foreign keycreate table products ( id bigint generated always as identity primary key, name text not null, category_id bigint references categories(id) on delete cascade);
-- Create the main tablescreate table movies ( id bigint generated by default as identity primary key, name text not null);create table actors ( id bigint generated by default as identity primary key, name text not null);-- Create a junction tablecreate table movie_actors ( movie_id bigint references movies(id) on delete cascade, actor_id bigint references actors(id) on delete cascade, role text, primary key (movie_id, actor_id));
insert into movies (name, description, release_year, rating)values ( 'The Matrix', 'A computer hacker learns about the true nature of reality.', 1999, 8.7);
create view movie_ratings as select m.name, m.release_year, m.rating, c.name as category from movies m left join categories c on m.category_id = c.id where m.rating >= 8.0;-- Query the viewselect * from movie_ratings;
Materialized views cache query results for better performance:
create materialized view product_stats as select category_id, count(*) as total_products, avg(price) as average_price, sum(quantity) as total_inventory from products where deleted_at is null group by category_id;-- Refresh the materialized viewrefresh materialized view product_stats;
-- Change data typealter table moviesalter column rating type numeric(4,2);-- Add NOT NULL constraintalter table moviesalter column name set not null;-- Drop NOT NULL constraintalter table moviesalter column description drop not null;
Here’s a real table from the Supabase source code:
-- Error tracking table with soft deletescreate table content.error ( code text not null, service uuid not null references content.service(id) on delete restrict, http_status_code smallint, message text, created_at timestamptz default now(), updated_at timestamptz default now(), deleted_at timestamptz default null, primary key (service, code));-- Enable row level securityalter table content.error enable row level security;-- Create index for non-deleted recordscreate index idx_content_error_service_code_nondeleted_only on content.error (service, code) where deleted_at is null;-- Create policy for authenticated userscreate policy content_error_authenticated_select_all on content.error for select to authenticated using (deleted_at is null);