---
title: "MariaDB to SQLite data types"
description: "Every MariaDB data type that SQLite stores differently, what the converter writes for it, when, and the report line."
canonical: https://intosql.com/docs/types/mariadb-to-sqlite
last_updated: 2026-10-15
---

# MariaDB to SQLite data types

Each row is a type from MariaDB that SQLite stores differently: what the SQLite script gets, why, and the line the report writes about it. The rows come from the converter's own rules, so this page matches what it does.

**Convert in the browser:** [MariaDB to SQLite](/mariadb-to-sqlite) opens the converter set up for this pair. The [MariaDB to SQLite migration guide](/docs/migrations/mariadb-to-sqlite) covers dumping, loading and the rules for keys, indexes and names.

A report line is a fix when the converter changed something and lists it, or a problem when a value or object is worth a look.

## Numbers

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| UNSIGNED integers | INTEGER with a CHECK that it isn't negative; BIGINT UNSIGNED holding values above 2^63-1 is TEXT | SQLite integers are 64-bit and signed. The check keeps negative values out as MySQL did; values past the signed range are kept as text so no digit is lost. | `unsigned_widened` (fix) |
| ZEROFILL and display widths | dropped | Zero padding is a way of showing a number, not part of it. The numbers are kept; format them when you read them if the padding matters. | `zerofill_dropped` (fix) |
| FLOAT(M,D) | REAL, without the scale | SQLite floats have no fixed scale. The stored values are copied as they are. | `float_scale_dropped` (fix) |
| DECIMAL(p,s) | DECIMAL(p,s) up to 15 digits; TEXT beyond | SQLite keeps about 15 significant digits in a number. Wider decimals are kept as text so every digit stays exact. | `decimal_as_text` (fix) |

## Booleans and bits

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| TINYINT(1), BOOL | INTEGER with the values as they are | SQLite has no boolean type; true and false are the integers 1 and 0, so every value keeps its meaning. | None |
| BIT(1), BIT(n) | INTEGER with the bits' value; BIT(64) as TEXT digits | A bit field is stored as the number its bits make. The top bit of a BIT(64) doesn't fit a signed integer, so its number is kept as text. | None |

## Text

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| CHAR(n), VARCHAR(n) | VARCHAR(n), not enforced | SQLite keeps the declared type for tools to read but doesn't limit the length; the values are the ones MySQL returns. | None |
| NUL bytes in text | kept | SQLite text can hold a NUL byte, so the value is copied as it is. | None |
| text that isn't valid in its character set | the bad bytes as the replacement character | SQLite text is UTF-8; its functions misread bytes that aren't. | `invalid_utf8_replaced` (problem) |

## Enums and sets

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| ENUM | TEXT with a CHECK of its values | Text with a check keeps the same values. | None |
| ENUM holding '' (MySQL's error value) | the empty value allowed by the check | MySQL stores an empty string when an invalid value goes into an ENUM in a lenient SQL mode. Those rows are kept and the check allows them. | `enum_invalid_value` (fix) |
| ENUM holding values outside its list | no CHECK | Values the list doesn't name would fail the check, so the check isn't created. | `enum_check_skipped` (problem) |
| SET | TEXT as MySQL writes it ('a,b') | SQLite has no arrays; the text is the one MySQL returns. | None |

## Dates and times

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| zero, partial or impossible dates (0000-00-00, 2024-02-30) | NULL | SQLite's date functions only read real calendar dates. They become NULL and the report counts them, as for every other database. | `invalid_date_null` (problem) |
| DEFAULT '0000-00-00' | no default | A default that isn't a real date is left out rather than replaced with a made-up one. | `zero_date_default` (fix) |
| TIME | TIME text as MySQL writes it, durations included | SQLite keeps times as text, so durations past a day or below zero are kept exactly. | None |
| YEAR | INTEGER with a CHECK of its range | SQLite has no year type; the check keeps the same values MySQL allows. | None |
| DATETIME | DATETIME as ISO 8601 text | SQLite stores dates as text its date functions read. | None |
| TIMESTAMP | TIMESTAMP as ISO 8601 text in UTC; the zone the dump states, UTC when it states none | A TIMESTAMP is a moment, written in UTC. Dumps state the zone they wrote it in (mysqldump writes UTC); without that, the values are read as UTC and the report says so. | `timestamp_zone_assumed` (problem) |

## Binary

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| BINARY, VARBINARY, BLOB | BLOB | Bytes stay bytes. | None |

## JSON, spatial and other types

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| JSON | TEXT | SQLite's JSON functions read JSON from text. A column declared JSON would turn "123" into a number, so it is TEXT. | None |
| GEOMETRY, POINT, POLYGON... | WKB in a BLOB | The standard well-known binary keeps every geometry exactly. | `geometry_as_blob` (fix) |
| INET4, INET6, UUID (MariaDB) | TEXT | SQLite has no such types; the text is the one MariaDB returns. | None |
| geometries in a dump without CREATE TABLE | WKB in a BLOB | MySQL's geometry format is recognised from the values and stored as standard WKB. | `geometry_as_blob` (fix) |
| types IntoSQL doesn't know | TEXT | Text holds any value; change the type after loading. | `unknown_type` (problem) |
| values that don't fit their column | NULL | A damaged or hand-written dump can hold values its column can't; they become NULL so the rest loads. | `invalid_value_null` (problem) |
| unreadable geometries | NULL | Bytes that aren't a geometry can't be stored as one. | `bad_geometry` (problem) |
| VECTOR(n) (MariaDB 11.7+) | TEXT with the floats as a JSON array | SQLite has no vector type; a JSON array keeps every float. | `type_replaced` (fix) |

## Counters and identities

| In MariaDB | In SQLite | Why | Report line |
| --- | --- | --- | --- |
| AUTO_INCREMENT | INTEGER PRIMARY KEY AUTOINCREMENT, with the counter set past the copied ids | SQLite counts a whole integer primary key. AUTOINCREMENT keeps ids from being reused, as MySQL does, and the counter continues after the highest id or the dump's AUTO_INCREMENT, whichever is higher. | None |
| AUTO_INCREMENT on part of a key or outside one | INTEGER without a counter | SQLite only counts a column that is the whole primary key, so the column keeps its values and new rows need theirs. | `identity_without_counter` (problem) |

## Other pairs

- MariaDB into [PostgreSQL](/docs/types/mariadb-to-postgresql), [MySQL](/docs/types/mariadb-to-mysql), [MariaDB](/docs/types/mariadb-to-mariadb), [SQL Server](/docs/types/mariadb-to-sql-server), [Oracle](/docs/types/mariadb-to-oracle)
- Into SQLite from [MySQL](/docs/types/mysql-to-sqlite), [PostgreSQL](/docs/types/postgresql-to-sqlite), [SQL Server](/docs/types/sql-server-to-sqlite), [SQLite](/docs/types/sqlite-to-sqlite), [Oracle](/docs/types/oracle-to-sqlite)
- [Every pair](/docs/types#from-one-database-to-another)
