Skip to content

JSON to MySQL Schema Transformation — Numio

Generates MySQL CREATE TABLE statements from sample JSON. The root becomes a table named generic; each nested object or array becomes a child table with a foreign key to the parent's primary key.

Sketching a normalized table layout for an API payload before writing a real migration.

JSON

MySQL Schema

When to use it

  • Sketching a normalized table layout for an API payload before writing a real migration.
  • Seeing which nested objects and arrays in a document would need their own tables when moving data from a document store to MySQL.

How to use

  1. Paste a JSON object, or an array of sample records that are merged into one table, into the left editor, or use the load-file button to open a UTF-8 file.
  2. Read the generated tables: the root is generic, children are generic_<key>, linked by generic_id foreign keys.
  3. Copy the SQL, then rename tables and adjust column types (for example DECIMAL for prices or VARCHAR lengths) before running it.

JSON sample object

{
  "id": 1024,
  "total": 19.5,
  "coupon": null,
  "created_at": "2026-01-05T10:00:00Z",
  "scores": [4, 4.5],
  "items": [{ "sku": "A1", "qty": 2 }]
}

MySQL CREATE TABLE statements

CREATE TABLE generic (
  id INT,
  total DOUBLE,
  coupon TEXT,
  created_at TIMESTAMP,
  PRIMARY KEY (id)
);

CREATE TABLE generic_scores (
  generic_id INT,
  id INT,
  value DOUBLE,
  PRIMARY KEY (id),
  FOREIGN KEY (generic_id) REFERENCES generic(id)
);

CREATE TABLE generic_items (
  generic_id INT,
  id INT,
  sku TEXT,
  qty INT,
  PRIMARY KEY (id),
  FOREIGN KEY (generic_id) REFERENCES generic(id)
);

Details and limitations

Integers become INT (BIGINT outside the 32-bit range), other numbers DOUBLE, strings TEXT and booleans BOOLEAN. No VARCHAR lengths, NOT NULL, AUTO_INCREMENT or indexes are generated.

The primary key is a key named id or containing _id; if none exists an id column is added. Strings longer than 18 characters that parse as dates become TIMESTAMP.

null values become TEXT columns. Arrays of scalars get a child table with a value column typed from all elements (scores above is DOUBLE).

Runs in your browser; the output is not validated against a MySQL server.

FAQ

Why is a decimal value typed DOUBLE and not DECIMAL?

The sample cannot show the precision you need, so non-integer numbers become DOUBLE. Change money columns to DECIMAL(p,s) by hand.

Can I choose the table name?

No. The root table is always generic and child tables are generic_<key>. Rename them in the copied SQL.

Does it generate INSERT statements?

No, only CREATE TABLE. To turn JSON rows into INSERT statements use the JSON to SQL tool.

Specifications and references