Guide · Doing
Design a schema change
Read this when you need a new table, column or foreign key and want to see the SQL, and the locks it takes, before anything touches the database. Design mode is Pro, works on all four engines, and runs nothing until the change has passed its checks and a dry run.
Start a design
- Press
⇧⌘Eon macOS orCtrl+Shift+Eon Windows, and pickcommerce. - Click
Design changesin the diagram's toolbar. - Click
New design for commerce.
Earlier designs are listed under Saved designs, each with Delete design, which asks first
and changes nothing in the database. The workbench shows the canvas, an inspector and the SQL
pane, and saves as you work: the toolbar says Saved.
On Free, saved designs open read-only: "Saved designs open read-only on Free. Upgrade to keep designing."
The ER diagram of the commerce schema stepping into design mode: a new table is added under orders, named, and linked to it by dragging a column.
The figure adds a reviews table and links it to orders, as the next sections do.
Add a table
- Press
T. The toolbar'sNew tablebutton does the same, and so does double-clicking empty canvas. - Type
reviewsand pressEnter.
The new table gets a primary key in the style the New table key menu beside the button names:
bigint identity key or uuid key on PostgreSQL.
Add a column
- Right-click the
reviewstable and clickAdd column. - Name it
rating. - Set its
Typein the inspector, for examplesmallint. - Tick
Required (NOT NULL).
The inspector also holds Default and Identity, and the toggles Primary key and Unique.
A Default is one expression. 0, 1, a NOT NULL outside brackets, an unclosed quote or an
unbalanced bracket is reported as a blocker, so a default can never smuggle a second clause
into the ALTER TABLE. Defaults read from the live database are left as they are.
Link two tables
- Drag the dot at the end of the
idrow inordersontoreviews. - In the
New linkpopover, chooseMany-to-one.One-to-oneandMany-to-manyare the other choices. - Set
On deletetoCascade, so a deleted order takes its reviews with it. - Click
Done.
The other On delete choices are No action, Restrict, Set null and Set default.
Undo link takes the link back.
Read the inspector
With nothing selected, the inspector describes the whole design. Changes, Blockers and
Warnings count what you've done and what's wrong with it. A blocker stops the apply. A warning
asks you to confirm it during review. Issues lists both, or says "No problems in the design."
Suggestions holds what Seqora noticed but won't insist on. A column named customer_id with no
foreign key, in a schema where customers has a key of the same type, is suggested as a link.
A Link button draws it.
Select a link to change its On delete and On update.
Read the SQL pane
The SQL pane updates with every edit and tags each statement that will hurt. On PostgreSQL:
| Tag | What the statement does | Example |
|---|---|---|
Deletes data |
Drops a table or a column. | Dropping orders.channel |
Rewrites table |
Rewrites every row. | A new column with a volatile default or an identity |
Scans table |
Reads every row to check it. | A NOT NULL column, an index, a foreign key on an existing table |
Blocks reads and writes |
Takes an ACCESS EXCLUSIVE lock. |
Most ALTER TABLE statements |
Blocks writes |
Takes a SHARE or SHARE ROW EXCLUSIVE lock. |
CREATE INDEX, a new foreign key to an existing table |
Read the tags together. A statement on commerce.orders tagged both Scans table and
Blocks reads and writes holds its lock for as long as reading 12,000,000 rows takes, and every
query on orders waits behind it.
Selection only narrows the pane to the selected table. Copy SQL copies the script.
Review and apply
- Click
Review and apply. The review opens onChecks, the first ofChecks → Dry run → Apply, under the eyebrowReview changes. - Read the checks: read-only queries for empty values, duplicates, orphan rows and dependent
objects, under
Must fix,Check before applyingandPassed and notes. - Tick
I understandon each warning you accept. - Click
Dry run. - Click the apply button. It names the count, as in
Apply 2 statements.
If the schema changed after you started, the checks say "The live schema changed since this
design started". Click Rebase onto the live schema to replay your edits on the current one.
Data checks skip tables over 5,000,000 rows, and say which: "Data checks were skipped on large
tables (commerce.orders) so the review doesn't scan millions of rows. The dry run still tests
every statement." Check them anyway includes them.
What the dry run and the apply do depends on the engine:
| Engine | Dry run | Apply |
|---|---|---|
| PostgreSQL | Runs every statement in a transaction and rolls it back, with lock_timeout at 5 seconds and statement_timeout at 120 seconds. |
One transaction, with SET LOCAL lock_timeout at 10 seconds and no statement timeout. |
| SQLite | Runs every statement in a transaction and rolls it back. | One transaction, with foreign-key enforcement off until the end, then checked. |
| MySQL, MariaDB | Replays every statement on empty copies of the tables in a scratch database, then drops it. | Each statement commits on its own. Seqora stops at the first failure. |
On a production connection, which Connect defines, the apply step asks you
to type the database name first: "This is a production connection. Type commerce to apply."
On a locked connection the checks run and the dry run waits: "This connection is locked
against writes", with an Unlock connection button.
When it's done you see Changes applied, and the catalog and diagram refresh. Save as .sql
writes the script to your SQL folder, ready to commit as a migration. The design stays as a
record that can't be edited.
Caveats
- A PostgreSQL dry run executes the real statements before rolling back, so it takes the same locks for as long as they run. Dry-run a change to a busy table when it is quiet.
- On MySQL and MariaDB, if a statement fails during apply, the ones before it stay applied. Refresh the schema and rebase the design before trying again.
- The MySQL dry run needs
CREATEonseqora_scratch_%databases. Without it Seqora checks only the syntax, and says "Only the syntax was checked". - Seqora only applies statements the designer generated. There is no field for hand-written DDL. Run that from Run, cancel, and transactions.
- Expression and partial indexes and generated columns are kept as they are.
- The tag examples above are PostgreSQL's. Each engine's DDL generator sets its own tags, so the same drawing can carry different ones on MySQL, MariaDB or SQLite.