CONCEPT Cited by 1 source
MySQL VARCHAR length requirement¶
MySQL VARCHAR declarations require an explicit maximum
length. Postgres allows VARCHAR without a length,
behaving like an unbounded text column. The asymmetry
surfaces immediately in any Postgres → MySQL schema
migration.
In MySQL for the
varchartype, we have to set a max value, whereas in Postgres we did not.— sources/2026-04-21-planetscale-migrating-from-postgres-to-mysql
Mechanisms¶
- MySQL —
VARCHAR(N)whereNis the max character count. If you don't know a bound, the drop-in answer isTEXT(no length, storage backed by a separate off-page region for large values). - Postgres —
VARCHARwith no length stores arbitrary- length text, up to 1 GB. The type is functionally interchangeable withTEXTin Postgres.
Migration choices¶
When moving a Postgres VARCHAR (unconstrained) column to
MySQL:
- Switch to
TEXT. Drop-in, no length guess required. Trade-off:TEXTis not directly indexable without a prefix length (see concepts/blob-text-index-prefix-requirement). - Keep
VARCHAR(N). PickNlarge enough to cover any existing row, but know that underestimating truncates data at insert time — this is a real operational hazard. - Profile actual column lengths first.
SELECT MAX(LENGTH(col))in Postgres gives an empirical upper bound before the migration.
SERIAL has a parallel pitfall¶
The PlanetScale post flags a related declarational asymmetry for integer identity columns:
If we set the
serialtype in MySQL, it'll default the underlying data type to abigint unsigned auto_increment.
Postgres's SERIAL is INTEGER-backed; MySQL's SERIAL is
a 64-bit alias. Capacity and storage footprint differ.
Related¶
- concepts/cross-engine-sql-data-type-equivalence — the umbrella concept.
- concepts/blob-text-index-prefix-requirement — the
indexing penalty for
TEXTcolumns that comes with the drop-in replacement. - systems/mysql
- patterns/cross-engine-database-migration-audit