eloquent 的 collation 属性仅在 mysql 8.0+ 和 postgresql 中影响 order by 排序,对 php 数组排序无效;mysql 依赖字段定义的 collate,postgresql 需显式指定 collation 参数。

Eloquent 的 collation 属性排序规则只在 MySQL 8.0+ 和 PostgreSQL 中生效,且仅影响查询时的 ORDER BY 行为,对 PHP 层面的数组排序完全无效。
MySQL 8.0+ 中设置字段 collation 影响 ORDER BY
MySQL 的排序行为由字段定义时的 COLLATE 决定,Eloquent 不会自动改写 SQL 的 ORDER BY 子句去套用它。真正起作用的是你显式调用 orderBy() 时,数据库按字段当前 collation 规则比较字符串。
- 确保建表时指定了语言敏感 collation,例如:
name VARCHAR(255) COLLATE utf8mb4_tr_0900_as_cs(土耳其语大小写敏感) - Laravel 迁移中可这样写:
Schema::table('users', function (Blueprint $table) { $table->string('name')->collation('utf8mb4_tr_0900_as_cs')->change(); }); - 直接查:
User::orderBy('name')->get()就会按土耳其语规则排序(如İ排在I前) - 若字段 collation 是默认的
utf8mb4_unicode_ci,orderBy('name')永远按 Unicode 码点排,和 locale 无关
PostgreSQL 中 collation 必须显式声明才生效
PostgreSQL 不从列定义继承 collation,Eloquent 的 collation 属性在这里毫无作用 —— 它既不生成 COLLATE 子句,也不修改 schema。
- 要按德语排序,必须手动写:
User::orderByRaw("name COLLATE 'de_DE.utf8'")->get() - 或在查询构造器中用
orderBy第二参数传 collation:orderBy('name', 'de_DE.utf8')(Laravel 9.21+ 支持) - 注意:PostgreSQL 的 collation 名称必须存在于系统中(
SELECT * FROM pg_collation;查看),不能随便写zh_CN或ja_JP - 若用
where条件做模糊匹配(如where('name', 'like', '%ö%')),collation 不影响匹配逻辑,只影响排序
PHP 层排序无法靠 Eloquent collation 解决
从数据库取出数据后,在 PHP 里用 collect($users)->sortBy('name') 或 usort(),结果完全取决于 PHP 的 strcmp() 或 Collator 类,和数据库 collation 零关系。
- 想实现中文拼音排序,得用:
$collator = new \Collator('zh'); $collator->asort($users); - 想让
sortBy('name')按法语规则排?不行 —— Laravel 的sortBy走 PHP 默认字节序,必须自己传Collator::sort() - Eloquent 模型里的
$casts、get*Attribute()、getAttribute()全部不触发任何 collation 行为 - 别试图在
boot()里改static::$connection的字符集,那只是连接层设置,不影响排序逻辑
真正容易被忽略的一点:MySQL 的 collation 是字段级的,但 ORDER BY 可以跨字段混用不同 collation,而 Laravel 查询构造器不提供这种能力 —— 你需要 orderByRaw 手动拼。PostgreSQL 更严格,collation 必须和字段类型兼容,否则报错 collation mismatch。
php免费学习视频:立即使用
踏上前端学习之旅,开启通往精通之路!从前端基础到项目实战,循序渐进,一步一个脚印,迈向巅峰!











