3つの列を持つテーブルがあります。
id(int 11) | user_id(int 4) | title(varchar 512)
____________|________________|___________________
1 | 3 | Thing X
2 | 3 | Something Else
3 | 5 | Thing X
そして、user_id
とtitle
を一意に組み合わせる必要があります。そのために私はこの簡単なクエリを使用しています:
ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`)
title
列の文字セットはutf8mb4_unicode_ci
です。データベースは文字セットutf8mb4
を使用して作成されました:
CREATE DATABASE learning_db CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci;
そして、テーブルのタイプはInnoDB
です。
私はいくつかのグローバルを設定しようとしました:
SET GLOBAL innodb_file_format=Barracuda;
SET GLOBAL innodb_file_per_table=on;
SET GLOBAL innodb_large_prefix=on;
しかし、同じエラー1071
が発生します。
Specified key was too long; max key length is 767 bytes
他に何かできることはありますか?
PS:title
の最初の191
文字のみをインデックスに設定すると、そのエラーは発生しません:
ALTER TABLE posts ADD UNIQUE `unique_post`(`user_id`, `title`(191))
...しかし、最後の文字だけが異なる可能性がある同じユーザーに関連するタイトルがあります(文字セットを考慮して最後の4バイトとも呼ばれます)
PS:私はローカルホストにいます(xamppを使用)。
わかりましたので、週末の長い研究の後、答えは非常に簡単です。この同じ問題に直面している他の人のためにここに置いておきます。
この回答は、MariaDB 10.1.38、db文字セットutf8mb4
、テーブルタイプInnoDB
およびテーブル文字セットutf8mb4_unicode_ci
でテストされています。
my.ini
を開き、次の行を追加します(すでに存在する場合は、[mysqld]の直後に=
の後にすべてを編集します)。
innodb_file_format = Barracuda
innodb_file_per_table = on
innodb_default_row_format = dynamic
innodb_large_prefix = 1
innodb_file_format_max = Barracuda
コマンド/ターミナルを介してそれらを設定することもできます:
Windowsの場合-xamppがc:\xampp\
にある場合:
コマンドを開き、mysql
のビンに移動します-この場合:
cd c:\xampp\mysql\bin
補足:
mysql -h localhost -u root
認証されたら、次のクエリを実行します(一度に1つ)。
SET GLOBAL innodb_file_format = Barracuda;
SET GLOBAL innodb_file_per_table = on
SET GLOBAL innodb_default_row_format = dynamic
SET GLOBAL innodb_large_prefix = 1
SET GLOBAL innodb_file_format_max = Barracuda
ただし、クエリを実行する場合は、Apacheを再起動するたびにオプションが書き換えられる可能性があるため、my.ini(または.cnf)を編集することをお勧めします。
InnoDB
ストレージ形式の詳細については、次をご覧ください。 here
また、この記事は、varchars
を最適化してunique keys
を作成する前に、非常に興味深いものです。 here