Chúng tôi đã gặp phải sự cố này khi cố gắng thêm chỉ mục UNIQUE vào trường VARCHAR (255) bằng utf8mb4. Mặc dù vấn đề đã được nêu rõ ở đây rồi, tôi muốn thêm một số lời khuyên thiết thực cho cách chúng tôi tìm ra vấn đề này và giải quyết nó.
Khi sử dụng utf8mb4, các ký tự được tính là 4 byte, trong khi dưới utf8, chúng có thể là 3 byte. Cơ sở dữ liệu InnoDB có một giới hạn là các chỉ mục chỉ có thể chứa 767 byte. Vì vậy, khi sử dụng utf8, bạn có thể lưu trữ 255 ký tự (767/3 = 255), nhưng sử dụng utf8mb4, bạn chỉ có thể lưu trữ 191 ký tự (767/4 = 191).
Bạn hoàn toàn có thể thêm các chỉ mục thông thường cho VARCHAR(255)
các trường bằng utf8mb4, nhưng điều xảy ra là kích thước chỉ mục được tự động cắt ở mức 191 ký tự - như unique_key
ở đây:
Điều này là tốt, bởi vì các chỉ mục thông thường chỉ được sử dụng để giúp MySQL tìm kiếm thông qua dữ liệu của bạn nhanh hơn. Toàn bộ lĩnh vực không cần phải được lập chỉ mục.
Vì vậy, tại sao MySQL tự động cắt chỉ mục cho các chỉ mục thông thường, nhưng lại đưa ra một lỗi rõ ràng khi cố gắng làm điều đó cho các chỉ mục duy nhất? Chà, để MySQL có thể tìm ra nếu giá trị được chèn hoặc cập nhật đã tồn tại, nó cần phải thực sự lập chỉ mục cho toàn bộ giá trị và không chỉ là một phần của nó.
Vào cuối ngày, nếu bạn muốn có một chỉ mục duy nhất trên một trường, toàn bộ nội dung của trường phải phù hợp với chỉ mục. Đối với utf8mb4, điều này có nghĩa là giảm độ dài trường VARCHAR của bạn xuống còn 191 ký tự hoặc ít hơn. Nếu bạn không cần utf8mb4 cho bảng hoặc trường đó, bạn có thể thả nó trở lại utf8 và có thể giữ các trường có độ dài 255 của bạn.