Проблемът е, че MySQL игнорира крайния празен интервал, когато прави сравнение на низове. Вижтеhttp://dev.mysql.com/doc/refman/ 5.7/en/char.html
(Тази информация е за 5.7; за 8.0 това се промени, вижте по-долу)
Разделът за like
операторът дава пример за това поведение (и показва, че like
уважава крайния празен интервал):
mysql> SELECT 'a' = 'a ', 'a' LIKE 'a ';
+------------+---------------+
| 'a' = 'a ' | 'a' LIKE 'a ' |
+------------+---------------+
| 1 | 0 |
+------------+---------------+
1 row in set (0.00 sec)
За съжаление UNIQUE
index изглежда използва стандартното сравнение на низове, за да провери дали вече има такава стойност и по този начин игнорира крайния празен интервал. Това е независимо от използването на VARCHAR
или CHAR
, и в двата случая вмъкването се отхвърля, тъй като уникалната проверка е неуспешна. Ако има начин да използвате like
семантика за UNIQUE
проверете, тогава не го знам.
Това, което бихте могли да направите, е да съхраните стойността като VARBINARY
:
mysql> create table test_ws ( `value` varbinary(255) UNIQUE );
Query OK, 0 rows affected (0.13 sec)
mysql> insert into test_ws (`value`) VALUES ('a');
Query OK, 1 row affected (0.08 sec)
mysql> insert into test_ws (`value`) VALUES ('a ');
Query OK, 1 row affected (0.06 sec)
mysql> SELECT CONCAT( '(', value, ')' ) FROM test_ws;
+---------------------------+
| CONCAT( '(', value, ')' ) |
+---------------------------+
| (a) |
| (a ) |
+---------------------------+
2 rows in set (0.00 sec)
По-добре не искате да правите нещо като сортиране по азбучен ред на тази колона, защото сортирането ще се извърши на стойностите на байтовете и това няма да е това, което потребителите очакват (все пак повечето потребители).
Алтернативата е да поправите MySQL и да напишете своя собствена сортировка, която е от тип NO PAD. Не съм сигурен дали някой иска да го направи, но ако го направи, уведомете ме;)
Редактиране:междувременно MySQL има съпоставяния, които са от тип NO PAD, според https://dev.mysql.com/doc/refman/8.0/en/char.html :
и https://dev.mysql.com/ doc/refman/8.0/en/charset-unicode-sets.html
Така че, ако опитате:
create table test_ws ( `value` varbinary(255) UNIQUE )
character set utf8mb4 collate utf8mb4_0900_ai_ci;
можете да вмъквате стойности със и без крайно празно пространство
Можете да намерите всички налични съпоставяния NO PAD с:
show collation where Pad_attribute='NO PAD';