Tại sao PostgreQuery của tôi ĐẶT HÀNG theo trường hợp không nhạy cảm?


27

Tôi có Postgres 9.4.4 chạy trên Debian và tôi có ORDER BYhành vi sau :

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)

uname -a:

Linux ---- 3.2.0-4-amd64 #1 SMP Debian 3.2.65-1 x86_64 GNU/Linux

Tuy nhiên, trên iMac của tôi, với Postgres 9.3.4, tôi nhận được những điều sau:

veure_test=# show LC_COLLATE;
 lc_collate  
-------------
 en_US.UTF-8
(1 row)

veure_test=# SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') ORDER BY 1;
 regexp_split_to_table 
-----------------------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)

uname -a:

Darwin ---- 14.4.0 Darwin Kernel Version 14.4.0: Thu May 28 11:35:04 PDT 2015; root:xnu-2782.30.5~1/RELEASE_X86_64 x86_64

Tôi đang bối rối tại sao phiên bản Debian dường như không phân biệt chữ hoa chữ thường và phiên bản OS X thì không. Tôi còn thiếu gì, hoặc tôi cần cung cấp thông tin gì khác?

Cập nhật : Trên máy Mac của tôi, pg_collationbảng hiển thị tôi có en_US.UTF-8đối chiếu, nhưng trên Debian, tôi có en_US.utf8đối chiếu. Do đó, trên máy Mac của tôi:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.UTF-8";                                                                                                                                                                                      
    bar    
-----------
 A
 CD
 Capacitor
 D
 a
 b
 c
 d
(8 rows)

Và trên Debian:

veure_test=# with foo as (
SELECT regexp_split_to_table('D d a A c b CD Capacitor', ' ') as bar
   )
SELECT bar FROM foo
ORDER BY bar collate "en_US.utf8";
    bar    
-----------
 a
 A
 b
 c
 Capacitor
 CD
 d
 D
(8 rows)

Vì vậy, en_US.UTF-8en_US.utf8có thứ tự sắp xếp khác nhau?


Tôi không có máy Mac để kiểm tra, vì vậy tôi đang chụp trong bóng tối ở đây ... Bất kỳ cơ hội nào mà chuỗi 'D d a A c b CD Capacitor'không được sử dụng như một texttrường trên máy Mac? IE, hãy thử SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;và xem điều gì sẽ xảy ra ...
Chris

Cùng một kết quả. Trong các tin tức khác, hóa ra select * from pg_collationhộp Debian có en_US.utf8, trong khi OS X thì có en_US.UTF-8. Sử dụng chúng để buộc đối chiếu rõ ràng trên các hộp tương ứng sẽ hiển thị các thứ tự sắp xếp khác nhau :(
Curtis Poe

Và tôi đã đăng một bản cập nhật có thể giải thích vấn đề, nhưng đối với tôi, nó chỉ làm sâu sắc thêm bí ẩn. Và bây giờ tôi đã tìm thấy cái này: stackoverflow.com/questions/19967555/ và cái này: stackoverflow.com/questions/27395317/ trộm
Curtis Poe

7
Thật không may, Postgres sử dụng triển khai đối chiếu từ HĐH, điều này làm cho loại hành vi này phụ thuộc vào HĐH (mà cá nhân tôi coi là một lỗi - một DBMS nên hoạt động giống hệt nhau bất kể HĐH). Vì vậy, điều này rút ra sự khác biệt trong các thư viện hệ thống giữa Debian và OSX
a_horse_with_no_name 14/07/2015

1
Sẽ có sự bất đồng giữa Postgres và các bộ phận khác của hệ thống nếu thứ tự sắp xếp không phù hợp với phần còn lại. Tôi cũng vậy, thích hành vi giống hệt nhau, nhưng tôi sẽ không gọi đó là lỗi để theo địa phương hệ thống. Cuối cùng, các địa phương giống hệt nhau nên hành xử giống hệt nhau trên HĐH. Các locale Debian dường như đúng , Apple có vẻ là có lỗi (trừ khi có một số giải thích khác).
Erwin Brandstetter

Câu trả lời:


16

Vì vậy, en_US.UTF-8en_US.utf8có thứ tự sắp xếp khác nhau?

Không, cả hai đều giống nhau, chỉ là một quy ước đặt tên khác nhau.

Tôi đang bối rối tại sao phiên bản Debian dường như không phân biệt chữ hoa chữ thường và phiên bản OS X thì không.

Ừ bạn đúng rồi đó. Đây là hành vi mặc định trên Mac. Các bộ sưu tập không hoạt động trên bất kỳ HĐH BSD-ish nào (bao gồm OSX) để UTF8mã hóa.

Dưới đây là một tài liệu tham khảo để chứng minh rằng:

Các sự cố với thứ tự sắp xếp (ngôn ngữ UTF8 không hoạt động

Như a_horse_with_no_name đã nói, Postgres sử dụng triển khai đối chiếu từ HĐH. Không có cách nào để có được kết quả tương tự trên cả hai hệ điều hành.

Trong trường hợp của bạn, bạn có thể (tôi nói có thể) làm như thế này : ORDER BY lower(fieldname).


2
Hãy cẩn thận để xác minh hiệu suất khi sử dụng ORDER BY function()trên các kết quả có khả năng lớn - vì nó dừng một chỉ mục được sử dụng cho sắp xếp, nó gần như chắc chắn sẽ gây ra một hoạt động sắp xếp bổ sung (có thể trên đĩa) và nó có thể thay đổi phương thức tấn công truy vấn của bạn rộng rãi hơn .
David Spillett

@David Spillett: Bạn nói đúng về chức năng Đặt hàng. Tôi nghĩ rằng câu trả lời của tôi tập trung nhiều hơn vào lý do tại sao OP lại có kiểu sắp xếp khác nhau trong iMac và Debian. Cảm ơn
JSapkota

1
Vâng, câu trả lời của bạn là hoàn toàn tốt và bao gồm các câu hỏi hoàn toàn. Việc đề cập "kiểm tra dữ liệu thực sau các thay đổi có thể ảnh hưởng đến kế hoạch truy vấn" đã trở thành một phản ứng theo thói quen trong tôi (giống như đề cập đến kiểm tra trong bất kỳ cuộc thảo luận nào về các bản sao lưu, v.v.) vì nó rất dễ quên (và mọi người thường làm) hoặc thậm chí không biết trong trường hợp những người mới hơn làm việc với cơ sở dữ liệu.
David Spillett
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.