Napotkaliśmy ten problem podczas próby dodania indeksu UNIQUE do pola VARCHAR (255) przy użyciu utf8mb4. Podczas gdy problem jest już dobrze zarysowany, chciałem dodać kilka praktycznych rad, w jaki sposób wymyśliliśmy to i rozwiązaliśmy.
Gdy używasz utf8mb4, znaki liczą się jako 4 bajty, podczas gdy w utf8 mogą one wynosić 3 bajty. Bazy danych InnoDB mają taki limit, że indeksy mogą zawierać tylko 767 bajtów. Tak więc, używając utf8, możesz przechowywać 255 znaków (767/3 = 255), ale używając utf8mb4, możesz przechowywać tylko 191 znaków (767/4 = 191).
Absolutnie możesz dodawać regularne indeksy dla VARCHAR(255)
pól za pomocą utf8mb4, ale dzieje się tak, że rozmiar indeksu jest automatycznie obcinany do 191 znaków - jak unique_key
tutaj:
Jest to w porządku, ponieważ zwykłe indeksy są po prostu używane, aby pomóc MySQL w szybszym wyszukiwaniu danych. Całe pole nie musi być indeksowane.
Dlaczego więc MySQL automatycznie obcina indeks dla zwykłych indeksów, ale zgłasza wyraźny błąd, próbując zrobić to dla unikalnych indeksów? Cóż, aby MySQL mógł dowiedzieć się, czy wstawiana lub aktualizowana wartość już istnieje, musi faktycznie zindeksować całą wartość, a nie tylko jej część.
Na koniec dnia, jeśli chcesz mieć unikalny indeks na polu, cała zawartość pola musi mieścić się w indeksie. W przypadku utf8mb4 oznacza to zmniejszenie długości pola VARCHAR do 191 znaków lub mniej. Jeśli nie potrzebujesz utf8mb4 dla tej tabeli lub pola, możesz upuścić go z powrotem do utf8 i mieć możliwość zachowania 255 pól długości.