Vui lòng giải thích cách Wordpress hoạt động với bộ ký tự và đối chiếu MySQL ở mức thấp


10

Như tiêu đề câu hỏi gợi ý, tôi đang tìm hiểu cách Wordpress hoạt động với các bộ ký tự và tùy chọn đối chiếu của MySQL. Như tôi sẽ trình bày dưới đây, mọi thứ không có ý nghĩa với tôi ...

Tôi đã cài đặt Wordpress bằng cách làm theo các hướng dẫn trên trang cài đặt của họ:

https://codex.wordpress.org/Installing_WordPress

Là một phần của hướng dẫn, tôi đã làm theo lời khuyên của họ để tạo thủ công cơ sở dữ liệu MySQL trên dòng lệnh, cụ thể là các lệnh:

mysql> CREATE DATABASE databasename;
Query OK, 1 row affected (0.00 sec)

mysql> GRANT ALL PRIVILEGES ON databasename.* TO "wordpressusername"@"hostname"
-> IDENTIFIED BY "password";
Query OK, 0 rows affected (0.00 sec)

mysql> FLUSH PRIVILEGES;
Query OK, 0 rows affected (0.01 sec)

mysql> EXIT

Hơn nữa, như được hướng dẫn, tôi đã chỉnh sửa tệp "wp-config.php" để sử dụng bộ ký tự UTF-8:

define( 'DB_CHARSET', 'utf8' );

... và để trống cài đặt đối chiếu:

define( 'DB_COLLATE', '' );

Đây là nơi niềm vui bắt đầu ...

  1. Nếu tôi nhập một ký tự không phải là một phần của MySQL UTF-8, nhưng là một phần của UTF-8 MB4, chẳng hạn như, vào một bài đăng, nó sẽ hiển thị chính xác trên trang được hiển thị. Tôi đã mong điều này sẽ không xảy ra, vì tôi đã không đặt ký tự thành UTF-8 MB4, nhưng UTF-8 bị hạn chế hơn (tất nhiên như được định nghĩa bởi MySQL, không được hiểu như thường).

  2. Nếu tôi điều tra vấn đề trong MySQL theo dòng lệnh, nó sẽ trở nên kỳ lạ hơn. Nếu tôi chạy show variables like 'char%';, tôi nhận được phản hồi này:

    +--------------------------+----------------------------+
    | Variable_name            | Value                      |
    +--------------------------+----------------------------+
    | character_set_client     | utf8                       |
    | character_set_connection | utf8                       |
    | character_set_database   | latin1                     |
    | character_set_filesystem | binary                     |
    | character_set_results    | utf8                       |
    | character_set_server     | latin1                     |
    | character_set_system     | utf8                       |
    | character_sets_dir       | /usr/share/mysql/charsets/ |
    +--------------------------+----------------------------+
    

Tôi đã mong đợi nhân vật cơ sở dữ liệu được đặt là UTF-8, không phải latin1.

  1. Nếu tôi chạy lệnh show variables like 'collation%';, đầu ra là:

    +----------------------+-------------------+
    | Variable_name        | Value             |
    +----------------------+-------------------+
    | collation_connection | utf8_general_ci   |
    | collation_database   | latin1_swedish_ci |
    | collation_server     | latin1_swedish_ci |
    +----------------------+-------------------+
    

Điều đó thậm chí còn xa lạ, vì những lý do rõ ràng (sẽ không mong đợi đối chiếu latin1_swbur_ci mặc định trong cơ sở dữ liệu UTF-8).

  1. Cuối cùng, nếu tôi chạy show full columns from mywpdatabase.wp_posts;, các dòng đầu ra, trong đó giá trị không phải là NULL, hiển thị đối chiếu là:

| post_content_filtered | longtext | utf8mb4_unicode_ci |

Câu hỏi của tôi sau đó - làm thế nào điều này có thể được giải thích? Tại sao Wordpress của tôi cài đặt hiển thị chính xác các ký tự UTF-8 MB4, khi cơ sở dữ liệu được xác định là UTF-8 trong cấu hình? Và tại sao cơ sở dữ liệu hiển thị trong MySQL là Latin1, đối chiếu Thụy Điển, thay vì UTF-8? Và tại sao, mặc dù tất cả điều này, các trường riêng lẻ trong bảng là utf8mb4_unicode_ci? Một lời giải thích cấp thấp về cách Wordpress làm việc với MySQL sẽ rất hữu ích. Cảm ơn bạn!

Câu trả lời:


11

Có hai định nghĩa trong wp-config.php của trang web WordPress:

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

Có một số điều thường bị hiểu lầm nhất. Tên của các hằng số trong các định nghĩa đó, có thể gợi ý rằng chúng có liên quan đến chính cơ sở dữ liệu. Họ không phải. Chúng có liên quan đến các bảng trong cơ sở dữ liệu.

Tạo cơ sở dữ liệu hoàn toàn độc lập với tạo bảng. WordPress không tạo cơ sở dữ liệu và không quan tâm đến bộ ký tự và đối chiếu mặc định của cơ sở dữ liệu, miễn là nó có thể kết nối với cơ sở dữ liệu.

