Mysql
 sql >> Cơ Sở Dữ Liệu >  >> RDS >> Mysql

MySQL kết hợp bất hợp pháp các đối chiếu

Sẽ rất hữu ích nếu bạn hiểu các định nghĩa sau:

  • Một mã hóa ký tự nêu chi tiết cách từng biểu tượng được biểu diễn dưới dạng nhị phân (và do đó được lưu trữ trong máy tính). Ví dụ:ký hiệu é (U + 00E9, chữ cái Latinh nhỏ E với dấu sắc) là được mã hóa dưới dạng 0xc3a9 trong UTF-8 (MySQL gọi utf8 ) và 0xe9 trong Windows-1252 (MySQL gọi latin1 ).

  • Một bộ ký tự là bảng chữ cái của các ký hiệu có thể được biểu diễn bằng cách sử dụng một bảng mã ký tự nhất định. Thật khó hiểu, thuật ngữ này cũng được sử dụng có nghĩa giống như mã hóa ký tự.

  • A đối chiếu là một thứ tự trên một tập ký tự, để các chuỗi có thể được so sánh. Ví dụ: latin1_swedish_ci của MySQL đối chiếu coi hầu hết các biến thể có dấu của một ký tự tương đương với ký tự cơ sở, trong khi của nó latin1_general_ci đối chiếu sẽ sắp xếp thứ tự chúng trước ký tự cơ sở tiếp theo nhưng không tương đương (cũng có những khác biệt khác, quan trọng hơn,:chẳng hạn như thứ tự của các ký tự như å , ä , öß ).

MySQL sẽ quyết định đối chiếu nào nên được áp dụng cho một biểu thức nhất định như được ghi lại trong Đối chiếu các biểu thức :cụ thể là đối chiếu của một cột được ưu tiên hơn so với đối chiếu của một chuỗi ký tự.

WHERE mệnh đề truy vấn của bạn so sánh các chuỗi sau:

  1. một giá trị trong fos_user.username , được mã hóa trong bộ ký tự của cột (Windows-1252) và thể hiện tùy chọn đối chiếu của nó latin1_swedish_ci (với giá trị cưỡng chế là 2); với

  2. chuỗi ký tự 'Nrv⧧Kasi' , được mã hóa trong bộ ký tự của kết nối (UTF-8, như được định cấu hình bởi Doctrine) và thể hiện tùy chọn đối chiếu của kết nối utf8_general_ci (với giá trị cưỡng chế là 4).

Vì chuỗi đầu tiên trong số các chuỗi này có giá trị cưỡng chế thấp hơn chuỗi thứ hai, MySQL cố gắng thực hiện so sánh bằng cách sử dụng đối chiếu của chuỗi đó:latin1_swedish_ci . Để làm như vậy, MySQL cố gắng chuyển đổi chuỗi thứ hai thành latin1 —Nhưng kể từ ký tự không tồn tại trong bộ ký tự đó, so sánh không thành công.

Cảnh báo

Người ta nên tạm dừng một chút để xem xét cách cột hiện được mã hóa:bạn đang cố gắng lọc các bản ghi trong đó fos_user.username bằng một chuỗi chứa ký tự không thể tồn tại trong cột đó !

Nếu bạn tin rằng cột không chứa các ký tự như vậy, thì bạn có thể đã ghi vào cột trong khi mã hóa ký tự kết nối được đặt thành thứ gì đó (ví dụ:latin1 ) khiến MySQL diễn giải chuỗi byte đã nhận là các ký tự nằm trong bộ ký tự Windows-1252.

Nếu đúng như vậy, trước khi tiếp tục, bạn nên sửa dữ liệu của mình!

  1. chuyển đổi các cột như vậy thành mã hóa ký tự đã được sử dụng khi chèn dữ liệu, nếu khác với mã hóa đương nhiệm:

    ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET foo;
    
  2. thả thông tin mã hóa được liên kết với các cột như vậy bằng cách chuyển đổi chúng thành binary bộ ký tự:

    ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET binary;
    
  3. kết hợp với các cột như vậy mã hóa mà dữ liệu đã thực sự được truyền bằng cách chuyển đổi chúng sang bộ ký tự có liên quan.

    ALTER TABLE fos_users MODIFY username VARCHAR(123) CHARACTER SET bar;
    

Lưu ý rằng, nếu chuyển đổi từ mã hóa nhiều byte, bạn có thể cần phải tăng kích thước của cột (hoặc thậm chí thay đổi loại của nó) để chứa độ dài tối đa có thể của chuỗi được chuyển đổi.

Một khi chắc chắn rằng các cột được mã hóa chính xác, người ta có thể buộc tiến hành so sánh bằng cách sử dụng đối chiếu Unicode bằng cách—

  • chuyển đổi rõ ràng giá trị fos_user.username thành một bộ ký tự Unicode:

    WHERE CONVERT(fos_user.username USING utf8) = ?
    
  • buộc chuỗi ký tự phải có giá trị cưỡng chế thấp hơn cột (sẽ gây ra chuyển đổi ngầm định giá trị của cột thành UTF-8):

    WHERE fos_user.username = ? COLLATE utf8_general_ci
    

Hoặc một người có thể, như bạn nói, chuyển đổi vĩnh viễn (các) cột thành bảng mã Unicode và đặt đối chiếu của nó một cách thích hợp.

Nguyên tắc cân nhắc là các bảng mã Unicode chiếm nhiều không gian hơn các bộ ký tự byte đơn, vì vậy:

  • có thể cần thêm dung lượng;

  • so sánh có thể chậm hơn; và

  • Độ dài tiền tố chỉ mục có thể cần được điều chỉnh (lưu ý rằng độ dài tối đa tính bằng byte, do đó có thể thể hiện ít ký tự hơn trước đây).

Ngoài ra, hãy lưu ý rằng, như được ghi trong ALTER TABLE Cú pháp :



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Tôi cần lấy dữ liệu dựa trên trình tự chính xác của nó trong một mảng

  2. SQLSTATE [42000]:Lỗi cú pháp hoặc vi phạm quyền truy cập:1064 Bạn có lỗi trong cú pháp SQL của mình - PHP - PDO

  3. Tính toán decile từ lần truy cập gần đây trong MySQL

  4. Sử dụng MariaDB

  5. Tải hình ảnh lên cơ sở dữ liệu MySQL bằng Blob