48

これについて多くの質問があったことは承知していますが、私の計算は正しいと思います。

  • MySQL は、UTF8 文字ごとに 3 バイトを予約します。
  • MyISAM では、長さ 1000 バイトのキーを使用できます。
  • 私の UTF8 VARCHAR(255)はバイトでなければなりません255 * 3 = 765

UNQUE がエントリごとに余分な 200+ バイトを必要としない限り、なぜこれが機能しないのですか?

mysql> ALTER TABLE entry ADD UNIQUE INDEX (name(255));
ERROR 1071 (42000): Specified key was too long; max key length is 1000 bytes

これについて私にできることはありますか?

編集:

制限は 250 であることが判明しました。文字は一意のインデックスに対して 4 バイトとしてカウントされるようですが、その理由はわかりません。

編集2:

Vladislav Vaintroub に感謝します。文字セットは確かに utf8mb4 です。それで謎が解けます。この変更に関するドキュメントは見たことがありません。

フィールドを暗黙的に切り捨てることによって非一意のインデックスを構築すると推測していますが、これは一意のインデックスには受け入れられないため、拒否されます。

回答としてコメントを再入力していただければ、喜んで受け入れます。

解決策: utf8mb4 ではなく utf8 を指定します (MySQL 管理者はこれを許可していないため、テーブルを手動で作成します)。

4

3 に答える 3

46

utf8mb4 を使用していて、長さが 191 文字を超える varchar 列に一意のインデックスがある場合、utf8mb4 は utf8 または latin1 よりも多くのストレージ スペースを必要とするため、innodb_large_prefix をオンにして、インデックス内のより大きな列を許可する必要があります。 . my.cnf ファイルに以下を追加します。

[mysqld]
innodb_file_format=barracuda
innodb_file_per_table=1
innodb_large_prefix=1
init_connect='SET collation_connection = utf8mb4_unicode_ci; SET NAMES utf8mb4'
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci

MySQL 5.7 ドキュメントからの理由と将来に関する詳細情報:

innodb_large_prefix が有効になっている場合 (MySQL 5.7.7 のデフォルト)、DYNAMIC または COMPRESSED 行フォーマットを使用する InnoDB テーブルのインデックス キー プレフィックスの制限は 3072 バイトです。innodb_large_prefix が無効になっている場合、インデックス キーのプレフィックスの制限は、すべての行形式のテーブルで 767 バイトです。

innodb_large_prefix は MySQL 5.7.7 で廃止され、将来のリリースで削除される予定です。innodb_large_prefix は MySQL 5.5 で導入され、大きなインデックス キー プレフィックスをサポートしていない以前のバージョンの InnoDB との互換性のために大きなインデックス キー プレフィックスを無効にしました。

要約すると、制限は互換性のためにのみ存在し、将来のバージョンで増加する予定です。

于 2016-04-04T14:48:30.127 に答える
8

より長いキーの長さが必要な場合は、innodb_large_prefix を確認してください。

http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_large_prefixにアクセスしてください

于 2012-07-18T11:38:14.533 に答える
8

MySQL はUTF8フィールドの最大量を 4 バイトに予約しているため、1000 バイトの制限を超えているのです。varcharを 255 未満で作成するか、なしで作成することをお勧めしますUTF8

これらの解決策はどちらもおそらく適切ではないか、すでに試したことがあるでしょう。

私が考えることができる他の唯一の解決策は、列を 2 つの小さな列に分割し、それらのフィールドの両方に一意のインデックスを作成することですが、上記と同じエラーが発生すると思います。

おそらく が必要なので、この作業を行うには、列を 250 (または 249) に少しUTF8減らすことを真剣に検討します。varchar(255)

于 2011-05-31T04:39:52.700 に答える