Free tool

MongoDB schema → SQL DDL

Paste documents from any collection. Get the inferred columns, the type mapping, and a CREATE TABLE statement for your target database — using the same inference engine that runs a real migration.

Your documents
A JSON array, one object, or one object per line — whatever mongoexport gave you.
CREATE TABLE
CREATE TABLE "users" (
  id VARCHAR(24) NOT NULL PRIMARY KEY,
  address JSONB NOT NULL,
  age DOUBLE PRECISION NOT NULL,
  email TEXT NOT NULL,
  lastseen TEXT,
  orders JSONB NOT NULL,
  signedupat TIMESTAMPTZ NOT NULL,
  tags JSONB,
  teamid VARCHAR(24) NOT NULL
);
Inferred fields — 9 columns from 2 documents
FieldColumnBSON typeSQL typeNullable
_idPKidobjectIdVARCHAR(24)no
addressaddressobjectJSONBno
ageageint, doubleDOUBLE PRECISIONno
emailemailstringTEXTno
lastSeenlastseennullTEXTyes (100% empty)
ordersordersarrayJSONBno
signedUpAtsignedupatdateTIMESTAMPTZno
tagstagsarrayJSONByes (50% empty)
teamIdteamidobjectIdVARCHAR(24)no

The table above is the faithful copy: one column per field, nested structures as JSON. That is what a migration writes today.

Proposed relational model

A faithful copy is not a relational schema. Here is the structure hiding inside these documents — which nested parts deserve their own tables, which flatten into columns, and which really are just JSON.

addressFlatten to columns
embedded object · in 100% of documents

A consistently-shaped embedded object. Flattening it into prefixed columns makes the fields directly queryable and indexable, with no join.

address_city TEXT
address_street TEXT
ordersChild table
object array · in 100% of documents · 1.5 elements avg

Repeating subdocuments with a consistent shape. This is a one-to-many relationship: a child table with a foreign key back to the parent is the relational form.

→ table orders (price, qty, sku)
tagsKeep as JSON
scalar array · in 50% of documents · 2.0 elements avg

An array of scalars has no internal structure to normalise. Keep it as JSON, or split it into a child table later if you need to query the elements individually.

Foreign key candidates
teamid→ teamshighHolds an ObjectId in every sampled document, which in MongoDB almost always points at another collection.

This analysis is advisory today — a migration still writes the flat table above. Running it against your real collection samples 500 documents instead of the handful you pasted, which is what makes the shape and frequency numbers meaningful. Connect a database →

Run it against your real database

NoSQLSync samples your collections, infers the schema, and migrates the data with live CDC. Free plan, no credit card.

Start free →