Người vận hành khác nhau
LIKE
và =
là các nhà khai thác khác nhau. Hầu hết các câu trả lời ở đây tập trung vào hỗ trợ ký tự đại diện, đây không phải là điểm khác biệt duy nhất giữa các nhà khai thác này!
=
là một toán tử so sánh hoạt động trên các số và chuỗi. Khi so sánh các chuỗi, toán tử so sánh so sánh toàn bộ chuỗi .
LIKE
là một toán tử chuỗi so sánh từng ký tự .
Để làm phức tạp vấn đề, cả hai nhà khai thác sử dụng một đối chiếu có thể có tác động quan trọng đến kết quả so sánh.
Ví dụ tạo động lực
Trước tiên chúng ta hãy xác định một ví dụ trong đó các toán tử này tạo ra các kết quả rõ ràng khác nhau. Cho phép tôi trích dẫn từ hướng dẫn sử dụng MySQL:
Theo tiêu chuẩn SQL, THÍCH thực hiện khớp trên cơ sở mỗi ký tự, do đó, nó có thể tạo ra kết quả khác với toán tử so sánh:
mysql> SELECT 'ä' LIKE 'ae' COLLATE latin1_german2_ci;
+-----------------------------------------+
| 'ä' LIKE 'ae' COLLATE latin1_german2_ci |
+-----------------------------------------+
| 0 |
+-----------------------------------------+
mysql> SELECT 'ä' = 'ae' COLLATE latin1_german2_ci;
+--------------------------------------+
| 'ä' = 'ae' COLLATE latin1_german2_ci |
+--------------------------------------+
| 1 |
+--------------------------------------+
Xin lưu ý rằng trang này của hướng dẫn sử dụng MySQL được gọi là Hàm so sánh chuỗi và =
không được thảo luận, hàm ý đó =
không hoàn toàn là chức năng so sánh chuỗi.
Làm thế nào không =
làm việc?
Các SQL Standard § 8.2 mô tả cách =
so sánh chuỗi:
Việc so sánh hai chuỗi ký tự được xác định như sau:
a) Nếu độ dài tính bằng ký tự của X không bằng độ dài tính bằng ký tự của Y, thì chuỗi ngắn hơn được thay thế một cách hiệu quả, với mục đích so sánh, với một bản sao của chính nó đã được mở rộng theo chiều dài của chuỗi dài hơn bằng cách ghép ở bên phải của một hoặc nhiều ký tự pad, trong đó ký tự pad được chọn dựa trên CS. Nếu CS có thuộc tính NO PAD, thì ký tự pad là ký tự phụ thuộc vào triển khai khác với bất kỳ ký tự nào trong bộ ký tự X và Y đối chiếu ít hơn bất kỳ chuỗi nào trong CS. Nếu không, ký tự pad là a.
b) Kết quả so sánh X và Y được đưa ra bởi chuỗi đối chiếu CS.
c) Tùy thuộc vào chuỗi đối chiếu, hai chuỗi có thể so sánh bằng nhau ngay cả khi chúng có độ dài khác nhau hoặc chứa các chuỗi ký tự khác nhau. Khi các hoạt động MAX, MIN, DISTINCT, tham chiếu đến một nhóm nhóm và các toán tử UNION, EXCEPT và INTERSECT tham chiếu đến các chuỗi ký tự, giá trị cụ thể được chọn bởi các hoạt động này từ một tập hợp các giá trị bằng nhau như vậy phụ thuộc vào việc triển khai.
(Nhấn mạnh thêm.)
Điều đó có nghĩa là gì? Nó có nghĩa là khi so sánh các chuỗi, =
toán tử chỉ là một trình bao bọc mỏng xung quanh đối chiếu hiện tại. Đối chiếu là một thư viện có các quy tắc khác nhau để so sánh các chuỗi. Đây là một ví dụ về đối chiếu nhị phân từ MySQL :
static int my_strnncoll_binary(const CHARSET_INFO *cs __attribute__((unused)),
const uchar *s, size_t slen,
const uchar *t, size_t tlen,
my_bool t_is_prefix)
{
size_t len= MY_MIN(slen,tlen);
int cmp= memcmp(s,t,len);
return cmp ? cmp : (int)((t_is_prefix ? len : slen) - tlen);
}
Đối chiếu cụ thể này xảy ra để so sánh từng byte (đó là lý do tại sao nó được gọi là "nhị phân" - nó không mang lại bất kỳ ý nghĩa đặc biệt nào cho chuỗi). Các đối chiếu khác có thể cung cấp so sánh nâng cao hơn.
Ví dụ, đây là một đối chiếu UTF-8 hỗ trợ so sánh không phân biệt chữ hoa chữ thường. Mã quá dài để dán ở đây, nhưng đi đến liên kết đó và đọc phần thân của my_strnncollsp_utf8mb4()
. Đối chiếu này có thể xử lý nhiều byte cùng một lúc và nó có thể áp dụng các biến đổi khác nhau (chẳng hạn như so sánh không phân biệt chữ hoa chữ thường). Các =
nhà điều hành là hoàn toàn trừu tượng từ những thay đổi bất thường của đối chiếu.
Làm thế nào không LIKE
làm việc?
Các SQL Standard § 8,5 mô tả cách LIKE
so sánh chuỗi:
<Vị ngữ>
M LIKE P
là đúng nếu tồn tại phân vùng M thành các chuỗi con sao cho:
i) Một chuỗi con của M là một chuỗi từ 0 hoặc nhiều hơn <biểu diễn ký tự> s của M và mỗi <biểu diễn ký tự> của M là một phần của chính xác một chuỗi con.
ii) Nếu bộ xác định chuỗi con thứ i của P là một bộ xác định ký tự tùy ý, thì chuỗi con thứ i của M là bất kỳ <biểu diễn ký tự> nào.
iii) Nếu bộ xác định chuỗi con thứ i của P là một bộ xác định chuỗi tùy ý, thì chuỗi con thứ i của M là bất kỳ chuỗi nào từ 0 trở lên <biểu diễn ký tự> s.
iv) Nếu trình xác định chuỗi con thứ i của P không phải là trình xác định ký tự tùy ý cũng không phải là trình xác định chuỗi tùy ý, thì chuỗi con thứ i của M bằng với trình xác định chuỗi con đó theo trình tự đối chiếu của <như vị ngữ>, không có việc thêm các ký tự <dấu cách> vào M và có cùng độ dài với trình xác định chuỗi con đó.
v) Số lượng chuỗi con của M bằng số lượng chỉ định chuỗi con của P.
(Nhấn mạnh thêm.)
Điều này khá dài dòng, vì vậy hãy phá vỡ nó. Các mục ii và iii lần lượt đề cập đến các ký tự đại diện _
và %
. Nếu P
không chứa bất kỳ ký tự đại diện nào, thì chỉ áp dụng mục iv. Đây là trường hợp quan tâm được đặt ra bởi OP.
Trong trường hợp này, nó so sánh từng "chuỗi con" (các ký tự riêng lẻ) M
với từng chuỗi con trong P
việc sử dụng đối chiếu hiện tại.
Kết luận
Điểm mấu chốt là khi so sánh các chuỗi, =
so sánh toàn bộ chuỗi trong khi LIKE
so sánh một ký tự tại một thời điểm. Cả hai so sánh sử dụng đối chiếu hiện tại. Sự khác biệt này dẫn đến kết quả khác nhau trong một số trường hợp, được chứng minh trong ví dụ đầu tiên trong bài viết này.
Bạn nên sử dụng cái nào? Không ai có thể nói với bạn điều đó - bạn cần sử dụng một cái đúng cho trường hợp sử dụng của bạn. Đừng tối ưu hóa sớm bằng cách chuyển đổi các toán tử so sánh.