Database Schema Designer
WebEverything runs locally in your browser — nothing is uploaded
Paste DDL on the left and you get three things on the right: 1. A relationship diagram — one box per table with primary and foreign keys marked, and foreign keys drawn as connectors; 2. The same tables in your target dialect — MySQL, PostgreSQL or SQLite, with types and auto-increment rewritten; 3. A structural check — the part worth having on its own. Why the check matters: finding these by eye across dozens of tables is hopeless, and each one is a fact: · A foreign key pointing at a table or column that does not exist (invisible in a diagram, fatal when you run the DDL); · PostgreSQL does not index foreign key columns automatically (MySQL does) — joins and parent deletes get slower; · Missing primary keys, duplicate column names, auto-increment on a non-integer type; · A column named with a SQL reserved word and not quoted (most databases refuse to parse it); · `VARCHAR` with no length (MySQL rejects it, PostgreSQL treats it as unlimited); · No `ON DELETE` clause (the default, RESTRICT, will block deleting a parent row). Conversion never drops anything silently: the type mapping is a short, explicit table, and anything that maps poorly or loses meaning (MySQL `unsigned`, `ON UPDATE CURRENT_TIMESTAMP`, `ENUM`) comes with a note. You should not discover a missing constraint months after running the output. The supported syntax is deliberately narrow: `CREATE TABLE` and `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY` only. Views, triggers and generated-column expressions are not parsed — anything unrecognised produces a “this line was skipped” warning rather than a guess (silently dropping it would leave you with a pretty diagram that is missing a table). Everything runs in your browser; nothing is uploaded.
Features
- Relationship diagram: table and column names, types, PK / FK marks, foreign-key connectors
- DDL for three dialects: MySQL, PostgreSQL and SQLite
- Type mapping: AUTO_INCREMENT → SERIAL, DATETIME → TIMESTAMP, TINYINT(1) → BOOLEAN and more
- The generated statements come in dependency order (referenced tables first), so the whole block runs
- Structural check: broken foreign keys, missing indexes, primary keys, duplicate columns, reserved words, type syntax, ON DELETE
- Findings graded error / warning / note, each naming the exact object
- Conversion notes list every lost behaviour instead of hiding it
- Lines that could not be parsed are reported, never dropped quietly
- Identifiers are quoted only when needed (reserved words or special characters)
- Ctrl / Cmd + Enter to analyse; a sample schema is preloaded
How to use
- Paste your DDL into the box (or use the preloaded sample)
- Pick a target dialect: MySQL, PostgreSQL or SQLite
- Press Analyse, or Ctrl / Cmd + Enter
- The diagram appears on the left; tables, findings and generated SQL on the right
- Use the per-row copy button to take the generated DDL
FAQ
- Which SQL syntax is supported?
- Only `CREATE TABLE` (column definitions, column- and table-level primary keys, unique, indexes, foreign keys, CHECK) and `ALTER TABLE ... ADD CONSTRAINT ... FOREIGN KEY`. Views, triggers, stored procedures, generated columns and complex `DEFAULT` expressions are not parsed — they produce a “this line was skipped” warning. Better to say nothing than to guess.
- Why does it warn about an unindexed foreign key in PostgreSQL?
- Because PostgreSQL does not index the referencing columns of a foreign key, while MySQL (InnoDB) does. Without an index, joins and parent-row deletes degrade into a scan. The warning is dialect-specific: it does not appear when MySQL is selected.
- Is the type conversion reliable? What gets lost?
- The mapping is a short, explicit table (about twenty common types) you can check against the output. Conversions that lose meaning always come with a note: `unsigned` has no PostgreSQL equivalent (the range changes), `ENUM` becomes TEXT (the allowed values are lost), and `ON UPDATE CURRENT_TIMESTAMP` needs a trigger in the target dialect. Types outside the table are kept as-is with a warning rather than guessed at.
- Can I run the generated statements?
- Yes, and they are ordered by dependency (referenced tables first), so running the whole block will not fail on a foreign key to a table that does not exist yet. Two caveats: SQLite does not enforce foreign keys unless every connection runs `PRAGMA foreign_keys = ON` (the generated SQL says so), and no data-migration logic is generated — moving existing rows is your call.
- Does it work the other way round — from a live database?
- No, there is no server here to connect to your database. But you can export DDL with `mysqldump --no-data`, `pg_dump --schema-only` or `sqlite3 .schema` and paste it in — which is the usual way this tool gets used.
Related tools
URL Parser
WebParse a URL into scheme, host, port, path, query parameters and fragment, with each parameter shown raw and decoded. Runs entirely in your browser.
User-Agent Parser
WebParse a user agent into browser, version, OS, device type and engine, and see which rules matched. Pattern matching only. Runs entirely in your browser.
HTTP Status Codes
WebLook up an HTTP status code for its meaning, 1xx–5xx class, typical uses and common traps. Runs entirely in your browser.
MIME Types
WebLook up a MIME type from an extension, or the default extension for a media type. Common types only. Runs entirely in your browser.
.gitignore Generator
WebGenerate a .gitignore from language, framework, editor and OS templates. Sections are merged and duplicates removed. Runs entirely in your browser.
Image to Base64
WebConvert an image to Base64 or a data URL by dropping, choosing or pasting it. Resize and switch format, all locally — nothing is ever uploaded.