2012-09-16 28 views
12

Ưu điểm/nhược điểm của việc sử dụng utf8 làm bộ ký tự dựa vào việc sử dụng latin1 là gì?utf-8 vs latin1

Nếu utf có thể hỗ trợ nhiều ký tự hơn và được sử dụng nhất quán không phải lúc nào cũng là lựa chọn tốt hơn? Có lý do nào để chọn latin1 không?

+0

Luôn sử dụng 'utf8mb4' chứ không phải' utf8' - [đó là một loại lỗi của MySQL] (https://medium.com/@adamhooper/in-mysql-never-use-utf8-use-utf8mb4-11761243e434). – xmedeko

Trả lời

10

latin1 có lợi thế là mã hóa một byte, do đó nó có thể lưu trữ nhiều ký tự hơn trong cùng dung lượng lưu trữ vì độ dài của kiểu dữ liệu chuỗi trong MySql phụ thuộc vào mã hóa. Hướng dẫn states rằng

Để tính số byte dùng để lưu trữ một CHAR Đặc biệt, VARCHAR, hoặc giá trị cột TEXT, bạn phải đưa vào tài khoản tập nhân vật sử dụng cho cột đó và liệu giá trị chứa các ký tự nhiều byte. Cụ thể, khi sử dụng bộ ký tự Unicode utf8 (hoặc utf8mb4) , bạn phải nhớ rằng không phải tất cả các ký tự đều sử dụng cùng số byte và có thể yêu cầu tối đa ba (bốn) byte cho mỗi ký tự. Để biết chi tiết về bộ nhớ được sử dụng cho các loại khác nhau của các ký tự utf8 hoặc utf8mb4, xem Phần 10.1.10, "Hỗ trợ Unicode".

Hơn nữa, nhiều thao tác chuỗi (chẳng hạn như lấy dữ liệu và so sánh phụ thuộc đối chiếu) nhanh hơn với mã hóa một byte.

Trong mọi trường hợp, latin1 không phải là ứng cử viên nghiêm túc nếu bạn quan tâm đến quốc tế. Nó có thể là một lựa chọn thích hợp khi bạn sẽ lưu trữ các giá trị an toàn đã biết (chẳng hạn như các URL được mã hóa theo phần trăm).

+0

Tính năng này cũng hỗ trợ các ngôn ngữ Unicode khác không? Tiếng Do Thái nói riêng? – qwertymk

+0

Nó không hỗ trợ tiếng Hebrew, @qwertymk. Xem http://en.wikipedia.org/wiki/ISO/IEC_8859-1 để biết danh sách các tập lệnh và thực sự là các ký tự * riêng lẻ, nó hỗ trợ. –

+0

@qwertymk: Rõ ràng là [không] (http://dev.mysql.com/doc/refman/5.5/en/charset-we-sets.html), nó được gọi là bộ ký tự Tây Âu. – Jon

1

Mã hóa có độ dài cố định như latin-1 luôn hiệu quả hơn về mức tiêu thụ CPU.

Nếu bộ mã thông báo trong một bộ ký tự có độ dài cố định được biết là đủ cho mục đích của bạn, và mục đích của bạn liên quan đến xử lý chuỗi nặng và chuyên sâu, với rất nhiều LENGTH() và SUBSTR() đó có thể là một lý do chính đáng để không sử dụng mã hóa như UTF-8.

Oh và BTW. Đừng nhầm lẫn, như bạn có vẻ như, giữa bộ ký tự và mã hóa của chúng. Một bộ ký tự là một số bộ chữ được xác định có thể ghi được. Tập ký tự giống nhau có thể có nhiều mã hóa riêng biệt. Các phiên bản khác nhau của tiêu chuẩn unicode mỗi phiên bản tạo thành một bộ ký tự. Mỗi người trong số họ có thể phải tuân theo UTF-8, UTF-16 và "UTF-32" (không phải là tên chính thức, nhưng nó đề cập đến ý tưởng sử dụng mã hóa đầy đủ bốn byte cho bất kỳ ký tự nào) và hai mã sau có thể có hương vị HOB-đầu tiên hoặc HOB.

15

UTF8 Ưu điểm:

  1. Hỗ trợ hầu hết các ngôn ngữ, bao gồm cả ngôn ngữ RTL như tiếng Hebrew.

  2. Không cần dịch khi nhập/xuất dữ liệu vào các thành phần nhận thức UTF8 (JavaScript, Java, v.v.).

Nhược UTF8:

  1. ký tự không phải là ASCII sẽ mất nhiều thời gian để mã hóa và giải mã, do chương trình mã hóa phức tạp hơn của họ.

  2. Ký tự không phải ASCII sẽ chiếm nhiều không gian hơn vì chúng có thể được lưu trữ sử dụng nhiều hơn 1 byte (ký tự không phải trong 127 ký tự đầu tiên của bộ ký tự ASCII). Trường CHAR(10) hoặc VARCHAR(10) có thể cần tối đa 30 byte để lưu trữ một số ký tự UTF8.

  3. Collations khác utf8_bin sẽ chậm hơn vì thứ tự sắp xếp sẽ không trực tiếp ánh xạ tới thứ tự mã hóa ký tự) và yêu cầu dịch trong một số thủ tục được lưu trữ (như biến mặc định là utf8_general_ci đối chiếu).

  4. Nếu bạn cần JOIN trường UTF8 và không phải UTF8, MySQL sẽ áp đặt lần truy cập hiệu suất SEVERE. Truy vấn phụ thứ hai sẽ có thể mất phút nếu các trường được tham gia là các tập hợp/collations ký tự khác nhau.

Bottom line:

Nếu bạn không cần phải hỗ trợ ngôn ngữ không phải latin1, muốn đạt được hiệu suất tối đa, hoặc đã có bảng sử dụng latin1, chọn latin1.

Nếu không, hãy chọn UTF8.

+1

Câu lệnh "Bạn có thể cần phải tăng độ dài trường' CHAR' để cho phép thêm không gian, vì 'VARCHAR (10)' chỉ có thể lưu trữ năm, hoặc ít hơn, các ký tự của dữ liệu UTF8. " (trong bất lợi 1) là không chính xác. Kích thước cột phản ánh số ký tự tối đa được phép, không phải kích thước lưu trữ (xem http://dev.mysql.com/doc/refman/5.6/en/storage-requirements.html). –

+0

meden: Bạn hoàn toàn đúng. Tôi đã cập nhật câu trả lời của mình để phản ánh thực tế này. Xin lỗi vì những lỗi lầm. –

+0

Còn ASCII thì sao? thay vì tiếng Latinh –

2

@Ross Smith II, Điểm 4 có giá trị vàng, có nghĩa là mâu thuẫn giữa các cột có thể nguy hiểm.

Để thêm giá trị cho các câu trả lời đã tốt, đây là một thử nghiệm hiệu suất nhỏ về sự khác biệt giữa các bảng mã:

Một hiện đại 2013 máy chủ, sử dụng thực tế bảng với 20000 dòng, không có chỉ mục trên cột có liên quan.

CHỌN 4 TỪ subscribers WHERE 1 ORDER BY time_utc_str; (4 là bộ nhớ cache buster)

  • varchar (20) CHARACTER SET COLLATION latin1 latin1_bin: 15ms
  • varbinary (20): 17ms
  • utf8_bin: 20ms
  • utf8_general_ci: 23MS

Đối với các chuỗi đơn giản như số ngày, quyết định của tôi sẽ là khi hiệu suất có liên quan, sử dụng utf8_bin (CHARACTER SET utf8 COLLATE utf8_bin). Điều này sẽ ngăn chặn bất kỳ tác động bất lợi nào với mã khác mà các bộ mã cơ sở dữ liệu mong đợi là utf8 trong khi vẫn là loại nhị phân.

Các vấn đề liên quan