web-dev-qa-db-ja.com

MySQL VARCHAR(255)UTF8はキーには長すぎますが、最大長は1000バイトです

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

  • MySQLはUTF8文字ごとに3バイトを予約します。
  • MyISAMでは、長さ1000バイトのキーを使用できます。
  • 私のUTF8 VARCHAR(255)should255 * 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であることがわかります。一意のインデックスの場合、charsは4バイトとしてカウントされるようですが、その理由はわかりません。

編集2:

Vladislav Vaintroubのおかげで、文字セットは確かにutf8mb4です。それは謎を解決します。この変更に関するドキュメントを見ていませんでした。

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

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

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

41
David Kanarek

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'
init_connect='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は、大きいインデックスキープレフィックスをサポートしないInnoDBの以前のバージョンとの互換性のために、大きいインデックスキープレフィックスを無効にするためにMySQL 5.5で導入されました。

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

41
jsears

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

これらのソリューションはどちらもおそらく適切ではないか、すでに試されているでしょう。

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

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

7
JohnL

より長いキー長が必要な人はinnodb_large_prefixを見てください

訪問 http://dev.mysql.com/doc/refman/5.5/en/innodb-parameters.html#sysvar_innodb_large_prefix

7
Omesh