如何使用 Doctrine 更改列字符集和排序规则?

Posted

技术标签:

【中文标题】如何使用 Doctrine 更改列字符集和排序规则?【英文标题】:How to change column charset and collation with Doctrine? 【发布时间】:2020-01-13 10:27:15 【问题描述】:

我正在开发一个 Symfony 3.4 项目,我希望表格的某些列使用字符集 utf8mb4。这背后的目的是允许表情符号。

这是我的 Doctrine 实体的摘要:

/**
 * @ORM\Table(name="categories")
 */
class Category 
    // ...

    /**
     * @var string
     * @ORM\Column(name="description", type="string", length=255)
     */
    private $description;

我首先更新了学说配置:

doctrine:
  charset: utf8mb4

然后,我更新了字段category.description的Doctrine配置:

-    * @ORM\Column(name="description", type="string", length=255)
+    * @ORM\Column(name="description", type="string", length=191, options="charset"="utf8mb4")

请注意,我将长度从 255 更改为 191,因为 utf8mb4 使用 4 个字节而不是 utf8 的 3 个字节。

最后,我运行了更新命令:

bin/console doctrine:schema:update --dump-sql

返回的内容:

ALTER TABLE categories CHANGE description description VARCHAR(191)  NOT NULL;

如您所见,没有关于 charset 的更新。此外,我们可以看到关键字VARCHAR(191)NOT 之间有一个双空格,假设这里应该有一些东西。 我期望的查询是这样的:

ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;

然后我运行更新命令:

bin/console doctrine:schema:update --force

但是当我重新运行--dump-sql 命令时,它会一遍又一遍地返回相同的查询(带有双空格)。

即使我手动将列的字符集设置为utf8mb4,查询仍然相同。

我使用的是doctrine/orm 的 v2.6.3。

我是否遗漏了配置中的某些内容? Doctrine 是否处理列字符集?

This 没有回答我的问题,因为它是关于更改 all 表的排序规则。就我而言,我想更改特定表的单个列的排序规则。

【问题讨论】:

Doctrine won't do this for you. 如果 Doctrine 不为我这样做,"charset"="utf8mb4" 的选项是什么? doctrine-project.org/projects/doctrine-orm/en/latest/reference/… 这能回答你的问题吗? Doctrine2: How to set all tables to collate with UTF8 并非如此。 This 是关于更改 all 表的排序规则。就我而言,我想更改特定表的单个列的排序规则。 【参考方案1】:

简答

Doctrine won't do this for you.

替代解决方案

使用DoctrineMigrationBundle 允许在纯 SQL 中创建迁移。因此,您可以编辑自动生成的迁移以在所需列上添加字符集/排序规则。

生成一个新的空白迁移:

bin/console doctrine:migrations:generate

然后,添加ALTER 语句:

use Doctrine\DBAL\Schema\Schema;
use Doctrine\Migrations\AbstractMigration;

final class Version20200113131732 extends AbstractMigration 
    public function up(Schema $schema) : void 
        $this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(191) COLLATE utf8mb4_unicode_ci NOT NULL;');
    

    public function down(Schema $schema) : void 
        $this->addSql('ALTER TABLE categories MODIFY `description` VARCHAR(255) COLLATE utf8_unicode_ci NOT NULL;');        
    

最后,只需运行迁移:

bin/console doctrine:migrations:migrate

【讨论】:

【参考方案2】:

看起来教义部分支持更改列排序规则(仅 Drizzle、mysql、PostgreSQL>=9.1、Sqlite 和 SQLServer 支持)。

见doctrine annotations reference

    /**
     * @ORM\Table(name="categories")
     */
    class Category 
        // ...
    
        /**
         * @var string
         * @ORM\Column(name="description", type="string", length=255, options="collation"="ascii_general_ci")
         */
        private $description;
    

【讨论】:

以上是关于如何使用 Doctrine 更改列字符集和排序规则?的主要内容,如果未能解决你的问题,请参考以下文章

更改列排序规则 - 安全吗?

Symfony 和 Doctrine 使迁移无效

如何在不转换列的情况下更改 MySQL 中的表(默认)排序规则[重复]

在 SQL 2005 中更改聚集索引列的排序规则

更改列排序规则

powerbi 怎么指定排序规则