2009-03-04 66 views
59

Có quy tắc nào khi chúng ta phải sử dụng các loại Unicode không?Khi nào chúng ta phải sử dụng NVARCHAR/NCHAR thay vì VARCHAR/CHAR trong SQL Server?

Tôi đã thấy rằng hầu hết các ngôn ngữ châu Âu (tiếng Đức, tiếng Ý, tiếng Anh, ...) đều có cơ sở dữ liệu giống nhau trong các cột VARCHAR.

Tôi đang tìm kiếm một cái gì đó như:

  1. Nếu bạn có Trung Quốc -> sử dụng NVARCHAR
  2. Nếu bạn có Đức và tiếng Ả Rập -> sử dụng NVARCHAR

gì về collation của máy chủ/cơ sở dữ liệu?

Tôi không muốn sử dụng luôn NVARCHAR như gợi ý ở đây What are the main performance differences between varchar and nvarchar SQL Server data types?

Trả lời

96

Lý do thực sự bạn muốn sử dụng NVARCHAR là khi bạn có khác nhau ngôn ngữ trong cùng một cột, bạn cần phải giải quyết các cột trong T-SQL mà không cần giải mã, bạn muốn có thể xem dữ liệu "nguyên bản" trong SSMS, hoặc bạn muốn chuẩn hóa trên Unicode.

Nếu bạn xử lý cơ sở dữ liệu dưới dạng lưu trữ câm, có thể lưu trữ chuỗi rộng và mã hóa khác nhau (thậm chí có độ dài thay đổi) trong VARCHAR (ví dụ UTF-8). Sự cố xảy ra khi bạn đang cố mã hóa và giải mã, đặc biệt nếu trang mã khác với các hàng khác nhau. Nó cũng có nghĩa là SQL Server sẽ không thể xử lý dữ liệu dễ dàng cho các mục đích truy vấn trong các cột được mã hóa T-SQL (có khả năng biến đổi).

Sử dụng NVARCHAR tránh tất cả điều này.

Tôi muốn giới thiệu NVARCHAR cho bất kỳ cột nào sẽ có dữ liệu do người dùng nhập vào trong đó tương đối không bị giới hạn.

Tôi muốn giới thiệu VARCHAR cho bất kỳ cột nào là khóa tự nhiên (như biển số xe, SSN, số sê-ri, thẻ dịch vụ, số đơn đặt hàng, số hiệu sân bay, vv) hoặc người dùng nhập, nhưng rất hạn chế (như số điện thoại) hoặc mã (ACTIVE/CLOSED, Y/N, M/F, M/S/D/W, v.v ...).Hoàn toàn không có lý do gì để sử dụng NVARCHAR cho những người đó.

Vì vậy, đối với một quy tắc đơn giản:

VARCHAR khi đảm bảo được chế NVARCHAR khác

+2

>> khi bạn có các ngôn ngữ khác nhau trong cùng một cột .... Đó là nó! –

+3

Cần lưu ý rằng * "các ngôn ngữ khác nhau" * không chỉ có nghĩa là các hàng khác nhau có thể chứa các giá trị từ các ngôn ngữ khác nhau. Nó cũng có nghĩa là nếu đối chiếu mặc định của cơ sở dữ liệu (tức là miền địa phương của máy chủ) khác với ngôn ngữ của bất kỳ máy tính khách nào. ví dụ. Máy chủ được đặt thành 'en-US', nhưng PC của tôi được đặt thành' fr-US'. –

+0

@IanBoyd Nói chung, đối chiếu sẽ có vấn đề cao khi trộn các ngôn ngữ trong một cột và trả về các mục bằng nhiều ngôn ngữ trong một bộ duy nhất và sử dụng đối chiếu đó để đặt hàng. Collation cũng có thể có ảnh hưởng đến các ký tự được kết hợp để được coi là một (Hungary dz và ly): http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue - nvarchar sẽ không giải quyết rằng –

3

Hy Lạp sẽ cần UTF-8 trên N loại cột: αβγ;)

10

Bạn nên sử dụng NVARCHAR bất cứ lúc nào bạn phải lưu trữ nhiều ngôn ngữ. Tôi tin rằng bạn phải sử dụng nó cho các ngôn ngữ châu Á nhưng không báo cho tôi về nó.

