我在MYSQL表中有一些列將包含不同語言的唯一字符串,並且有些情況下某些字符將與例如英語A與瑞典語A和MYSQL將視爲平等。MYSQL UTF8_bin不區分大小寫的唯一索引
因此,我正在考慮使用UTF8_bin
整理這些列,因爲它似乎更合適。
問題是,與UTF_8_bin
獨特的索引不會區分大小寫,所以如果兩個字符串是相同的語言,'Andreas'和'andreas'將是可能的。
有沒有解決方法?
我在MYSQL表中有一些列將包含不同語言的唯一字符串,並且有些情況下某些字符將與例如英語A與瑞典語A和MYSQL將視爲平等。MYSQL UTF8_bin不區分大小寫的唯一索引
因此,我正在考慮使用UTF8_bin
整理這些列,因爲它似乎更合適。
問題是,與UTF_8_bin
獨特的索引不會區分大小寫,所以如果兩個字符串是相同的語言,'Andreas'和'andreas'將是可能的。
有沒有解決方法?
您可以使用生成的列來存儲字符串的小寫字母版本,並在其上使用唯一索引。
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('ä');
這將意味着你的查詢會使用不同的列來比較和更新(這可能需要如果您使用框架,可以進一步調整),但是如果這些解決方案是完美的,則不會將解決方法稱爲解決方法。