DVD Rental Database ER Diagram
The DVD Rental database is the PostgreSQL tutorial's sample schema: a DVD store where films are stocked as inventory per store, customers rent inventory, staff process rentals, and payments record each charge. Fifteen tables are mapped above, from actor and category through film, inventory, rental, payment, and the staff/store geography chain. One detail worth knowing: the tutorial dump is a simplified variant - the store relationships (customer, inventory, and staff each belong to a store) exist as columns but carry no foreign-key constraints in the file, so they are restored here to match the official ER diagram.
Last updated: 2026-09-27
Source: DVD Rental sample database (postgresqltutorial.com), plain-SQL dump via neondatabase/postgres-sample-dbs · License: MIT
Tables in the DVD Rental schema
| Column | Type | Nullable | Key |
|---|---|---|---|
| customer | |||
| customer_id | integer | No | PK |
| store_id | smallint | No | - |
| first_name | character varying(45) | No | - |
| last_name | character varying(45) | No | - |
| character varying(50) | Yes | - | |
| address_id | smallint | No | - |
| activebool | boolean | No | - |
| create_date | date | No | - |
| last_update | timestamp without time zone | Yes | - |
| active | integer | Yes | - |
| actor | |||
| actor_id | integer | No | PK |
| first_name | character varying(45) | No | - |
| last_name | character varying(45) | No | - |
| last_update | timestamp without time zone | No | - |
| category | |||
| category_id | integer | No | PK |
| name | character varying(25) | No | - |
| last_update | timestamp without time zone | No | - |
| film | |||
| film_id | integer | No | PK |
| title | character varying(255) | No | - |
| description | text | Yes | - |
| release_year | public.year | Yes | - |
| language_id | smallint | No | - |
| rental_duration | smallint | No | - |
| rental_rate | numeric(4,2) | No | - |
| length | smallint | Yes | - |
| replacement_cost | numeric(5,2) | No | - |
| rating | public.mpaa_rating | Yes | - |
| last_update | timestamp without time zone | No | - |
| special_features | text[] | Yes | - |
| fulltext | tsvector | No | - |
| film_actor | |||
| actor_id | smallint | No | PK |
| film_id | smallint | No | PK |
| last_update | timestamp without time zone | No | - |
| film_category | |||
| film_id | smallint | No | PK |
| category_id | smallint | No | PK |
| last_update | timestamp without time zone | No | - |
| address | |||
| address_id | integer | No | PK |
| address | character varying(50) | No | - |
| address2 | character varying(50) | Yes | - |
| district | character varying(20) | No | - |
| city_id | smallint | No | - |
| postal_code | character varying(10) | Yes | - |
| phone | character varying(20) | No | - |
| last_update | timestamp without time zone | No | - |
| city | |||
| city_id | integer | No | PK |
| city | character varying(50) | No | - |
| country_id | smallint | No | - |
| last_update | timestamp without time zone | No | - |
| country | |||
| country_id | integer | No | PK |
| country | character varying(50) | No | - |
| last_update | timestamp without time zone | No | - |
| inventory | |||
| inventory_id | integer | No | PK |
| film_id | smallint | No | - |
| store_id | smallint | No | - |
| last_update | timestamp without time zone | No | - |
| language | |||
| language_id | integer | No | PK |
| name | character(20) | No | - |
| last_update | timestamp without time zone | No | - |
| payment | |||
| payment_id | integer | No | PK |
| customer_id | smallint | No | - |
| staff_id | smallint | No | - |
| rental_id | integer | No | - |
| amount | numeric(5,2) | No | - |
| payment_date | timestamp without time zone | No | - |
| rental | |||
| rental_id | integer | No | PK |
| rental_date | timestamp without time zone | No | - |
| inventory_id | integer | No | - |
| customer_id | smallint | No | - |
| return_date | timestamp without time zone | Yes | - |
| staff_id | smallint | No | - |
| last_update | timestamp without time zone | No | - |
| staff | |||
| staff_id | integer | No | PK |
| first_name | character varying(45) | No | - |
| last_name | character varying(45) | No | - |
| address_id | smallint | No | - |
| character varying(50) | Yes | - | |
| store_id | smallint | No | - |
| active | boolean | No | - |
| username | character varying(16) | No | - |
| password | character varying(40) | Yes | - |
| last_update | timestamp without time zone | No | - |
| picture | bytea | Yes | - |
| store | |||
| store_id | integer | No | PK |
| manager_staff_id | smallint | No | - |
| address_id | smallint | No | - |
| last_update | timestamp without time zone | No | - |
Frequently asked questions
What tables are in the DVD Rental database?
The DVD Rental sample database has 15 tables: actor, film, film_actor, film_category, category, language, inventory, store, staff, customer, address, city, country, rental, and payment.
How do films become rentals in the DVD Rental schema?
A film title is stocked as physical inventory rows per store. A rental links one inventory item to one customer and the staff member who processed it, and each rental can produce a payment row. So the path is film -> inventory -> rental -> payment.
Where can I download the DVD Rental sample database?
From postgresqltutorial.com (as a pg_restore archive) or as plain SQL from the neondatabase/postgres-sample-dbs repository on GitHub, which is the source used for this diagram.
Explore more schemas
Visualize your own database
Paste your PostgreSQL connection string and get an interactive ER diagram of your own schema in under 10 seconds. No signup required.
Try it free →