Чому мій PostgreSQL ПОРЯДОК ВІДЧЕННІЙ до регістру?


27

У мене на Debian працює Postgres 9.4.4, і я отримую таку ORDER BYповедінку:

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

Однак на моєму iMac з Postgres 9.3.4 я отримую наступне:

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

Мене загадує, чому версія Debian видається нечутливою до регістру, а версія OS X - ні. Що мені не вистачає чи яку іншу інформацію мені потрібно надати?

Оновлення : У моєму Mac pg_collationтаблиця показує, що у мене є en_US.UTF-8порівняння, а на Debian - en_US.utf8порівняння. Таким чином, на моєму Mac:

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)

І на 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)

Так en_US.UTF-8і чи en_US.utf8є різні замовлення на сортування?


У мене немає Mac для тестування, тому я знімаю тут у темряві ... Будь-який шанс, що рядок 'D d a A c b CD Capacitor'не буде передано як textполе на Mac? IE, спробуйте SELECT regexp_split_to_table('D d a A c b CD Capacitor'::text, ' ') ORDER BY 1;і подивіться, що станеться ...
Кріс

Той самий результат. В інших новинах виявляється, що select * from pg_collationпоказано, що у вікні Debian є en_US.utf8, а в OS X є en_US.UTF-8. Використовуючи їх для явного примусового порівняння у відповідних полях, показано різні порядки сортування :(
Curtis Poe

І я опублікував оновлення, яке могло б пояснити проблему, але для мене це лише поглиблює таємницю. І я зараз знайшов це: stackoverflow.com/questions/19967555/… і це: stackoverflow.com/questions/27395317/…
Кертіс По

7
На жаль, Postgres використовує реалізацію порівняння з ОС, яка робить подібну поведінку ОС залежною (яку я особисто вважаю помилкою - СУБД повинна поводитися однаково незалежно від ОС). Таким чином, це зводиться до відмінностей у системних бібліотеках між Debian та OSX
a_horse_with_no_name

1
Між Postgres та іншими частинами системи виникне розбіжність, якщо порядок сортування не відповідатиме решті. Я теж віддаю перевагу однаковій поведінці, але я б не назвав це помилкою, щоб дотримуватися локальної системи. Зрештою, однакові локалі повинні поводитися однаково в межах ОС. Локаль Debian , здається, права , Apple , здається, що з вини (якщо немає якогось - то іншого пояснення).
Ервін Брандштеттер

Відповіді:


16

Так en_US.UTF-8і чи en_US.utf8є різні замовлення на сортування?

Ні, це обоє однакові, просто інша умова іменування.

Мене загадує, чому версія Debian видається нечутливою до регістру, а версія OS X - ні.

Так, ви праві. Це поведінка за замовчуванням на Mac. Збірники не працюють на будь-якій ОС BSD (включаючи OSX) для UTF8кодування.

Ось посилання на підтвердження того, що:

Проблеми з порядком сортування (локалі UTF8 не працюють

Як сказав a_horse_with_no_name , Postgres використовує реалізацію зіставлення з ОС. Неможливо отримати однаковий результат в обох операційних системах.

У вашому випадку ви можете (я , можливо , сказав) зробити так: ORDER BY lower(fieldname).


2
Не забудьте перевірити ефективність при використанні ORDER BY function()на потенційно великих наборах результатів - оскільки він зупиняє використання індексу для сортування, це майже напевно спричинить додаткову операцію сортування (можливо, на диску) і може змінити метод планувальника запитів більш широко атакувати ваш запит. .
Девід Спіллетт

@David Spillett: Ви маєте рацію щодо функції замовлення. Я думаю, що моя відповідь більш орієнтована на те, чому в ОП є різні способи сортування в iMac та Debian. Спасибі
JSapkota

1
Так, ваша відповідь ідеально чудова і повністю охоплює питання. Згадка про "тестування реальних даних після змін, які можуть вплинути на план запитів", стала для мене звичною реакцією (подібно до згадки про тестування в будь-якій дискусії про резервні копії та таке інше), як це легко забути (і це часто роблять люди) або навіть не знаю, якщо це стосується людей, які новіше працюють в базі даних.
Девід Спіллетт
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.