From c6f2b0d3d9693264c5d984ccad9933be0e85728a Mon Sep 17 00:00:00 2001 From: mscherer Date: Tue, 27 Jan 2026 10:54:08 +0100 Subject: [PATCH 1/2] Remove hardcoded default collation for MySQL tables Let MySQL/MariaDB use the database default collation instead of forcing utf8mb4_unicode_ci on every table. This avoids collation mismatches on servers with different defaults (e.g. MariaDB 11.8 uses utf8mb4_uca1400_ai_ci). Users who need a specific collation can still set it explicitly in their migrations. Fixes #1010 --- docs/en/writing-migrations.rst | 3 +-- src/Db/Adapter/MysqlAdapter.php | 1 - 2 files changed, 1 insertion(+), 3 deletions(-) diff --git a/docs/en/writing-migrations.rst b/docs/en/writing-migrations.rst index 161c803d..4272fbc1 100644 --- a/docs/en/writing-migrations.rst +++ b/docs/en/writing-migrations.rst @@ -546,10 +546,9 @@ In addition, the MySQL adapter supports following options: Option Platform Description ========== ================ =========== comment MySQL, Postgres set a text comment on the table -collation MySQL, SqlServer the default collation for a table if different than the database. +collation MySQL, SqlServer set the table collation *(defaults to database collation)* row_format MySQL set the table row format engine MySQL define table engine *(defaults to ``InnoDB``)* -collation MySQL define table collation *(defaults to ``utf8mb4_unicode_ci``)* signed MySQL whether the primary key is ``signed`` *(defaults to ``false``)* limit MySQL set the maximum length for the primary key ========== ================ =========== diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php index 0873581a..f8f779ed 100644 --- a/src/Db/Adapter/MysqlAdapter.php +++ b/src/Db/Adapter/MysqlAdapter.php @@ -251,7 +251,6 @@ public function createTable(TableMetadata $table, array $columns = [], array $in // This method is based on the MySQL docs here: https://dev.mysql.com/doc/refman/5.1/en/create-index.html $defaultOptions = [ 'engine' => 'InnoDB', - 'collation' => 'utf8mb4_unicode_ci', ]; $options = array_merge( From 4b10cb155fa847fc6b98ba0b7282a5b711924e02 Mon Sep 17 00:00:00 2001 From: mscherer Date: Tue, 27 Jan 2026 11:01:12 +0100 Subject: [PATCH 2/2] Add Migrations.default_collation config option Allow configuring a global default collation for MySQL tables via Configure::read('Migrations.default_collation'). When null (default), tables inherit the database server collation. Per-table collation options still take precedence. --- config/app.example.php | 1 + src/Db/Adapter/MysqlAdapter.php | 5 +++++ 2 files changed, 6 insertions(+) diff --git a/config/app.example.php b/config/app.example.php index 3fc952b0..d5b367d9 100644 --- a/config/app.example.php +++ b/config/app.example.php @@ -9,5 +9,6 @@ 'unsigned_primary_keys' => null, // Default false 'unsigned_ints' => null, // Default false, make sure this is aligned with the above config 'column_null_default' => null, // Default false + 'default_collation' => null, // Default null (uses database collation). Set to e.g. 'utf8mb4_unicode_ci' to override. ], ]; diff --git a/src/Db/Adapter/MysqlAdapter.php b/src/Db/Adapter/MysqlAdapter.php index f8f779ed..b1d8a182 100644 --- a/src/Db/Adapter/MysqlAdapter.php +++ b/src/Db/Adapter/MysqlAdapter.php @@ -253,6 +253,11 @@ public function createTable(TableMetadata $table, array $columns = [], array $in 'engine' => 'InnoDB', ]; + $collation = Configure::read('Migrations.default_collation'); + if ($collation) { + $defaultOptions['collation'] = $collation; + } + $options = array_merge( $defaultOptions, array_intersect_key($this->getOptions(), $defaultOptions),