Đây là vấn đề nếu bạn lấy tiếng Nga ví dụ và lưu trữ nó trong một varchar, bạn sẽ được miễn là bạn xác định đúng trang mã. Nhưng giả sử bạn sử dụng cài đặt sql tiếng Anh mặc định, thì các ký tự tiếng Nga sẽ không được xử lý chính xác. Nếu bạn đang sử dụng NVARCHAR(), chúng sẽ được xử lý đúng cách.

Sửa

Ok tôi xin trích dẫn MSDN và maybee tôi là cụ thể nhưng bạn không muốn lưu trữ trang hơn sau đó một mã trong một cột varcar, trong khi bạn có thể bạn không nên

Khi bạn xử lý dữ liệu văn bản là được lưu trữ trong char, varchar, varchar (tối đa) hoặc loại dữ liệu văn bản, giới hạn quan trọng nhất cần xem xét là chỉ có thể xác thực thông tin từ một trang mã đơn . số hệ thống. (Bạn có thể lưu trữ dữ liệu từ nhiều trang mã, nhưng đây không phải là được đề nghị.) Trang mã chính xác được sử dụng để xác thực và lưu trữ dữ liệu phụ thuộc trên collation của cột. Nếu số đối chiếu cấp không được định nghĩa là , thì việc đối chiếu cơ sở dữ liệu được sử dụng. Để xác định mã trang được sử dụng cho một cột nào đó, bạn có thể sử dụng chức năng COLLATIONPROPERTY , như thể hiện trong đang ví dụ sau đây:

Dưới đây là một số chi tiết:

Ví dụ này minh họa thực tế rằng nhiều ngôn ngữ, chẳng hạn như Gruzia và Tiếng Hin-ddi, không có các trang mã, vì chúng là các đối chiếu chỉ Unicode.Những collations không thích hợp cho cột sử dụng char, varchar, hoặc kiểu dữ liệu văn bản

Vì vậy, Gruzia hay Tiếng Hin-ddi thực sự cần phải được lưu trữ như nvarchar. Ả Rập cũng là một vấn đề:

Một vấn đề bạn có thể gặp là không có khả năng lưu trữ dữ liệu khi không tất cả các ký tự mà bạn muốn hỗ trợ được chứa trong các mã trang. Trong nhiều trường hợp, Windows coi một trang mã cụ thể là trang "phù hợp nhất" phù hợp, có nghĩa là có không đảm bảo rằng bạn có thể dựa trên trang mã để xử lý tất cả văn bản; nó là chỉ là cái tốt nhất có sẵn. An ví dụ về điều này là chữ viết tiếng Ả Rập: nó hỗ trợ nhiều ngôn ngữ, bao gồm Baluchi, Berber, Farsi, Kashmiri, Kazakh, Kirghiz, Pashto, Sindhi, Uighur, Urdu và hơn thế nữa. Tất cả các các thứ tiếng có thêm nhân vật ngoài những người trong tiếng Ả Rập ngôn ngữ theo quy định trong Windows đang trang 1256. Nếu bạn cố gắng để lưu trữ những nhân vật phụ trong một cột phi Unicode có collation Ả Rập , các nhân vật được chuyển đổi thành dấu chấm hỏi.

Điều cần ghi nhớ khi bạn sử dụng Unicode mặc dù bạn có thể lưu trữ các ngôn ngữ khác nhau trong một cột, bạn chỉ có thể sắp xếp bằng một lần đối chiếu. Có một số ngôn ngữ sử dụng các ký tự latin nhưng không giống như các ngôn ngữ latin khác. Điểm nhấn là một ví dụ tốt về điều này, tôi không thể nhớ lại ví dụ nhưng có một ngôn ngữ Đông Âu mà Y không sắp xếp giống như tiếng Anh Y. Sau đó, có tiếng Tây Ban Nha mà tiếng Tây Ban Nha người dùng hết hạn để được sắp xếp sau h.

Tất cả trong tất cả các vấn đề bạn phải đối phó khi xử lý nội bộ hóa. Đó là ý kiến ​​của tôi đó là dễ dàng hơn để chỉ cần sử dụng các ký tự Unicode từ đầu, tránh các chuyển đổi thêm và mất không gian hit. Do đó tuyên bố của tôi trước đó.

