Двоичная сортировка PostgreSQL UTF-8

#postgresql #utf-8 #collation

#postgresql #utf-8 #сопоставление

Вопрос:

Я хотел бы иметь сопоставление, которое упорядочивает кодировку UTF-8 0x1234 ниже 0x1235 независимо от сопоставления символов в стандарте Unicode. MySQL использует для этого utf8_bin. MSSQL, по-видимому http://msdn.microsoft.com/en-us/library/ms143350.aspx есть параметры сортировки BIN и BIN2. Хотя найти их было легко, я даже не могу найти список сопоставлений, PostgreSQL поддерживает гораздо меньше ответов на этот конкретный вопрос.

Ответ №1:

Подойдет язык C. UTF-8 разработан таким образом, что порядок байтов также является порядком кодовых точек. Это не тривиально, но рассмотрим, как работает UTF-8:

Диапазон чисел Байт 1 Байт 2 Байт 3
0000-007F 0xxxxxxx
0080-07FF 110xxxxx 10xxxxxx
0800-FFFF 1110xxxx 10xxxxxx 10xxxxxx

При сортировке двоичных данных, например, языка C, порядок будет определяться первым неравным байтом. Что нам нужно, чтобы увидеть, что если два числа, закодированные в UTF-8, отличаются, то первый неравный байт будет меньше для меньшего значения. Если числа находятся в разных диапазонах, то первый байт действительно будет меньше для меньшего числа. В пределах того же диапазона порядок определяется буквально теми же битами, что и без кодирования.

Комментарии:

1. Это сортировка по кодовой точке, которая практически бесполезна в Unicode. Как заставить его выполнять правильную алфавитную сортировку, используя алгоритм сортировки, требуемый Unicode в его алгоритме сортировки Unicode?

2. @tchrist: Вопрос не в этом.

Ответ №2:

Порядок сортировки текста зависит от lc_collate (не от языкового стандарта системы!). Язык системы используется по умолчанию только при создании кластера БД, если вы не указали другой язык.

Ожидаемое поведение работает только с языковым C стандартом . Прочитайте все об этом в прекрасном руководстве:

Параметры сортировки C и POSIX определяют «традиционное поведение C», в котором только буквы ASCII от «A» до «Z» обрабатываются как буквы, а сортировка выполняется строго по значениям байтов символьного кода.

Акцент мой. В PostgreSQL 9.1 появилось несколько новых функций для сортировки. Может быть именно то, что вы ищете.

Комментарии:

1. Как заставить его выполнять сортировку по алфавиту вместо сортировки по кодовой точке? Вы знаете, чтобы он использовал алгоритм сортировки Unicode. В противном случае вы никогда не получите алфавитную сортировку текста в Юникоде.

2. @tchrist: Обычно вы lc_collate устанавливаете свой язык. Пример: в Англии вы, вероятно lc_collate , установили бы en_EN.utf8 значение . Попробуйте SHOW lc_collate; посмотреть ваши настройки. Перейдите по ссылке в моем ответе для получения дополнительной информации.

Ответ №3:

Postgres использует параметры сортировки, определенные системным языком при создании кластера.

Вы можете попытаться УПОРЯДОЧИТЬ ПО кодированию (столбец, ‘hex’)