lập chỉ mục chống lại các chuỗi không phân biệt chữ hoa chữ thường nhưng trường hợp của dữ liệu vẫn tồn tại. Làm thế nào điều này thực sự hoạt động?
Đây thực sự không phải là một hành vi cụ thể của SQL Server, nó chỉ là cách những thứ này hoạt động nói chung.
Vì vậy, dữ liệu là dữ liệu. Nếu bạn đang nói về một chỉ mục cụ thể, dữ liệu cần được lưu trữ vì nó khác, nó sẽ yêu cầu tra cứu trong bảng chính mỗi lần để có được giá trị thực và sẽ không có khả năng chỉ mục bao phủ (tại ít nhất không phải cho các loại chuỗi).
Dữ liệu, trong chỉ mục bảng / chỉ mục cụm hoặc chỉ mục không phân cụm, không chứa bất kỳ thông tin đối chiếu / sắp xếp nào. Nó chỉ đơn giản là dữ liệu. Đối chiếu (quy tắc địa phương / văn hóa và độ nhạy) chỉ là dữ liệu meta được gắn vào cột và được sử dụng khi một thao tác sắp xếp được gọi (trừ khi bị ghi đè bởiCOLLATE
mệnh đề), trong đó bao gồm việc tạo / xây dựng lại một chỉ mục. Các quy tắc được xác định bởi đối chiếu không nhị phân được sử dụng để tạo khóa sắp xếp, là biểu diễn nhị phân của chuỗi (khóa sắp xếp là không cần thiết trong đối chiếu nhị phân). Các biểu diễn nhị phân này kết hợp tất cả các quy tắc địa phương / văn hóa và độ nhạy được chọn. Các khóa sắp xếp được sử dụng để đặt các bản ghi theo thứ tự đúng, nhưng chúng không được lưu trong chỉ mục hoặc bảng. Chúng không được lưu trữ (ít nhất là tôi chưa thấy các giá trị này trong chỉ mục và được thông báo rằng chúng không được lưu trữ) bởi vì:
- Chúng không thực sự cần thiết để sắp xếp vì chúng chỉ đơn thuần là theo thứ tự như các hàng trong bảng hoặc chỉ mục. Nhưng, thứ tự vật lý của chỉ số chỉ là sắp xếp, không so sánh.
- Trong khi lưu trữ chúng có thể giúp so sánh nhanh hơn, nó cũng sẽ làm cho chỉ mục lớn hơn vì kích thước tối thiểu cho một ký tự là 5 byte và đó chỉ là "chi phí chung" (của cấu trúc khóa sắp xếp). Hầu hết các ký tự có 2 byte mỗi ký tự, cộng với 1 byte nếu có dấu, cộng với 1 byte nếu là chữ hoa. Ví dụ: "e" là khóa 7 byte, "E" và "é" đều là 8 byte và "É" là khóa 9 byte. Do đó, không có giá trị lưu trữ những cuối cùng.
Có hai loại đối chiếu: SQL Server và Windows.
Máy chủ SQL
SQL Server collations (những người có tên bắt đầu với SQL_
) là lớn tuổi, trước SQL Server 2000 cách để sắp xếp / so sánh (mặc dù SQL_Latin1_General_CP1_CI_AS
là vẫn mặc định cài đặt trên hệ điều hành tiếng Anh-Mỹ, khá buồn bã). Trong mô hình cũ, đơn giản, không Unicode này, mỗi tổ hợp ngôn ngữ, trang mã và các độ nhạy khác nhau được cung cấp một ánh xạ tĩnh của từng ký tự trong trang mã đó. Mỗi ký tự được gán một giá trị (nghĩa là sắp xếp trọng lượng) để biểu thị cách nó tương đương với các ký tự khác. So sánh trong mô hình này dường như thực hiện thao tác hai lượt:
- Thứ nhất, nó loại bỏ tất cả dấu (ví dụ rằng " ü " trở thành " u '), mở rộng ký tự như' Æ " thành " Một " và " E ", sau đó thực hiện một loại ban đầu để từ đó đang ở trong một trật tự tự nhiên (làm thế nào bạn sẽ mong đợi để tìm thấy chúng trong một từ điển).
- Sau đó, nó đi từng ký tự để xác định sự bình đẳng dựa trên các giá trị cơ bản trên mỗi ký tự. Phần thứ hai này là những gì mustaccio đang mô tả trong câu trả lời của ông .
Các độ nhạy duy nhất có thể được điều chỉnh trong các va chạm này là: "trường hợp" và "dấu" ("chiều rộng", "loại kana" và "bộ chọn biến thể" không khả dụng). Ngoài ra, không có bộ sưu tập nào trong số các bộ sưu tập này hỗ trợ các Ký tự bổ sung (có nghĩa là những bộ này là đặc trưng cho Unicode và các bộ sưu tập này chỉ áp dụng cho dữ liệu không phải là Unicode).
Cách tiếp cận này chỉ áp dụng cho VARCHAR
dữ liệu phi Unicode . Mỗi kết hợp duy nhất của miền địa phương, trang mã, phân biệt chữ hoa chữ thường và độ nhạy của giọng nói có một "ID sắp xếp" cụ thể, bạn có thể thấy trong ví dụ sau:
SELECT COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CI_AS', 'SortID'), -- 52
COLLATIONPROPERTY(N'SQL_Latin1_General_CP1_CS_AS', 'SortID'), -- 51
COLLATIONPROPERTY(N'Latin1_General_100_CI_AS', 'SortID'); -- 0
Sự khác biệt duy nhất giữa hai lần va chạm đầu tiên là độ nhạy trường hợp. Đối chiếu thứ ba là đối chiếu Windows và do đó không có bảng ánh xạ tĩnh.
Ngoài ra, các đối chiếu này nên sắp xếp và so sánh nhanh hơn các đối chiếu Windows do việc tra cứu đơn giản để sắp xếp ký tự. Tuy nhiên, những va chạm này cũng ít chức năng hơn và thường nên tránh nếu có thể.
các cửa sổ
Các đối chiếu Windows (những tên có tên không bắt đầu SQL_
) là cách sắp xếp / so sánh mới hơn (bắt đầu trong SQL Server 2000). Trong mô hình Unicode mới, phức tạp, mới hơn này, mỗi sự kết hợp của miền địa phương, trang mã và các độ nhạy khác nhau không được đưa ra một ánh xạ tĩnh. Đối với một điều, không có trang mã trong mô hình này. Mô hình này gán một giá trị sắp xếp mặc định cho mỗi ký tự và sau đó mỗi miền / văn hóa có thể gán lại các giá trị sắp xếp cho bất kỳ số lượng ký tự nào. Điều này cho phép nhiều nền văn hóa sử dụng cùng một nhân vật theo những cách khác nhau. Điều này có ảnh hưởng đến việc cho phép nhiều ngôn ngữ được sắp xếp một cách tự nhiên bằng cách sử dụng cùng một đối chiếu nếu chúng không sử dụng cùng một ký tự (và nếu một trong số chúng không cần gán lại bất kỳ giá trị nào và chỉ có thể sử dụng mặc định).
Các giá trị sắp xếp trong mô hình này không phải là các giá trị đơn lẻ. Chúng là một mảng các giá trị gán trọng số tương đối cho chữ cái cơ sở, bất kỳ dấu phụ nào (nghĩa là dấu), vỏ, v.v. do đó, vô cảm). Nếu đối chiếu là nhạy cảm với dấu, thì phần "dấu phụ" của mảng được sử dụng, nếu không nó bị bỏ qua (do đó, không nhạy cảm).
So sánh trong mô hình này là một hoạt động nhiều vượt qua:
- Đầu tiên, chuỗi được chuẩn hóa để các cách biểu diễn khác nhau của cùng một ký tự sẽ được đánh đồng. Ví dụ: " ü " có thể là một ký tự / điểm mã (U + 00FC). Bạn cũng có thể kết hợp một tổ chức phi có dấu " u " (U + 0075) với một dấu tách đôi Kết hợp " ̈ " (U + 0308) để có được: " ü ", mà không chỉ trông giống nhau khi trả lại (trừ khi có một vấn đề với phông chữ của bạn), nhưng cũng được coi là giống với phiên bản ký tự đơn (U + 00FC), trừ khi sử dụng đối chiếu nhị phân (so sánh byte thay vì ký tự). Phá vỡ bình thường nhân vật duy nhất vào các mảnh khác nhau, trong đó bao gồm mở rộng cho các ký tự như " Æ " (như đã nêu ở trên cho SQL Server collation).
- Hoạt động so sánh trong mô hình này đi từng ký tự theo từng độ nhạy . Các khóa sắp xếp cho các chuỗi được xác định bằng cách áp dụng các yếu tố thích hợp của từng mảng đối chiếu các giá trị dựa trên độ nhạy nào là "nhạy cảm". Các giá trị khóa sắp xếp được sắp xếp theo tất cả các độ nhạy chính của từng ký tự (ký tự cơ sở), theo sau là tất cả các độ nhạy thứ cấp (trọng lượng dấu phụ), tiếp theo là trọng lượng trường hợp của mỗi ký tự, v.v.
- Sắp xếp được thực hiện dựa trên các phím sắp xếp được tính toán. Với mỗi độ nhạy được nhóm lại với nhau, bạn có thể nhận được một thứ tự sắp xếp khác nhau so với đối chiếu SQL Server tương đương khi so sánh các chuỗi gồm nhiều ký tự và các dấu có liên quan và đối chiếu là nhạy cảm với dấu (và thậm chí còn hơn thế nếu đối chiếu là cũng phân biệt chữ hoa chữ thường).
Để biết thêm chi tiết về cách sắp xếp này, cuối cùng tôi sẽ xuất bản một bài đăng hiển thị các giá trị khóa sắp xếp, cách tính toán, sự khác biệt giữa các máy chủ SQL và Windows, v.v. Nhưng bây giờ, vui lòng xem câu trả lời của tôi về: Sắp xếp nhạy cảm theo dấu ( xin lưu ý rằng câu trả lời khác cho câu hỏi đó là một lời giải thích tốt về thuật toán Unicode chính thức, nhưng SQL Server thay vào đó sử dụng một thuật toán tùy chỉnh, mặc dù tương tự và thậm chí là bảng cân tùy chỉnh).
Tất cả các độ nhạy có thể được điều chỉnh trong các va chạm này: "trường hợp", "dấu", "chiều rộng", "kiểu kana" và "bộ chọn biến thể" (bắt đầu trong SQL Server 2017 và chỉ cho các bộ sưu tập của Nhật Bản). Ngoài ra, một số đối chiếu này (khi được sử dụng với dữ liệu Unicode) hỗ trợ các Ký tự bổ sung (bắt đầu trong SQL Server 2012). Cách tiếp cận này áp dụng cho cả hai NVARCHAR
và VARCHAR
dữ liệu (ngay cả dữ liệu không phải là Unicode). Nó áp dụng cho VARCHAR
dữ liệu không phải là Unicode bằng cách trước tiên chuyển đổi giá trị sang Unicode bên trong, sau đó áp dụng các quy tắc sắp xếp / so sánh.
Xin lưu ý:
- Không có đối chiếu mặc định chung cho SQL Server. Có một mặc định cài đặt khác nhau dựa trên cài đặt ngôn ngữ / ngôn ngữ hiện tại của HĐH tại thời điểm cài đặt (không may
SQL_Latin1_General_CP1_CI_AS
cho các hệ thống tiếng Anh Mỹ, vì vậy vui lòng bỏ phiếu cho đề xuất này ). Điều này có thể được thay đổi trong quá trình cài đặt. Đối chiếu mức cá thể này sau đó đặt đối chiếu cho [model]
DB là mẫu được sử dụng khi tạo DB mới, nhưng đối chiếu có thể được thay đổi khi thực hiện CREATE DATABASE
bằng cách chỉ định COLLATE
mệnh đề. Đối chiếu mức cơ sở dữ liệu này được sử dụng cho các biến số và chuỗi ký tự, cũng như mặc định cho các cột mới (và đã thay đổi!) Khi COLLATE
mệnh đề không được chỉ định (đó là trường hợp cho mã ví dụ trong câu hỏi).
- Để biết thêm thông tin về Collations / encodes / Unicode, vui lòng truy cập: Collations Info