Published: 2026-06-14
Migrate SQL Server to MySQL
Jam SQL Studio migrates SQL Server tables to MySQL — schema and data — from the Object Explorer. Right-click a table or database, point it at a MySQL (or MariaDB) connection, and Jam translates the types into MySQL's dialect, copies the rows, and verifies the counts. The headline translations: bit → tinyint(1), uniqueidentifier → char(36), datetime2 → datetime, nvarchar(max) → text, and IDENTITY → AUTO_INCREMENT.
The workflow — connect both, right-click Migrate Table to Connection…, Preview, Migrate — is shared across pairs; see the cross-engine workflow. This is the less common direction (most teams move onto PostgreSQL), but the canonical type model runs the same way; below is what's specific to SQL Server → MySQL.
SQL Server → MySQL type mapping
| SQL Server | MySQL | Note |
|---|---|---|
bit | tinyint(1) | MySQL's idiomatic boolean |
tinyint | tinyint | Note: SQL Server tinyint is unsigned 0–255; MySQL tinyint is signed |
smallint / int / bigint | smallint / int / bigint | |
real | float | |
float | double | |
decimal(p,s) / numeric(p,s) | decimal(p,s) | Exact |
money | decimal(19,4) | The money spelling is lost; value preserved |
smallmoney | decimal(10,4) | |
char(n) / nchar(n) | char(n) | |
varchar(n) / nvarchar(n) | varchar(n) | |
varchar(max) / nvarchar(max) / text / ntext | text | Unbounded character data |
binary / varbinary | binary / varbinary | |
varbinary(max) / image | blob | Unbounded binary |
uniqueidentifier | char(36) | Gotcha: no native UUID; stored as text |
date / time | date / time | |
datetime / datetime2 / smalldatetime | datetime | Tz-less |
datetimeoffset | timestamp | Lossy: MySQL has no tz-aware type — offset dropped |
xml, sql_variant, hierarchyid, spatial | carried verbatim + warning | No canonical equivalent |
SQL Server → MySQL gotchas
uniqueidentifier→char(36). MySQL has no UUID type. The GUID lands as readable 36-character text. For a smaller footprint, switch tobinary(16)withUUID_TO_BIN()after migrating — butchar(36)is the safe default.tinyintsign flips. SQL Servertinyintis unsigned (0–255); MySQLtinyintis signed (−128–127). Values above 127 needtinyint unsignedon the MySQL side — check the source range if you used the high end.datetimeoffsetloses its offset. MySQL has no timezone-aware datetime, so the offset is dropped. If timezone fidelity matters, store the UTC instant plus a separate offset column.- Schemas become databases. SQL Server's
schema.tabletwo-part naming has no direct MySQL analogue (MySQL's "schema" is the database). The table lands in the target database you pick; objects that referenceddbo.explicitly need those references dropped. - Case sensitivity depends on the platform. MySQL table-name case sensitivity follows
lower_case_table_namesand the host filesystem — a detail that doesn't exist in SQL Server. Pick a casing convention before migrating a large schema.
What stays manual
Tables, types, constraints, indexes, and data migrate automatically. T-SQL procedural code does not translate to MySQL's stored-program dialect: views, stored procedures, functions, and triggers are a manual port. Run a cross-engine Schema Compare after migrating to get the by-name inventory of what's missing on MySQL, then rewrite each in MySQL's syntax (which, like the PostgreSQL case, differs from T-SQL in variables, error handling, and built-in functions).
Frequently asked questions
How does SQL Server bit map to MySQL?
A SQL Server bit becomes a MySQL tinyint(1), which is MySQL's idiomatic boolean, and the 0/1 values carry across directly. Both engines store the boolean as a one-byte integer, so this is a faithful, lossless mapping.
What happens to uniqueidentifier when migrating to MySQL?
MySQL has no native UUID type, so a SQL Server uniqueidentifier maps to char(36) and the GUID is stored as its 36-character text form. If storage size matters you can switch to binary(16) on the MySQL side and convert with UUID_TO_BIN, but char(36) is the readable, drop-in default Jam emits.
Does IDENTITY become AUTO_INCREMENT in MySQL?
Yes. A SQL Server IDENTITY column becomes a MySQL AUTO_INCREMENT column, and after the rows are copied the auto-increment counter is set to continue past the highest migrated id. MySQL allows one AUTO_INCREMENT column per table and it must be a key, which matches the usual IDENTITY primary-key pattern.
Related guides
- Cross-engine database migration — the overview and full workflow.
- Migrate SQL Server to PostgreSQL — the most common direction, with the deepest guide.
- Migrate MySQL to PostgreSQL
- Migrate SQL Server to PostgreSQL the interactive way — the same right-click → preview → migrate workflow (shown for a PostgreSQL target, identical for a MySQL one).
- Cross-engine Schema Compare — scope the manual port.
Jam SQL Studio