Microsoft's classic sample database, converted to SQLite. Northwind is a small company that imports speciality foods and resells them. It has customers, orders, products, suppliers, staff and sales territories, all joined by keys. Click any table to browse it, follow a key to the row it points at, or write your own query in the SQL console.
sqlite3 northwind.db. The Northwind tab of the SQLite3 guide walks through everything the database was built to teach.Each arrow runs from a foreign key (FK) to the primary key (PK) it references: from the “many” side to the “one” side. The number in each header is the table's row count.
Eight product groups, each with a bitmap picture stored as a BLOB.
Companies that buy from Northwind. A five-letter text key (ALFKI) instead of a number.
Nine staff. ReportsTo points back into the same table, which makes the org chart.
Three freight companies. Orders.ShipVia points here.
Companies Northwind buys from. Each product has exactly one supplier.
One row per order: who bought, which employee sold it, which shipper carried it.
The catalogue: price, stock on hand, stock on order and the reorder level.
The order lines. Its primary key is two columns, (OrderID, ProductID).
Four regions: Eastern, Western, Northern, Southern.
US sales territories, each in one region.
A junction table: which employee covers which sales territory (many-to-many).
Customer types. Empty in Microsoft's data, kept to show the design.
Junction table between customers and demographics. Also empty.
- Alphabetical list of products69
- Current Product List69
- Customer and Suppliers by City120
- Orders Qry830
- Products Above Average Price25
- Products by Category69
- Quarterly Orders86
- Invoices2155
- Order Details Extended2155
- Order Subtotals830
- Product Sales for 199777
- Category Sales for 19978
- Sales by Category77
- Sales Totals by Amount66
- Summary of Sales by Quarter809
- Summary of Sales by Year809
The SQL console runs whatever you type, so it is protected in four separate ways. Any one of them would be enough on its own.
- The file is opened with
mode=ro&immutable=1. SQLite opens it read-only and never takes a lock on it. PRAGMA query_only = ONmakes SQLite refuse any statement that would write.- An authorizer callback checks every statement as it is compiled. It allows only reads, function calls and a few introspection pragmas such as
PRAGMA table_info, and it refusesATTACH, so a query can't open any other file on the server. - The operating system: the web server's user account has no write permission on the file.
Each query is also stopped after 2 seconds and returns at most 500 rows, so one visitor can't tie up the server.