0

ウェブサイトに flourishlib を使用しています。私のクライアントは、携帯電話で絵文字を使用できるようにすることを要求しました。理論的には、MySQL データベースの文字エンコーディングを utf8 から utf8mb4 に変更する必要があります。

ここまではとても良いですが、次のように切り替えると、次のようになります。

# For each database:
ALTER DATABASE database_name CHARACTER SET = utf8mb4 COLLATE utf8mb4_unicode_ci;
# For each table:
ALTER TABLE table_name CONVERT TO CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# For each column:
ALTER TABLE table_name CHANGE column_name column_name VARCHAR(191) CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
# (Don’t blindly copy-paste this! The exact statement depends on the column type, maximum length, and other properties. The above line is just an example for a `VARCHAR` column.)

この場合、各文字は 3 バイトではなく 4 バイトを使用します。これにより、データベースのサイズが 33% 増加します。これにより、パフォーマンスが低下し、より多くのストレージ スペースが使用されます。そのため、特定のテーブルの特定の列のみを utf8mb4 のエンコーディングに切り替えることにしました。

すべてが正しいことを確認するために、いくつかのことを確認しました。その中で、flourishlib を調べたところ、疑わしい部分がいくつか見つかりました。

  1. utf8mb4 をサポートしていないように見える fUTF8 クラスがあります。

  2. fDatabase で、いくつかの調査結果を引用しています。

    if ($this->connection && function_exists('mysql_set_charset') && !mysql_set_charset('utf8', $this->connection)) {
        throw new fConnectivityException(
            'There was an error setting the database connection to use UTF-8'
        );
    }
    //...
    // Make MySQL act more strict and use UTF-8
    if ($this->type == 'mysql') {
        $this->execute("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'");
        $this->execute("SET NAMES 'utf8'");
        $this->execute("SET CHARACTER SET utf8");
    }
    
  3. fSQLSchemaTranslation でこれを見ることができます:

    $sql = preg_replace('#\)\s*;?\s*$#D', ')ENGINE=InnoDB, CHARACTER SET utf8', $sql);
    

私は、いくつかのテーブルのいくつかの列に utf8mb4 の文字エンコーディングを持たせるという私たちの探求を、flolishlib がサポートしないのではないかと疑っています。これをサポートするために何かをアップグレードできないかと思います。最悪のシナリオとして、utf8 のすべてのテキストを utf8mb4 にオーバーライドできます。しかし、それは非常に醜いハックであり、より良い解決策があるかどうか疑問に思っています. このハックを作成する必要がありますか、それとももっと正統なアプローチがありますか?

4

2 に答える 2

1

問題を解決しました。次のように、列の文字セットと照合順序を変更して、絵文字をサポートしたいテーブルを変更しました。

ALTER TABLE table_name CHANGE column_name column_name text CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;

その後、flourishlib が絵文字をサポートできるようにするために、いくつかの醜いハックを行わなければなりませんでした。

fDatabase.php :

685行目:

        if ($this->connection && function_exists('mysql_set_charset') && !mysql_set_charset('utf8mb4', $this->connection)) {
            throw new fConnectivityException(
                'There was an error setting the database connection to use UTF-8'
            );
        }

行 717 は同じままです。この行が変更されると、すべてがクラッシュします。

if ($this->connection && function_exists('mysqli_set_charset') && !mysqli_set_charset($this->connection, 'utf8')) {

800行目:

    // Make MySQL act more strict and use UTF-8
    if ($this->type == 'mysql') {
        $this->execute("SET SQL_MODE = 'REAL_AS_FLOAT,PIPES_AS_CONCAT,ANSI_QUOTES,IGNORE_SPACE'");
        $this->execute("SET NAMES 'utf8mb4'");
        $this->execute("SET CHARACTER SET utf8mb4");
    }

fSQLSchemaTranslation.php :

1554行目:

$sql = preg_replace('#\)\s*;?\s*$#D', ')ENGINE=InnoDB, CHARACTER SET utf8mb4', $sql);

fXML.php :

403行目:

    if (preg_replace('#[^a-z0-9]#', '', strtolower($encoding)) == 'utf8mb4') {
        // Remove the UTF-8 BOM if present
        $xml = preg_replace("#^\xEF\xBB\xBF#", '', $xml);
        fCore::startErrorCapture(E_NOTICE);
        $cleaned = self::iconv('UTF-8', 'UTF-8', $xml);
        if ($cleaned != $xml) {
            $xml = self::iconv('Windows-1252', 'UTF-8', $xml);
        }
        fCore::stopErrorCapture();
    }

最後に、影響を受ける列のいずれかに変更がある場合は、これを実行します。

App::db()->query("set names 'utf8mb4'");

->query()これは、基本的にオブジェクトの実行をトリガーしfDatabaseます。

于 2015-09-09T13:14:29.417 に答える
-1

データベースのサイズを 33% 増やします。

違います。英字は依然としてそれぞれ 1 バイトを使用します。utf8mb4 で得られるのは、絵文字といくつかの漢字を保存できることです。

ALTER ... CHANGE列にする必要はありません。おそらくVARCHAR(255)問題のある缶詰があったことを除いて。単純に 191 に切り替えるのではなく、各列の「妥当な」数値に切り替えます。または何もしないでください。191 は限定品INDEXです。すべての列にインデックスを付けているわけではありませんよね?

サポートしていないように見えるfUTF8クラス

flourishlib に苦情を申し立てます。またはそれを放棄します。(これらのフォーラムであまりにも多くの質問が、MySQL 自体ではなく、不十分なサード パーティのパッケージに関する苦情です。)

MySQL で utf8mb4 に変更して、flourishlib が変更を認識しないようにすることができる場合があります。技術的に言えば、MySQL の utf8mb4 は、他の世界の utf8 の概念と一致します。MySQL の utf8 は不完全な実装です。

$this->execute("SET NAMES 'utf8'");

このコードが表示されている場合は、変更できます。

于 2015-09-08T06:41:48.347 に答える