Giá trị 'utf8' trong định nghĩa đầu tiên có nghĩa là bộ ký tự bị hạn chế ít nhất từ ​​gia đình 'utf8', đó là 'utf8' hoặc 'utf8mb4'.

Nếu bạn để lại định nghĩa ở trên không thay đổi, trước khi thử cài đặt trang web của bạn, thì giống như yêu cầu WordPress đưa ra lựa chọn của riêng mình, liên quan đến bộ ký tự và đối chiếu bảng của cơ sở dữ liệu, được hỗ trợ bởi MySQL (tùy thuộc vào phiên bản MySQL) và ít hạn chế nhất.

Sau đây là những điều, WordPress phân tích để xác định lựa chọn của mình, trong quá trình cài đặt:

  • Phiên bản của MySQL
  • đối chiếu cơ sở dữ liệu (trong wp-config.php)

Dựa trên phiên bản của MySQL, WordPress quyết định, nên sử dụng nhóm utf8 nào. Có hai, được phân biệt bằng tên của họ: utf8utf8mb4 . Các bộ ký tự từ nhóm utf8 , cho phép lưu trữ các ký tự dài tối đa 3 byte. Các bộ ký tự từ nhóm utf8mb4 , cho phép lưu trữ các ký tự dài tối đa 4 byte.

Bây giờ, WordPress kiểm tra giá trị của DB_COLLATE xác định. Nếu trống, nó sẽ sử dụng đối chiếu giới hạn ít nhất từ họ utf8 đã chọn , nếu không, sẽ sử dụng giá trị được chỉ định.

Ví dụ

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', '');

Nếu MySQL không hỗ trợ utf8mb4 (phiên bản cũ hơn) thì bộ ký tự bảng sẽ là utf8 và đối chiếu sẽ là utf8_general_ci . Mặt khác, chúng ta có thể mong đợi utf8mb4utf8mb4_unicode_520_ci hoặc utf8mb4_unicode_ci (phụ thuộc phiên bản MySQL).

define('DB_CHARSET', 'utf8');
define('DB_COLLATE', 'utf8_polish_ci');

Phiên bản MySQL cũ hơn - utf8utf8_polish_ci . Phiên bản MySQL mới hơn - utf8mb4utf8mb4_polish_ci ( hậu tố _polish_ci được vinh danh)

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'cp1250_polish_ci');

Bất kỳ phiên bản MySQL nào - cp1250cp1250_polish_ci .

define('DB_CHARSET', 'cp1250');
define('DB_COLLATE', 'utf8_general_ci');

Bất kỳ phiên bản MySQL nào - lỗi (không khớp với bộ ký tự và đối chiếu)

Tóm lược

Trong hầu hết các trường hợp, để lại các giá trị định nghĩa, được giải thích ở trên, không thay đổi, là một lựa chọn tốt. Nhưng, nếu bạn muốn đối chiếu các bảng khớp với ngôn ngữ của trang web của mình, bạn có thể sửa đổi giá trị của DB_COLLATE xác định một cách thích hợp (ví dụ: utf8mb4_polish_ci ).

Lưu ý: điều đó giải thích, tại sao ký tự được lưu trữ và truy xuất đúng cách. Đơn giản, bộ ký tự bảng của bạn thuộc nhóm utf8mb4 , không phải utf8 .


1
Cảm ơn bạn đã giải thích cách Wordpress thiết lập đối chiếu, nhưng bạn chưa giải quyết được các điểm còn lại. Tại sao, nếu bộ ký tự UTF-8 được xác định, MySQL có hiển thị cơ sở dữ liệu dưới dạng latin1 không? Và tại sao nó hiển thị đối chiếu cơ sở dữ liệu như Thụy Điển? Ngoài ra, bạn có vẻ khó hiểu về bộ ký tự và đối chiếu. Đối chiếu chỉ xác định thứ tự, quy tắc so sánh, không phải bộ ký tự. Do đó, bất kể đối chiếu nào được sử dụng, nếu UTF-8 là bộ ký tự, các ký tự bên ngoài nó (như được định nghĩa theo nghĩa hẹp hơn của MySQL) sẽ không hiển thị.
X-Mann

Tôi sẽ cập nhật câu trả lời của tôi, để giải thích rõ hơn về quy trình.
Frank P. Walentynowicz

1
Cảm ơn các cập nhật! Tôi đã chấp nhận câu trả lời của bạn, bây giờ tất cả đã rõ ràng. Vấn đề là ở MySQL và sự thiếu chuyên môn của tôi về nó - Tôi không biết các bảng có thể sử dụng một bộ ký tự rộng hơn cơ sở dữ liệu. Thông tin mới này đã giúp tôi thoải mái. Tôi không cần thay đổi bộ ký tự mặc định trong MySQL, Wordpress sẽ chăm sóc nó ở cấp độ bảng.
X-Mann

Không có gì. Tôi rất vui vì nó đã giúp.
Frank P. Walentynowicz
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.