+3

>> Bạn nên sử dụng NVARCHAR bất cứ khi nào bạn phải lưu trữ nhiều ngôn ngữ Điều này không đúng. Tiếng Đức và tiếng Ý và tiếng Anh phù hợp tốt trong cùng một bảng với các cột VARCHAR. Vui lòng cụ thể hơn –

+0

Xem http://www.sqlservercentral.com/Forums/Topic19439-9-1.aspx và http://stackoverflow.com/questions/7207590/sql-server-case-collation-issue để biết ví dụ với dz và ly bằng tiếng Hungary. –

2

Josh nói: " .... Một cái gì đó để giữ trong tâm trí khi bạn đang sử dụng Unicode mặc dù bạn có thể lưu trữ các ngôn ngữ khác nhau trong một cột duy nhất bạn chỉ có thể sắp xếp bằng cách sử dụng một đối chiếu duy nhất. Có một số ngôn ngữ sử dụng ký tự latin nhưng không giống như các ngôn ngữ latin khác. một ngôn ngữ Đông Âu có Y không giống như tiếng Anh Y. Sau đó, có tiếng Tây Ban Nha mà người dùng Tây Ban Nha hết hạn để được sắp xếp sau h. "

Tôi là một người Tây Ban Nha loa bản địa và "ch" không phải là một lá thư nhưng hai "c" và "h" và bảng chữ cái tiếng Tây Ban Nha cũng giống như: abcdefghijklmn ñ opqrstuvwxyz Chúng tôi không mong đợi "ch" sau " h "nhưng" i " Bảng chữ cái cũng giống như trong tiếng Anh ngoại trừ các chữ cái hoặc trong HTML" & ntilde; "

Alex

+0

Xin chào Alex, bạn đã bao giờ lưu trữ các ngôn ngữ khác nhau trong 1 cột chưa? Chúng tôi có các cột khác nhau cho các ngôn ngữ khác nhau trong 1 bảng. –

+0

Có lẽ họ đang nói đến tiếng Séc. Chúng ta có "ch" giữa "h" và "i" và nó là một chữ cái riêng biệt của bảng chữ cái. – jahav

0

TL; DR;
Unicode - (nchar, nvarchar và ntext)
Không unicode - (char, varchar và văn bản).

From MSDN

Collations trong SQL Server cung cấp phân loại quy tắc, trường hợp, và giọng tính nhạy cảm đối với dữ liệu của bạn. Các collations được sử dụng với các kiểu dữ liệu ký tự như char và varchar quyết định trang mã và các ký tự tương ứng có thể được biểu diễn cho dữ liệu đó .

Giả sử bạn đang sử dụng SQL mặc định đối chiếu SQL_Latin1_General_CP1_CI_AS sau đó kịch bản sau đây sẽ in ra tất cả các biểu tượng mà bạn có thể phù hợp trong VARCHAR vì nó sử dụng một byte để lưu trữ một ký tự (tổng cộng 256) nếu bạn không nhìn thấy nó trên danh sách được in - bạn cần NVARCHAR.

declare @i int = 0; 
while (@i < 256) 
begin 
print cast(@i as varchar(3)) + ' '+ char(@i) collate SQL_Latin1_General_CP1_CI_AS 
print cast(@i as varchar(3)) + ' '+ char(@i) collate Japanese_90_CI_AS 
set @i = @i+1; 
end 

Nếu bạn thay đổi đối chiếu để cho phép nói tiếng Nhật, bạn sẽ nhận thấy rằng tất cả các chữ cái châu Âu lạ thành một số ký hiệu thành ?.

Unicode là tiêu chuẩn để ánh xạ các điểm mã tới ký tự. Bởi vì , nó được thiết kế để bao gồm tất cả các ký tự của tất cả các ngôn ngữ của thế giới , không cần các trang mã khác nhau để xử lý các bộ ký tự khác nhau. Nếu bạn lưu trữ dữ liệu ký tự phản ánh nhiều ngôn ngữ , luôn sử dụng các loại dữ liệu Unicode (nchar, nvarchar và ntext) thay vì các loại dữ liệu không phải Unicode (char, varchar và văn bản).

Nếu không, sắp xếp của bạn sẽ trở nên kỳ lạ.

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