Relational databases that you design without SQL

Design your tables, their fields, and the links between them in a visual editor, while a managed Postgres or SQLite engine stores, indexes, and checks every row.

A database engine behind a visual editor

The views, fields, and sync in Tables all work on the databases that you create here. A managed Postgres or SQLite engine stores each database, so your team edits its records in an interface that looks like a spreadsheet while the engine indexes the columns and plans each query. In the visual editor, your team can define tables, set field types, and link related tables without writing SQL. A team whose spreadsheet tool slows down as its records grow can move those records into Tables and keep working in the same kind of grid, because Postgres or SQLite stores the rows underneath.

Create a production database without writing SQL

The steps below take an empty database to a shared one that contains your existing records, links its tables, and shows each person the rows that their role allows.

What you can set up in a Tables database

If you set up a Postgres database by hand, someone on your team will have to write SQL, manage migrations, and configure indexes. As a result, colleagues who don't write SQL will have to ask an engineer for every change to the structure of a table.

Define tables, fields, and the relationships between them in a visual editor, where you can add a text field, a date field, or a link to another table with a click. Tables turns each choice that you make there into a Postgres or SQLite structure, so the engine enforces your field types and constraints from the first row onward.

When you keep orders, invoices, and support tickets in separate sheets, each sheet will need its own copy of the customer's name. If someone corrects that name in one sheet, the other copies will go on showing the old one. A formula that refers to another sheet can also break whenever someone moves a column.

A relation field connects a customer record to that customer's orders, invoices, and support tickets in other tables. Lookup fields display values from those linked rows, so Tables stores the customer's name once and shows it on every order. Rollup fields calculate figures from the linked records, such as a customer's total order value, number of open tickets, and average response time, which Tables recalculates whenever a linked record changes.

A spreadsheet tool can limit how many rows a sheet holds, so a table that keeps growing will eventually reach that limit. At that point, you will have to move the data into a database and set up your team's forms and reports again.

Tables places no artificial cap on the rows in a database, because a managed Postgres or SQLite engine stores the rows, indexes them, and optimizes each query. The interface that your team uses looks the same at 500 rows as it does at 500,000.

Row-level permissions illustration

When you share a spreadsheet, the other person can usually open the whole sheet, so a manager who needs the rows for one region can open the rows for every region too. You can work around that by giving each team a filtered copy, but each copy will then hold its own version of every value that changes.

Choose which rows each person or team can open and edit, so that a sales rep can open their own deals, a regional manager can open the deals for that region, and an executive can open the whole pipeline. Tables builds these permissions on the roles that you already set in Teams, so you keep one set of roles for both your workspace and your data.

Import, export, and API access illustration

Before your team can use a new database, someone will have to bring in records from CSV exports, spreadsheets, and older databases, each with its own field names and date formats. That person will have to match every column to the new fields and remove the duplicates that appear in more than one export. Afterward, whenever someone builds a report from that data, they will have to export it again.

When you import a CSV file or a spreadsheet export, Tables matches each source column to a field and flags the duplicates that it finds. You can export a database as CSV, JSON, or a standard database format for a report, a backup, or a migration. Through the Tables API, other software can fetch and update your records, so the same database can store the data for your Builder apps, your automation workflows, and the outside systems that you connect.

What your team gains from one database

Room to grow without moving your data

Tables stores your data on Postgres or SQLite from the first row that you enter, so your team can keep the same database as a table grows from hundreds of rows to hundreds of thousands.

Data modeling without SQL

Colleagues who don't write SQL can define tables, set relationships, and configure fields in the visual editor. Your engineers can then keep their time for larger design decisions, because anyone on the team can add a date field.

One database with access by row

Because Tables controls access row by row, your whole organization can work in one database while each team opens the rows for its own work.

Every connected tool works from the same records

Through the API and the import and export tools, your Builder apps, automation workflows, and outside systems all work from the same database, so you keep each record in one place.

Databases in practice

Filters slow down at 40,000 rows

A 30-person company keeps its customer accounts, deals, and support tickets in one spreadsheet tool. At 40,000 rows, each filter takes several seconds while the lookups between linked records begin to time out. The operations lead therefore moves the data into Tables, which maps each field during the import and keeps the relations, lookups, and rollups that the team already uses.

Result

The team works in a grid that looks like its old sheet, while Postgres indexes the columns that each filter uses so that the filters stay fast at 40,000 rows. Because Tables sets no row cap, the operations lead can keep adding records to the same database as the company grows.

Filters slow down at 40,000 rows

One district, 12 campuses, one enrollment database

A school district tracks student enrollment, teacher assignments, and classroom allocations for its 12 campuses in one database. Tables uses row-level permissions to give each campus administrator the rows for their own campus, while the district office can open every row. Relation fields link each student to their teachers, classrooms, and course schedule. From those links, Tables calculates each campus's total enrollment, its ratio of students to teachers, and its free classroom capacity in rollup fields.

Result

The district office sees each campus's changes in the shared database as soon as an administrator saves them, so the office stops collecting enrollment numbers from 12 spreadsheets by email each week. Because each administrator can edit only their own campus's rows, an administrator's mistake can affect only the records of their own campus.

One district, 12 campuses, one enrollment database

Consulting firm tracks every client in one portfolio

A consulting firm tracks its projects, deliverables, time entries, and client feedback in Tables. A relation field links each project to the client's record in People, while rollup fields on the client row total the billable hours, list the outstanding deliverables, and average the satisfaction scores. Each project manager opens their own projects, whereas the partners open the whole portfolio. At the end of each month, Wallet fetches the time entries through the Tables API to prepare the invoices.

Result

Wallet takes the hours and the deliverable status straight from Tables, so the billing team stops copying time entries into each invoice. The partners can check every project on the client rollups, which means that they stop asking each project manager for a status report.

Consulting firm tracks every client in one portfolio

Design a database that grows with your records

Lay out your tables in a visual editor while a managed Postgres or SQLite engine stores and indexes every row.