2016-09-25 27 views
2

我在MYSQL表中有一些列將包含不同語言的唯一字符串,並且有些情況下某些字符將與例如英語A與瑞典語A和MYSQL將視爲平等。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('ä'); 

這將意味着你的查詢會使用不同的列來比較和更新(這可能需要如果您使用框架,可以進一步調整),但是如果這些解決方案是完美的,則不會將解決方法稱爲解決方法。