Komunikat o błędzie w MySql:
Illegal mix of collations (utf8_unicode_ci,IMPLICIT) and (utf8_general_ci,IMPLICIT) for operation '='
Przeszedłem przez kilka innych postów i nie byłem w stanie rozwiązać tego problemu. Część, której to dotyczy, jest podobna do tej:
CREATE TABLE users (
userID INT UNSIGNED NOT NULL AUTO_INCREMENT,
firstName VARCHAR(24) NOT NULL,
lastName VARCHAR(24) NOT NULL,
username VARCHAR(24) NOT NULL,
password VARCHAR(40) NOT NULL,
PRIMARY KEY (userid)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE TABLE products (
productID INT UNSIGNED NOT NULL AUTO_INCREMENT,
title VARCHAR(104) NOT NULL,
picturePath VARCHAR(104) NULL,
pictureThumb VARCHAR(104) NULL,
creationDate DATE NOT NULL,
closeDate DATE NULL,
deleteDate DATE NULL,
varPath VARCHAR(104) NULL,
isPublic TINYINT(1) UNSIGNED NOT NULL DEFAULT '1',
PRIMARY KEY (productID)
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
CREATE TABLE productUsers (
productID INT UNSIGNED NOT NULL,
userID INT UNSIGNED NOT NULL,
permission VARCHAR(16) NOT NULL,
PRIMARY KEY (productID,userID),
FOREIGN KEY (productID) REFERENCES products (productID) ON DELETE RESTRICT ON UPDATE NO ACTION,
FOREIGN KEY (userID) REFERENCES users (userID) ON DELETE RESTRICT ON UPDATE NO ACTION
) ENGINE = INNODB CHARACTER SET utf8 COLLATE utf8_unicode_ci;
Procedura składowana, której używam, jest następująca:
CREATE PROCEDURE updateProductUsers (IN rUsername VARCHAR(24),IN rProductID INT UNSIGNED,IN rPerm VARCHAR(16))
BEGIN
UPDATE productUsers
INNER JOIN users
ON productUsers.userID = users.userID
SET productUsers.permission = rPerm
WHERE users.username = rUsername
AND productUsers.productID = rProductID;
END
Testowałem z php, ale ten sam błąd pojawia się w SQLyog. Przetestowałem również odtworzenie całego DB, ale bez rezultatu.
Każda pomoc będzie mile widziana.
źródło
COLLATE utf8_unicode_ci
do stałych łańcuchowych:SET @EMAIL = '[email protected]' COLLATE utf8_unicode_ci;
. Jest to szczególnie przydatne, jeśli uruchamiasz skrypt z konsoli, gdzie domyślne kodowanie konsoli ma zastosowanie do sortowania stałych łańcuchowych.(utf8mb4_unicode_ci, IMPLICIT)
zamiast(utf8_unicode_ci, IMPLICIT)
. Zbieram dane z sieci za pomocą języka Python, a następnie tworzę plik CSV ze skrobanymi danymi, który następnie przetwarzam za pomocą pliku PHP na serwerze, który przesyła dane do mojej bazy danych. wszystkie moje tabele / kolumny MySQL są sortowane jakoutf8mb4_unicode_ci
. Czy problem może wynikać z tego, że koduję dane jakutf8
w python / csv?Spędziłem pół dnia na poszukiwaniu odpowiedzi na identyczny błąd „Niedozwolona mieszanka zestawień” z konfliktami między utf8_unicode_ci i utf8_general_ci.
Zauważyłem, że niektóre kolumny w mojej bazie danych nie zostały specjalnie zestawione utf8_unicode_ci . Wygląda na to, że mysql niejawnie zestawił te kolumny utf8_general_ci .
Konkretnie, uruchomienie zapytania „SHOW CREATE TABLE table1” zwróciło coś takiego:
Zwróć uwagę, że wiersz „col1” varchar (4) CHARACTER SET utf8 NOT NULL nie ma określonej kolacji. Następnie uruchomiłem następujące zapytanie:
ALTER TABLE table1 CHANGE col1 col1 VARCHAR(4) CHARACTER SET utf8 COLLATE utf8_unicode_ci NOT NULL;
To rozwiązało mój błąd „Nielegalna mieszanka zestawień”. Mam nadzieję, że to pomoże komuś innemu.
źródło
COLLATE
dla całej tabeli (tj.ALTER TABLE table1 CHARSET utf8 COLLATE utf8_unicode_ci
) Nie rozwiąże problemu , trzeba to zrobić dla każdej (problematycznej) kolumny.Miałem podobny problem, ale przyszło mi do głowy wewnątrz procedury, kiedy mój parametr zapytania został ustawiony za pomocą zmiennej np
SET @value='foo'
.Przyczyną tego było niedopasowanie
collation_connection
i sortowanie w bazie danych. Zmienionocollation_connection
na dopasowaniecollation_database
i problem zniknął. Myślę, że jest to bardziej eleganckie podejście niż dodawanie Sortuj po parametrze / wartości.Podsumowując: wszystkie zestawienia muszą się zgadzać. Użyj
SHOW VARIABLES
i upewnij sięcollation_connection
icollation_database
dopasuj (sprawdź także sortowanie tabeli za pomocąSHOW TABLE STATUS [table_name]
).źródło
SET @my_var = 'string1,string2' COLLATE utf8_unicode_ci;
Trochę podobnie do odpowiedzi @bpile, w moim przypadku było ustawienie wpisu my.cnf
collation-server = utf8_general_ci
. Po tym, jak zdałem sobie z tego sprawę (i po wypróbowaniu wszystkiego powyżej), siłą przełączyłem moją bazę danych na utf8_general_ci zamiast utf8_unicode_ci i to wszystko:źródło
W moim przypadku mam następujący błąd
Niedozwolona kombinacja zestawień (utf8_general_ci, IMPLICIT) i (utf8_unicode_ci, IMPLICIT) dla operacji „=”
Po tygodniach wyszukiwania w Google zauważyłem, że dwa porównywane przeze mnie pola mają różne nazwy zestawień. Pierwsza, tj. Nazwa użytkownika, to utf8_general_ci, podczas gdy druga to utf8_unicode_ci, więc wróciłem do struktury drugiej tabeli i zmieniłem drugie pole (matric_no) na utf8_general_ci i działało jak urok.
źródło
Pomimo znalezienia ogromnej liczby pytań dotyczących tego samego problemu ( 1 , 2 , 3 , 4 ) nigdy nie znalazłem odpowiedzi, która uwzględniłaby wydajność, nawet tutaj.
Chociaż podano już wiele działających rozwiązań, chciałbym rozważyć wydajność.
EDYCJA: Podziękowania dla Manatax za wskazanie, że opcja 1 nie ma problemów z wydajnością.
Korzystanie z opcji
1 i2 , czyli metody rzutowania COLLATE , może prowadzić do potencjalnego wąskiego gardła, ponieważ żaden indeks zdefiniowany w kolumnie nie zostanie użyty, co spowoduje pełne skanowanie .Mimo że nie wypróbowałem opcji 3 , mam przeczucie, że będzie ona miała takie same konsekwencje, jak opcja
1 i2.Wreszcie opcja 4 jest najlepszą opcją w przypadku bardzo dużych stołów, gdy jest to wykonalne. Chodzi mi o to, że nie ma innych zastosowań, które opierają się na oryginalnym zestawieniu.
Rozważ to uproszczone zapytanie:
W moim oryginalnym przykładzie miałem znacznie więcej połączeń. Oczywiście tabela1 i tabela2 mają różne sortowania. Użycie operatora sortowania do rzutowania spowoduje, że indeksy nie będą używane.
Zobacz wyjaśnienie sql na poniższym obrazku.
Wizualne wyjaśnienie zapytania podczas korzystania z rzutowania COLLATE
Z drugiej strony opcja 4 może skorzystać z możliwego indeksu i prowadzić do szybkich zapytań.
Na poniższym obrazku widać, że to samo zapytanie jest uruchamiane po zastosowaniu opcji 4 , czyli po zmianie schematu / tabeli / sortowania kolumn.
Wizualne wyjaśnienie zapytania po zmianie sortowania, a zatem bez rzutowania sortowania
Podsumowując, jeśli wydajność jest ważna i możesz zmienić sortowanie tabeli, wybierz opcję 4 . Jeśli musisz działać na jednej kolumnie, możesz użyć czegoś takiego:
źródło
Dzieje się tak, gdy kolumna jest jawnie ustawiona na inne sortowanie lub domyślne sortowanie jest inne w tabeli, której dotyczy zapytanie.
jeśli masz wiele tabel, w których chcesz zmienić sortowanie po uruchomieniu tego zapytania:
Spowoduje to wyświetlenie zapytań potrzebnych do przekonwertowania wszystkich tabel w celu użycia prawidłowego sortowania na kolumnę
źródło