2016-09-25 7 views
2

MYSQLテーブルには、異なる言語で一意の文字列が含まれている列があります。スウェーデン語AとMYSQLを使用する英語Aは、それらを同等として扱います。MYSQL UTF8_bin大文字と小文字を区別しない一意のインデックス

私はこれらの列の照合がより適切であると思われるので、UTF8_binの照合を使用することを検討しています。

UTF_8_binで一意のインデックスは大文字と小文字を区別しないため、両方の文字列が同じ言語の場合は 'Andreas'と 'andreas'が可能になります。

これに対応する方法はありますか?

答えて

1

文字列の小文字のバージョンを格納する生成された列を使用し、その列に一意のインデックスを使用できます。

create table test_utf8_bin_ci 
(u8 varchar(50) charset utf8mb4 collate utf8mb4_unicode_ci, 
    u8_bin_ci varchar(50) charset utf8mb4 collate utf8mb4_bin as (lower(u8)) unique 
); 

insert into test_utf8_bin_ci (u8) 
values ('A'),('Ä'),('Å'),('Â'),('Á'),('À'); 

insert into test_utf8_bin_ci (u8) 
values ('å'); 

Error Code: 1062. Duplicate entry 'å' for key 'u8_bin_ci' 

5.7.8より前のバージョンのMySQLでは、生成された列のインデックスはまだサポートされていません。したがって、「通常」の列(as (lower(u8))なし)を追加し、値をinsert/updateトリガーで計算する必要があります。ユニークなインデックスは、計算されたカラムと同じように動作しますが、コード化するだけでもう少しです。

create trigger trbins_test_u8_bin_ci before insert on test_u8_bin_ci 
for each row 
    set new.u8_bin_ci = lower(new.u8); 
create trigger trbupd_test_u8_bin_ci before update on test_u8_bin_ci 
for each row 
    set new.u8_bin_ci = lower(new.u8); 

あなたが_binを使用する場合は、機能の多くは、例えば、いずれかのもう小文字を区別しない場合に動作しないことに注意する必要があります

select * 
from test_utf8_bin_ci 
where u8 = 'ä'; 

は結果を提供しません。 (あなたが例えばwhere lower(u8) = lower('ä')を使用している場合は不可能である)を検索するためにインデックスを使用できるようにするには、

select * 
from test_utf8_bin_ci 
where u8_bin_ci = lower('ä'); 

を使用することができ、あなたのクエリを比較するために別の列を使用して更新することを意味するものであろうと(必要かもしれませんフレームワークを使用している場合はもう少し適応します)、完全であれば回避策は回避策と呼ばれることはありません。

関連する問題