Выпуск 4
« РСУБД Sybase
ASA 9 - мощность, легкость и надежность »
Рассылка N
4 |
Здравствуйте, уважаемые
коллеги. Я продолжаю выпуск рассылки, посвященный Sybase ASA 9.
Содержание рассылки:
-
Рекомендации по
установке Developer версии для Linux
-
Оптимизация
работы Sybase Central и ISQL
-
Особенности уникальных ограничений таблиц
-
Правила на таблицы и поля
-
Связи таблиц и каскадные операции
-
Индексы, уникальные и кластерные индексы
Рекомендации по установке Developer
версии для Linux |
Поскольку я являюсь обычным пользователем Линукса, то в качестве
базовой ОС, для установки ASA, я выбрал дистрибутив Mandrake 9.2 . На примере
этого дистрибутива я и опишу, с какими проблемами мне пришлось столкнуться во
время инсталляции:
-
Инсталляцию желательно делать, находясь под root-ом, хотя в
документации ASA написано, что не важно, с какими правами
пользователь.
-
Распакуйте выкаченный архив с инсталляцией ASA, зайдите в
распаковавшуюся папку SYBSasaEval и запустите setup.
-
По ходу инсталляции выберите свой регион, прочитайте и
согласитесь с лицензией, введите полученный по почте от Sybase серийный номер,
пометьте какие компоненты необходимо инсталлировать. Я рекомендую согласиться
с предлагаемым инсталляцией путем установки (/opt/sybase), иначе придется
переписывать конфигурационные файлы (хотя для Mandrake 9.2 их все равно
править придется).
-
После инсталляции
зайдите в папку /opt/sybase/SYBSsa9/bin . В ней есть 2 конфигурационных файла:
asa_config.sh и asa_config.csh . В этих файлах прописаны необходимые для
запуска ASA пути и переменные окружения. Если Вы инсталлировали не в
предлагаемые по умолчанию пути, то Вам .необходимо исправить пути в этих
файлах. Скопируйте эти файлы в папку /etc/profile.d и не забудьте им
проставить соответствующие права доступа запуска для нужных групп и
пользователей.
-
Не знаю почему, но в
Mandrake 9.2 JRE, входящая в комплект ASA не работает. Если ASA не захочет
запускаться или же откажутся работать Sybase Central и утилиты, то я
рекомендую зайти на http://www.sun.com/ и
скачать последнюю версию JRE 1.4.2.03 для Линукса. Запустите ее установку, и
все, что получилось в созданной инсталляцией Java папке, скопируйте в папку
/opt/sybase/shared/jre_1.4.1_linux_sun_i386 . Будьте только внимательными, так
как в папке /opt/sybase/shared/jre_1.4.1_linux_sun_i386/man есть символическая
ссылка и поверх нее ничего копировать не надо, чтобы не получить рекурсию
копирования.
-
Для запуска
визуальных утилит необходимо проверить, что установлена переменная DISPLAY (в
Mandrake 9.2 она почему то не установлена). Напишите в консоли: echo $DISPLAY
. Если ничего не будет возвращено, то необходимо зайти в папку /etc и в конце
файла profile последней строчкой написать: export DISPLAY = 127.0.0.1:0.0
-
Теперь можно
запускать саму ASA. Напишите в консоли: dbsrv9 <Option>
<DatabaseFileName> и если все правильно, то сервер стартует. Не
забудьте, что на файлы базы данных должны быть установлены все нужные права
чтения и записи для пользователя той сессии, из которой запускается ASA.
-
Осталось последнее,
запуск Sybase Central и ISQL. Для этого стартуйте XServer, если он еще не
запущен, командой startx. Вы можете запустить утилиты как с консоли командами
scjview и dbisql, или же сделав соответствующие ярлыки запуска на рабочем
столе Вашего установленного оконного менеджера.
Оптимизация работы Sybase Central и
ISQL |
Визуальные утилиты ASA написаны на Java, что с одной стороны хорошо, так
как они кроссплатформенны и работают на любой ОС в едином визуальном стиле. С
другой стороны Java к сожалению из за этого очень требовательна к процессору и
памяти, что приводит к торможению работы ее приложений из за перидической сборки
мусора. Эту ситуацию немного можно поправить, увеличив для Java параметры
управления памятью, что особо актуально для ISQL, который при работе с большими
по размеру скриптами может выдать ошибку: Out of memory. Для этого в ярлыки
запуска Sybase Central и ISQL добавьте к запускаемым приложениям следующие
параметры: -Xms<StartMemSize> -Xmx<MaxMemSize> , где StartMemSize –
это минимальный объем памяти приложения в байтах, а MaxMemSize – максимально
допустимый использующийся обьем памяти в байтах. По умолчанию Java запускает
приложения с минимальным объемом 2мб и максимальным 64мб, что для утилит ASA не
является хорошим решением. Если памяти на машине достаточно, то я рекомендую
запускать Sybase Central с объемом 64мб/128мб и ISQL с 32мб/160мб. Чем больше Вы
дадите максимальной памяти для java приложения, тем быстрее оно будет работать
за счет того, что будет реже производиться сборка мусора, которая во время
процесса парализует работу приложений, и реже получать сообщения о нехватке
памяти.
Особенности уникальных ограничений
таблиц (unique constraints) |
Ничем не отличаются от аналогичных уникальных ограничений в других РСУБД
и являются по своей сути обычными уникальными индексами, которые так же
участвуют наравне с индексами таблицы в планах запросов и даже могут выступать в
роли кластерных индексов. Единственное их отличие от уникальных индексов – они
не могут указывать на NULL поля, в отличие например от MSSQL, где это
разрешено.
Правила на таблицы и поля (check
constraints) |
Как Вы уже поняли, в ASA существует два вида правил для поддержки
целостной ссылочности информации. В правилах можно пользоваться системными и UDF
функциями, однако при использовании UDF всегда стоит помнить, что при генерации
скрипта базы данных любой Case инструмент и сама ASA будет прописывать создание
UDF в скрипте позже, чем создание структуры таблиц и без ручной правки такой
скрипт запуститься не сможет. Это замечание относится не только к правилам, но и
к использованию UDF для вычисляемых полей. В ASA не поддерживаются глобальные
правила и умолчания и команды CREATE RULE и CREATE DEFAULT. Для стандартизации
правил и умолчаний в ASA можно воспользоваться доменами и через них прописывать
нужные правила и умолчания.
Table check
constraint: |
Позволяет прописать
правило, в котором разрешаются проверка всех полей таблицы. Например,
следующее правило проверяет, что нельзя заносить товар с кодом 100, если
дата оформления заказа была произведена ранее 1 января 2004
года: |
(Product_id <> 100 or
SaleDate <> '20040101') |
Column
check constraint: |
Позволяет
прописать правило на указанное поле таблицы. Использование в правиле
ссылок на другие поля таблицы не разрешено. Очевидным преимуществом такого
рода правил несомненно является улучшение производительности на операции
вставки и изменения записей, где правило на таблицу вызывается всегда, а
правило на поле будет вызвано только в случае его реального изменения. В
следующем правиле проверяется категория пользователя, которая может
содержать числа в интервале от 1 до 5: |
(CategoryUser between 1 and
5) |
Связи таблиц и каскадные операции
(foreign keys) |
Как и в других РСУБД, в ASA поддерживается организация целостной
ссылочности данных через внешние ключи (в дальнейшем FK). FK можно
организовывать на ключевой индекс (Primary Key) любой таблицы, если он у нее
присутствует. FK могут быть nullable, если поле внешнего ключа разрешает NULL
значения и указанна соответствующая опция при создании FK. Это позволяет
создавать внешние ключи, которые не обязательно должны ссылаться на ключ
родительской таблицы. Так же поддерживается опция CHECK ON COMMIT, которая
указывает, что проверка на правильность внешних ключей будет произведена не
сразу во время операции изменения информации таблицы, а только в конце
транзакции, непосредственно перед командой COMMIT. особенно эта опция полезна
при организации таблиц, хранящих графы, где внешний ключ ссылается на родителя в
той же таблице и проверку на правильность FK можно провести только после
завершения всех операцией ввода и изменения информации с этой таблицей. Поля
внешних ключей автоматически индексируются ASA и выступают как полноценные
индексы, вплоть до назначения их кластерными индексами. В ASA, как и многих
других РСУБД поддерживаются каскадные операции, позволяющие, при изменении
ключевых полей записей таблиц, автоматически изменять значения внешних ключей их
дочерних таблиц, или же, при удалении записей, автоматически удалять записи из
дочерних таблиц, сбрасывать их на NULL(если поле стоит как nullable) или же
устанавливать их значение в указанное значение по умолчанию для этих полей. В
механизме каскадных операциях ASA на самом деле присутствует несколько
тонкостей, о которых знать не повредит:
-
При указании каскадной операции для внешнего ключа
ASA создает системный триггер, в котором производиться необходимая
соответствующая операция. В Sybase Central их можно увидеть в соответствующем
разделе “System triggers”. Такие триггеры создаются как “for each row”, то
есть они вызываются для каждой изменяемой или удаляемой записи, на которую
предстоит произвести каскадную операцию. Можно было бы удивиться, почему так
сделано, ведь триггеры, вызывающиеся на каждую запись, по определению
изначально менее производительны, чем “for each statement”, то есть
вызывающиеся для обработки всего массива изменяемых записей (например в Sybase
ASE и MS SQLServer существуют именно только такие триггеры). В данном случае,
применяемый для каскадных операций в ASA, такой тип триггеров лично я обьясняю
тем, что в ASA можно указать порядок проведения каскадных операций – до или
после команд изменения данных UPDATE и DELETE, а в ASA для before триггеров
поддерживается только уровень “for each row”. Хотя я бы на самом деле просто
сделал 2 системных триггера – один как row-триггер, если требуется проводить
каскадные операции перед командой изменения данных и как statement-триггер,
если каскадные операции проводятся после операции изменения
данных.
-
Как упоминалось уже в предыдущем пункте, в ASA
можно указать порядок вызова системных триггеров. Осуществляется это
установкой опции базы данных RI_TRIGGER_TIME в значения “BEFORE” или
“TRIGGER”. Сразу сказать, что удобней и выгодней очень сложно, ASA по
умолчанию ставит уровень AFTER. Однако стоит обратить внимание, что на самом
деле в зависимости от этой опции коренным образом изменяется сама логика
изменения и удаления данных по каскадным операциям и даже действия Ваших
триггеров. Рассмотрим это на примере каскадных удалений:
BEFORE: удаляемые данные еще находятся в
самой таблице. Поэтому, если при удалении дочерних записей системным триггером
произойдет ошибка, то ничего особенного не произойдет и как такового отката
транзакции на самом деле не произойдет. Если на операции удаления записей в
триггерах дочерних таблиц прописана Ваша логика, то получается, что она так же
будет вызвана до фактического удаления записей в родительской таблице. Так как
удаляемые записи в родительской таблице еще существуют, то Вы можете к ним
обращаться и обрабатывать. Однако понять, что они подготовлены к удалению, Вы
никак не сможете.
AFTER: удаляемые данные уже попали в
лог-файл и физически стерты с таблицы. Поэтому, если при удалении дочерних
записей системным триггером произойдет ошибка, то будет произведен откат
транзакции, что довольно дорогостоящая операция. Для Ваших триггеров,
описывающих логику на удаление записей из дочерних таблиц родительских записей
в родительской таблице уже существовать не будет. С одной стороны это удобно –
если родительской записи нет, то всегда можно понять, что текущая запись
участвует в каскадном удалении, а не просто удаляется из своей таблицы. С
другой стороны, если например для проверки законности удаления дочерней записи
триггеру необходима информация ее родительской записи, то получить уже он ее
не сможет. При таких случаях я рекомендую просто не пользоваться каскадными
операциями и самостоятельно ее организовывать в триггерах before, вручную
удаляя записи таких проблематичных дочерних таблиц.
-
Ваши триггера на родительские таблицы, на которые
ссылаются дочерние таблицы с каскадными операциями, будут проводиться только
после того, как будут выполнены системные триггера, что приведет к тому, что
они не смогут увидеть дочерние записи. Например, в БД стоит опция действия
каскадных операций AFTER. Удаляется запись родительской таблицы Parent, на
которую по FK ссылается дочерней таблицы Children с выставленной опцией
необходимости каскадных удалений. Порядок действия будет
таков:
-
-
Вызывается триггер
BEFORE DELETE таблицы Parent. С него можно обращаться ко всем
записям таблиц Parent и Children.
-
Происходит физическое
удаление записи из таблицы Parent, делается соответствующая
пометка в лог-файл БД
-
Вызывается системный
триггер, ответственный за каскадное удаление, который в свою
очередь вызывает DELETE нужных записей из таблицы Children
-
Вызывается триггер
BEFORE DELETE таблицы Children. С него можно увидеть все записи
таблицы Children, однако родительской записи в таблице Parent уже
нет
-
Происходит физическое
удаление записи из таблицы Children, делается соответствующая
пометка в лог-файл БД
-
Вызывается триггер
AFTER DELETE таблицы Children. Удаляемых записей в таблицах Parent
и Children увидеть он не может
-
Производятся системные
проверки целостной ссылочности таблицы Children.
-
Вызывается триггер
AFTER DELETE таблицы Parent. Удаляемых записей в таблицах Parent и
Children увидеть он не может
-
Производятся системные проверки
целостной ссылочности таблицы
Parent. |
Я не берусь утверждать, что вышеизложенный порядок абсолютно такой, каким
я его изложил, так как в BOL по этому поводу ничего не сказано и вышеизложенный
порядок взят мной из личных наблюдений и исследований. Например под вопросом
остаются пункты 7 и 9, так как я не знаю точно, когда ASA производит проверки на
целостность таблицы. Однако проводимые как AFTER каскадные операции были бы
просто не возможны, если бы перед ними была произведена проверка и выявлено, что
происходит удаление записей, являющихся родительскими по отношению к другим
таблицам, из чего я и сделал вывод, что все проверки выполняются только под
конец всех операций и выполнения AFTER триггеров. Хотя возможен и вариант, что
ASA выполняет проверку целостности и правильности информации непосредственно
перед ее физическим изменением в базе данных, после выполнения триггеров BEFORE,
просто игнорируя проверки на целостность, для которых установлены каскадные
операции. К сожалению проверить это не предоставляется возможным, если только
это лично не прояснят сами разработчики ASA.
Индексы. Уникальные и кластерные
индексы |
Индексы в ASA могут быть обычными, уникальными и кластерными. В целях
повышения производительности их можно хранить отдельно от таблиц, в других
файлах базы данных (dbspaces). Уникальные индексы аналогичны уникальным
ограничениям, однако в отличие от них могут содержать в себе поля, способные
хранить значения NULL. Так же на таблицу разрешается сделать один кластерный
индекс, который будет определять порядок физического размещения записей. Однако
в отличие от многих других РСУБД, создание кластерного индекса не означает
немедленную перестройку записей таблицы в порядке, указанным индексом. Для
физического изменения порядка расположения записей таблицы по установленному
кластерному индексу необходимо воспользоваться командой REORGINAZE TABLE .
Кластерный индекс так же влияет на порядок добавления записей в таблицу, где ASA
пытается отсортировать добавляемые записи и записать их в страницы, содержащие
ближайшие по значениям записи, если в страницах хватает места. При записи в
подходящую страницу, содержащие в ней записи не пересортировываются и не
перестраиваются с учетом добавляемых записей, в основном преследуются цель
расположения близких по значению записей на одних страницах, чтобы было возможно
максимально быстро осуществлять выборку записей с учетом использования
кластерного индекса. Такой способ работы с кластерным индексом содержит в себе
ряд преимуществ и недостатков:
-
Высокая скорость операций вставки
записей.
-
Ручная физическая перестройка таблицы с помощью
команды REORGANIZE TABLE позволяет самому проектировщику БД решать, когда
стоит вызывать эту операцию, а когда нет.
-
ASA не может гарантировать при постоянном
добавлении записей с различными значениями полей полную кластеризованность
таблицы, что будет приводить к увеличению ее фрагментации. В данном случае
команда REORGINIZE TABLE дефрагментирует таблицу, однако это трудоемкая
операция, которая будет занимать достаточно времени при обработке таблиц с
большим количеством записей.
-
С учетом того, что кластеризованный индекс в ASA не
ставит себе целью обеспечения полноценного отсортированного хранения записей
таблиц по кластерному индексу, то никогда не стоит надеяться, что “SELECT *
FROM Table“ вернет записи, отсортировав их по кластерному индексу, в отличие
например от MSSQL, который именно так и делает.
Так же дефрагментировать таблицы, выстроив по значению кластерного ключа,
можно, воспользовавшись утилитой выгрузки базы данных или командами выгрузки и
загрузки данных с таблиц UNLOAD TABLE и LOAD TABLE.
Способ хранения индексов определяется самой ASA в зависимости от многих
условий. Это может быть обычное B-дерево, Хэш-индекс, сжатое B-дерево и т.д. Для
проверки и выявления сбоев в хранении таблиц и индексов, в ASA существуют
специальные команды и утилиты, позволяющие выполнять такие проверки в различных
режимах – от скоростной до полной проверки. В качестве расширения
функциональности использования индексов в ASA разрешено строить индексы с
использованием системных функций, например можно построить индекс по году поля
даты: Year(DateField). Так же в ASA существуют виртуальные индексы, однако они
служат для оптимизаций запросов без построения реальных индексов в базе данных и
будут мной рассмотрены в рассылках, посвященных оптимизации запросов в
ASA.
В качестве заключения главы: вся вышеизложенная информация по индексам
наглядно показывает, что во многом построение и использование индексов в ASA
отличается от принципов других РСУБД, что приводит к тому, что известные и
проверенные принципы построения индексов для оптимизации запросов, в ASA могут
не только не улучшать план выполнения запросов, но и тормозить выполнение самих
запросов.
В следующей, пятой
рассылке: |
-
Представления
-
Триггера
-
Хранимые процедуры
-
Пользовательские
функции |
Большое спасибо всем тем, кто принял участие в подготовке
рассылки: |
-
Наталья Алешина (менеджер московского представительства
Sybase)
-
Федор Корюгин (программист)
-
Алексей Орлов
(программист) |
До встречи в следующей
рассылке, с уважением, ASCRUS.
Материалы данной рассылки является собственностью ее автора. При
использовании информации из рассылки ссылка на автора
обязательна. |
|