Мир InterBase. Архитектура, администрирование и разработка приложений баз данных в InterBase/FireBird/Yaffil
Шрифт:
Хранение символьных данных без использования наборов символов
Считать данные таблицы, в которой символьные поля имеют разные наборы символа с помощью одного SQL-запроса также не получится, если мы укажем один из трех наборов данных, то InterBase попытается привести все данные к этому набору, а это может у него не получиться - и тогда возникнет ошибка "Cannot transliterate characters between character sets".
Однако существует еще один, недокументированный способ хранить в базе данных символы из различных наборов. Этот способ заключается в том, чтобы вообще не указывать набор символов, тогда по умолчанию будет применять character set NONE, использование которого дает понять InterBase, что символьные данные должны храниться так, как они есть, без всяких интерпретаций. При этом всю ответственность
Казалось бы, надо всегда пользоваться CHARACTER SET NONE и избегать различных проблем, однако, отказываясь от наборов символов, мы отказываемся и от полезных свойств, которые они с собой несут. Прежде всего, использование CHARACTER SET, а, точнее, их COLLATION ORDERS (способов упорядочения) позволяет корректно сортировать русские символы и приводить их к верхнему регистру.
Дело в том, что по умолчанию русские буквы сортируются в двоичном порядке, т. е. в соответствии с порядком расположения кодов символов. При этом строчные буквы располагаются после прописных, а буква "Ы" вообще располагается отдельно. Чтобы заставить их сортироваться правильно, надо указать способ упорядочения, т. е. COLLATION ORDER.
Вносим ясность
У начинающих разработчиков часто возникает путаница в голове от многочисленных опций, определяющих поведение InterBase с русскими буквами. Вероятно, дочитав до этого места, вы уже достаточно запутались во множестве взаимнопересекающихся определений. Чтобы внести ясность в эти понятия, давайте еще раз их прокомментируем.
Основа всего - символьные типы InterBase, которые позволяют хранить в каждом поле до 32767 байт. Однако байты в общем случае не равнозначны символам, потому что в различных системах кодировки для представления одного символа могут использоваться 1, 2 или даже 3 байта. Таким образом, когда мы определяем поле типа CHAR или VARCHAR, то мы задаем количество символов, которые там могут поместиться, а количество байтов определяется умножением заданной длины на максимальный размер символа для данного набора символов Для набора символов WIN1251 любой символ занимает 1 байт, поэтому размер поля в байтах будет равен объявленной длине. А вот при использовании кодировки UNICODE_FSS максимальный размер символа составляет 3 байта; таким образом, реальная длина поля будет равна утроенному объявленному размеру. Вы не сможете создать поле с кодировкой UNICODE_FSS с длиной более чем 32767 div 3 = 10921 символ. В то же время реальный размер символа может быть меньше максимального, использовавшегося InterBase для расчета размера поля, т. е. вы сможете записать в такое поле больше символов, чем его объявленная длина!
Наборы символов (CHARACTER SET) - это фактически таблицы перекодировки физического представления (где один символ занимает 2 или 3 байта) в желаемое (т. е. такое, каким эти символы хотят видеть соответствующие клиентские приложения).
В InterBase существует множество наборов символов, полный список которых можно найти в документации по InterBase. Каждый набор символов использует для хранения тех или иных символов разное количество байт. Проще говоря, это таблица, где каждому символу поставлен в соответствие 1- или 2- или 3-байтовый код.
Когда мы создаем символьное поле и указываем набор символов явно или с помощью установок по умолчанию, то в этом случае мы неявно задаем, сколько символов поместится в это поле. Например, набор символов UNICODE_FSS использует 2 байта для кодирования русских букв. Следовательно, мы можем поместить в поле, объявленное как VARCHAR(255) CHARACTER SET UNICODE_FSS, количество русских символов, равное 255 * 3 div 2, т. е. 382.
Далее, каждый набор символов (CHARACTER SET) имеет свой порядок сортировки по умолчанию. Очень часто этот порядок сортировки не отражает принятую в языке сортировку конкретных символов. Например, русский набор символов WIN1251 неправильно сортирует символы русского алфавита, т. е. сортирует их в порядке следования двоичных кодов символов.
Как же изменить сортировку символов по умолчанию внутри набора символов? Для этого применяются порядки (или способы) сортировки наборов символов - так называемые COLLATION ORDERS. Дополнительно с каждым COLLATION ORDER связаны таблицы преобразования в нижний и верхний регистр. Для каждого набора символов существуют свои определенные
порядки сортировки Например, для самого распространенного русского набора символов WIN1251 существуют два способа сортировки: WIN1251, который задается по умолчанию, и опциональная сортировка PWX_CYRL. В порядке сортировки PXW_CYRL одни и те же прописные и строчные буквы имеют одинаковый вес, т. е. этот порядок сортировки не зависит от регистра символов (case insensitive). Русские буквы будут располагаться в следующем порядке: аАбБвВ...яЯ.Как устроены способы сортировки? В COLLATION ORDERS строится дополнительная таблица пересортировки, определяющая порядок (условный вес) символов при сортировке. И в этой таблице для представления порядка символа может использоваться несколько байтов (2 или 3, например). В частности, в COLLATION ORDER WIN1251 используется 1 байт для представления символа и его порядка, а в опциональной PWX_CYRL - целых 3 байта!
Размер представления веса символа в таблице порядка сортировки имеет значение при использовании индексов по полям символьных типов данных. Дело в то, что в индексе хранятся не исходные символьные строки, а ключи, полученные из строки на основе таблицы сортировки. Размер ключа может быть больше размера исходной строки: так, для порядка сортировки PXW_CYRL размер ключа может быть больше максимум в 3 раза, чем исходная строка. InterBase использует максимальный коэффициент для ограничения размера индекса по символьным полям. Таким образом, при максимальном размере индекса 254 байта вы не сможете создать индекс по полю с длиной более 254 div 3 = 84 символа Поэтому использование COLLATION ORDER может оказаться вещью, требующей достаточно многих ресурсов. Тем не менее весь вопрос в том, как ее применять Параметр COLLATE можно использовать и по требованию, прямо в тексте запроса, не указывая его в самом определении поля Когда мы указываем в запросе использовать для сортировки или приведения к верхнему регистру какой-либо способ сортировки, то InterBase сам достраивает данные из этого поля с учетом указанного способа
Использовать конкретный COLLATE в запросе очень легко, правда, в этом случае не может быть использован индекс:
SELECT *
FROM table1
ORDER BY SYMBOLIC_FIELD1 COLLATE PXW_CYRL
Другой пример - для встроенной функции UPPER.
SELECT UPPER(fieldl COLLATE PXW_CYRL) From tablel
Этот способ является наиболее гибким: хранить можно лишь сами символы, а специальный порядок сортировки применять, только когда это требуется.
Русификация клиентских приложений InterBase
Разобравшись с русификацией баз данных InterBase и с тем, как обеспечить хранение и интерпретацию символов на уровне базы данных, необходимо рассмотреть вопрос о том, как сделать так, чтобы клиентские приложения могли корректно читать и записывать символьные данные.
Принцип здесь очень простой: при подключении к базе данных в клиентских приложениях необходимо указать точно такой же набор символов, как и в самой базе данных. В этом случае передаваемые данные будут интерпретироваться правильно и появляться у пользователя на экране в виде корректных символов, а не бессмысленных значков.
Способ указания того, какой набор символов использовать, различен для каждой библиотеки доступа. Для библиотек FEBPlus и ЕВХ для подключения к базе данных с набором символов, например, WIN125I, нужно указать в параметрах подключения lc_type=WIN1251.
Для работы с базами данных, использующими WIN1251, через Borland Database Engine необходимо указать в параметрах псевдонима LANGDRJVER=PDOX ANSI Cyrr.
Для работы с базой данных через JDBC необходимо указать в настройках драйвера строку charset=cp!251 (подробнее см. в главе "Разработка клиента InterBase на Java" (ч. 3)).
Собственные наборы символов и способы сортировки
Сами кодировки хранятся в файле gdsintl.dll, который находится в каталоге %INTERBASE%\Intl. Вы можете самостоятельно разрабатывать и подключать свои собственные наборы символов и COLATION ORDERS в InterBase и во все его клоны. Для их разработки существует специальный инструментарий, ссылки на который вы можете найти на сайте www InterBase-world.com.
Транзакции. Параметры транзакций