LXF87-88:PostgreSQL
Yaleks (обсуждение | вклад) (uncomplete) |
Yaleks (обсуждение | вклад) м (→Работа с базой) |
||
(не показаны 2 промежуточные версии 1 участника) | |||
Строка 2: | Строка 2: | ||
== Работа с базой == | == Работа с базой == | ||
− | ''ЧАСТЬ 3: Вы уже неоднократно слышали, что | + | ''ЧАСТЬ 3: Вы уже неоднократно слышали, что PostgreSQL — это одна из самых мощных открытых СУБД, и сегодня '''Евгений Балдин''' расскажет вам, почему.'' |
+ | {| align="right" | ||
+ | | «Познание бесконечности требует бесконечного времени». | ||
+ | <div align="right">Девиз отдела Абсолютного Знания<br /> | ||
+ | «Понедельник начинается в субботу»</div> | ||
+ | |}<div style="clear:both;"></div> | ||
В этой статье мы предпримем попытку сделать краткий обзор | В этой статье мы предпримем попытку сделать краткий обзор | ||
− | возможностей PostgreSQL. Не надо | + | возможностей PostgreSQL. Не надо иллюзий — «объять необъятное невозможно», поэтому многое из интересного осталось |
− | + | за кадром, но все же «попытка — не пытка». | |
− | за кадром, но все же | + | |
=== Немного об основах === | === Немного об основах === | ||
− | Применительно к базам данных часто упоминается принцип ACID: | + | Применительно к базам данных часто упоминается принцип ACID: атомарность (Аtomicity), целостность (Consistency), локализация пользовательских процессов (Isolation) и устойчивость к ошибкам (Durability). |
− | + | ||
− | + | ||
Для обеспечения совместной работы множества пользователей | Для обеспечения совместной работы множества пользователей | ||
− | (concurrency) в целях следования заветам ACID, PostgreSQL | + | (concurrency) в целях следования заветам ACID, PostgreSQL использует систему управления версиями или MVCC (Multi-Version Concurrency |
− | + | ||
Control). При подсоединении пользователя MVCC «подсовывает» ему | Control). При подсоединении пользователя MVCC «подсовывает» ему | ||
− | собственную версию или мгновенный снимок (snapshot) базы | + | собственную версию или мгновенный снимок (snapshot) базы данных. В этом случае изменения, производимые пользователем, невидимы другими пользователями до тех пор, пока текущая транзакция<ref>Транзакция представляет собой последовательность операций, которая обязана либо |
− | + | ||
− | + | ||
выполниться полностью, либо отмениться совсем, как будто это единое целое. При этом, | выполниться полностью, либо отмениться совсем, как будто это единое целое. При этом, | ||
независимо от других параллельно идущих транзакций (isolation), должна сохраняться | независимо от других параллельно идущих транзакций (isolation), должна сохраняться | ||
целостность данных (consistency).</ref> | целостность данных (consistency).</ref> | ||
(transaction) не подтверждается (commit). Кроме проблем, связанных | (transaction) не подтверждается (commit). Кроме проблем, связанных | ||
− | с ACID, многоверсионность позволяет уменьшить или даже, во | + | с ACID, многоверсионность позволяет уменьшить или даже, во многих случаях, исключить необходимость блокировки данных (locks) |
− | + | ||
при чтении. | при чтении. | ||
− | Надежность<ref>Этот момент отражен в FAQ fido7.ru.os.cmp следующим образом:<br /> | + | Надежность<ref>Этот момент отражен в FAQ [news://fido7.ru.os.cmp fido7.ru.os.cmp] следующим образом:<br /> |
Q51: Народ, а вы стабильным софтом пользоваться не пробовали?<br /> | Q51: Народ, а вы стабильным софтом пользоваться не пробовали?<br /> | ||
A51: Пробовали, но мэйнфреймы с дизель-генераторами не везде есть.</ref> (reliability) сохранения данных является одним из | A51: Пробовали, но мэйнфреймы с дизель-генераторами не везде есть.</ref> (reliability) сохранения данных является одним из | ||
− | основных показателей качества СУБД. Сохранение измененных | + | основных показателей качества СУБД. Сохранение измененных данных — очень нетривиальная процедура. Дело в том, что диски очень |
− | + | «ме-е-едленные», поэтому прежде чем попасть на диск, данные проходят через промежуточные буферы (cache), начиная от системного | |
− | «ме-е-едленные», поэтому прежде чем попасть на диск, данные | + | |
− | + | ||
кэша файловой системы, заканчивая кэшем на самом диске. Никто | кэша файловой системы, заканчивая кэшем на самом диске. Никто | ||
− | не сможет гарантировать, что все в них положенное, в случае | + | не сможет гарантировать, что все в них положенное, в случае возникновения каких-либо проблем, окажется в безопасном постоянном |
− | + | хранилище. Для максимального уменьшения вероятности потери данных PostgreSQL использует журнал транзакций или Write Ahead Log | |
− | хранилище. Для максимального уменьшения вероятности потери | + | |
− | + | ||
(WAL). Прежде чем записать данные о проведенной транзакции на | (WAL). Прежде чем записать данные о проведенной транзакции на | ||
− | диск, информация об изменениях заносится в WAL. Если что-то | + | диск, информация об изменениях заносится в WAL. Если что-то случилось, то данные можно восстановить по журналу. Если данные не |
− | + | попали в журнал, то, соответственно, исчезнет вся транзакция — жалко, | |
− | попали в журнал, то, соответственно, исчезнет вся | + | |
конечно, зато целостность не нарушается. Следствием использования | конечно, зато целостность не нарушается. Следствием использования | ||
WAL является отсутствие необходимости «скидывать» данные на диск | WAL является отсутствие необходимости «скидывать» данные на диск | ||
с помощью fsync, так как достаточно убедиться, что записан WAL. Это | с помощью fsync, так как достаточно убедиться, что записан WAL. Это | ||
− | значительно увеличивает производительность в | + | значительно увеличивает производительность в многопользовательской среде с множеством мелких запросов на изменение данных, так |
− | + | ||
как записать один последовательный файл WAL гораздо проще, чем | как записать один последовательный файл WAL гораздо проще, чем | ||
изменять множество таблиц по всем диску. В качестве бонуса журнал | изменять множество таблиц по всем диску. В качестве бонуса журнал | ||
− | транзакций позволяет организовать непрерывное резервное | + | транзакций позволяет организовать непрерывное резервное копирование данных (on-line backup) — мечту администратора и возможность |
− | + | ||
«отката» базы данных на любой момент в прошлом (point-in-time | «отката» базы данных на любой момент в прошлом (point-in-time | ||
− | recovery) | + | recovery) — своеобразную машину времени. |
=== Типы данных === | === Типы данных === | ||
− | Как и положено базе данных, PostgreSQL поддерживает довольно | + | {{Врезка |
− | + | |Заголовок=Азбука SQL: В | |
− | + | |Содержание= | |
+ | Самый популярный оператор в SQL – это SELECT. | ||
+ | Получение данных практически всегда организуется с | ||
+ | его помощью. Он всего один, поэтому нет никакого | ||
+ | языка получения данных – он сам себе язык. Причем язык декларативный, потому как при использовании SELECT описываются | ||
+ | свойства искомых данных, а не информация о том, как эти данные | ||
+ | получить. | ||
+ | |||
+ | Урезанные правила для SELECT представлены ниже: | ||
+ | <source lang="sql"> | ||
+ | SELECT «список искомых данных» | ||
+ | [ FROM «список источников получения данных» ] | ||
+ | [ WHERE «условное выражение» ] | ||
+ | [ GROUP BY «выражение» [, …]] | ||
+ | [ HAVING «условное выражение» [, …] ] | ||
+ | [ ORDER BY «выражение» [, …] ] | ||
+ | [ LIMIT «число» ] | ||
+ | [ OFFSET «число» ] | ||
+ | </source> | ||
+ | Если в качестве «списка искомых данных» передать «*» (звездочку), то выводятся все поля из «списка источников получения | ||
+ | данных». Результат, выдаваемый SELECT, можно использовать как | ||
+ | источник получения данных, наравне c именами таблиц. Вложенный | ||
+ | SELECT должен заключаться в круглые скобки. С помощью WHERE | ||
+ | описываются свойства, которые хочется видеть среди полученных | ||
+ | данных. | ||
+ | |||
+ | Инструкция GROUP BY позволяет сгруппировать результаты по | ||
+ | указанному признаку. Инструкция HAVING выполняет примерно те | ||
+ | же функции, что и инструкция WHERE, но работает уже после применения GROUP BY. Поэтому в случае HAVING можно использовать | ||
+ | агрегатные функции. | ||
+ | |||
+ | Сортировка данных обеспечивается с помощью инструкции | ||
+ | ORDER BY. «Выражение» для сортировки представляет из себя | ||
+ | функцию от имен столбцов (просто имя столбца – тоже выражение) и метода сортировки. Через запятую можно указать еще одно | ||
+ | выражение, которое принимается во внимание, если предыдущее | ||
+ | выражение для сортируемых строчек выдает одинаковые значения. | ||
+ | Сортировка может производиться по возрастанию (ASC), по убыванию (DESC) и по заданному пользователем алгоритму (USING | ||
+ | «оператор сравнения»; ASC эквивалентен конструкции USING <,DESC – инструкции USING >.). | ||
+ | |||
+ | Для ограничения на число получаемых в ответ на запрос строк | ||
+ | можно использовать инструкцию LIMIT, которая гарантирует, что | ||
+ | число выведенных строк не будет превышать указанное в качестве | ||
+ | параметра число. Инструкция OFFSET указывает SELECT, сколько | ||
+ | строк из уже отобранных следует пропустить, прежде чем начать | ||
+ | вывод. | ||
+ | |Ширина=300px}} | ||
+ | Как и положено базе данных, PostgreSQL поддерживает довольно много стандартных типов данных. Более того, пользователь может определять свои собственные типы данных, если он не найдет необходимых | ||
примитивов среди стандартных. | примитивов среди стандартных. | ||
+ | |||
==== Числовые типы ==== | ==== Числовые типы ==== | ||
Обычные числовые (numeric) типы представлены целыми числами в | Обычные числовые (numeric) типы представлены целыми числами в | ||
два (smallint), четыре (integer) или восемь (bigint) байт длиной, числа | два (smallint), четыре (integer) или восемь (bigint) байт длиной, числа | ||
− | с плавающей | + | с плавающей точкой — в четыре (real) и восемь байт (double precision) |
длиной. Кроме обычных чисел, в случае real и double поддерживаются | длиной. Кроме обычных чисел, в случае real и double поддерживаются | ||
− | значения Infinity, -Infinity и | + | значения Infinity, -Infinity и NaN — бесконечность (), минус бесконечность (-) и «не число» (not-a-number), соответственно. |
− | + | ||
PostgreSQL поддерживает числа с произвольной точностью | PostgreSQL поддерживает числа с произвольной точностью | ||
− | numeric(precision,scale), где | + | numeric(precision, scale), где precision — число всех знаков в определяемой величине, а scale — число знаков в дробной части. PostgreSQL |
− | + | ||
позволяет выполнять действия без накопления ошибки с подобными | позволяет выполнять действия без накопления ошибки с подобными | ||
величинами с точностью вплоть до 1000 знаков. Этим типом данных | величинами с точностью вплоть до 1000 знаков. Этим типом данных | ||
не следует злоупотреблять, так как операции над подобными числами | не следует злоупотреблять, так как операции над подобными числами | ||
занимают очень много времени. | занимают очень много времени. | ||
− | Битовые поля представлены типами bit(size) | + | |
− | + | Битовые поля представлены типами bit(size) — битовая строка фиксированной длины size и bit varying(size) — битовая строка переменной | |
длины с ограничением по размеру size. | длины с ограничением по размеру size. | ||
+ | |||
К числовым типам PostgreSQL относятся и «псевдотипы» serial и | К числовым типам PostgreSQL относятся и «псевдотипы» serial и | ||
− | bigserial. Эти типы соответствуют типам integer и bigint, за | + | bigserial. Эти типы соответствуют типам integer и bigint, за исключением того, что при записи новых данных в таблицу с колонкой этого типа, |
− | + | значение по умолчанию в ней увеличивается на единицу — то есть это | |
− | значение по умолчанию в ней увеличивается на | + | |
автоматически создаваемая упорядоченная последовательность. | автоматически создаваемая упорядоченная последовательность. | ||
==== Символьные типы ==== | ==== Символьные типы ==== | ||
− | В стандарте SQL символьный тип определяется как строка | + | В стандарте SQL символьный тип определяется как строка определенной длины character(size), где size — длина строки. В дополнение к |
− | + | стандарту, PostgreSQL поддерживает строки переменной длины с ограничением varchar(size) и без ограничения — text. | |
− | стандарту, PostgreSQL поддерживает строки переменной длины с | + | |
− | + | ||
==== Бинарные типы ==== | ==== Бинарные типы ==== | ||
− | Бинарную строку можно сохранить, используя тип bytea. SQL | + | Бинарную строку можно сохранить, используя тип bytea. SQL предполагает, что вся информация передается как текст, поэтому при передаче данных следует экранировать некоторые из символов. |
− | + | ||
− | + | ||
В PostgreSQL есть специальный тип данных Large Objects. По сути | В PostgreSQL есть специальный тип данных Large Objects. По сути | ||
дела, это просто способ сохранять любые файлы размером вплоть до | дела, это просто способ сохранять любые файлы размером вплоть до | ||
2 Гб прямо в базе данных. Операции с подобными объектами выходит | 2 Гб прямо в базе данных. Операции с подобными объектами выходит | ||
− | за рамки SQL. Для доступа к Large Objects есть специальный | + | за рамки SQL. Для доступа к Large Objects есть специальный программный интерфейс, смоделированный по образу и подобию обычного |
− | + | ||
чтения/записи файла. | чтения/записи файла. | ||
==== Типы даты/времени ==== | ==== Типы даты/времени ==== | ||
Временем в PostgreSQL заведует тип timestamp или timestamp with time | Временем в PostgreSQL заведует тип timestamp или timestamp with time | ||
− | + | zone — он может хранить дату и время, начиная с 4713 г. до н. э. вплоть | |
− | до | + | до 5874897 г., с точностью в одну микросекунду (μс), занимая восемь |
− | байт. Второй упомянутый тип включает часовой пояс и позволяет | + | байт. Второй упомянутый тип включает часовой пояс и позволяет автоматически учитывать переход на летнее/зимнее время. С таким диапазоном и точностью проблема типа широко разрекламированной Y2K |
− | + | ||
− | + | ||
случится не скоро. | случится не скоро. | ||
+ | |||
Разница между двумя датами представлена типом interval длиной в | Разница между двумя датами представлена типом interval длиной в | ||
− | двенадцать байт, что позволяет хранить информацию о событиях, | + | двенадцать байт, что позволяет хранить информацию о событиях, связанных даже с рождением и смертью Вселенной. |
− | + | ||
− | Также есть отдельный тип для календарного времени (date) и | + | Также есть отдельный тип для календарного времени (date) и просто для времени (time или time with timezone). |
− | + | ||
− | PostgreSQL поддерживает множество способов ввода даты и | + | PostgreSQL поддерживает множество способов ввода даты и времени. С моей точки зрения, в некоторых случаях СУБД проявляет |
− | + | ||
излишний интеллект, поэтому рекомендую выбрать стандартный ISO, | излишний интеллект, поэтому рекомендую выбрать стандартный ISO, | ||
который выглядит примерно так: | который выглядит примерно так: | ||
Строка 126: | Строка 156: | ||
2006-08-26 21:08:14+07 | 2006-08-26 21:08:14+07 | ||
</source> | </source> | ||
− | В таком случае ошибиться в порядке месяца и дня становится | + | В таком случае ошибиться в порядке месяца и дня становится весьма затруднительно, независимо от того, какая локаль используется |
− | + | ||
системой. | системой. | ||
+ | |||
Для типа timestamp определены дополнительные константы: | Для типа timestamp определены дополнительные константы: | ||
− | * | + | * epoch — начало эпохи с точки зрения времени Unix (четырехбайтовый time_t): 1970-01-01 00:00:00+00; |
− | * | + | * infinity — позже, чем любое возможное из времен; |
− | * - | + | * -infinity — раньше, чем любое возможное из времен; |
− | * | + | * now — здесь и сейчас; |
− | * | + | * today — сегодняшняя полночь; аналогично, yesterday — вчерашняя полночь и, tomorrow — завтрашняя полночь. |
==== Логические типы ==== | ==== Логические типы ==== | ||
− | Логические типы представлены типом boolean. Логично, что он | + | Логические типы представлены типом boolean. Логично, что он принимает значения либо TRUE (‘t’, ‘true’, ‘y’,’yes’, ‘1’) — «истина», либо FALSE |
− | + | (‘f’, ‘false’, ‘n’, ‘no’, ‘0’) — «ложь». Все просто, за исключением одного | |
− | (‘f’, ‘false’, ‘n’, ‘no’, ‘0’) | + | «но» — есть еще одна возможность: «значение не определено» (NULL). |
− | + | Собственно говоря, это не особенность типа boolean. При использовании SQL, с тем, что значение может быть не определено, необходимо | |
− | Собственно говоря, это не особенность типа boolean. При | + | считаться всегда и везде. Вот такая вот логика — вовсе не двоичная. |
− | + | ||
− | считаться всегда и везде. Вот такая вот | + | |
==== Остальные стандартные типы ==== | ==== Остальные стандартные типы ==== | ||
− | К оставшимся стандартным типа относятся различные | + | К оставшимся стандартным типа относятся различные геометрические типы данных: точка (point), линия (line), отрезок (lseg), прямоугольник (box), путь (path), замкнутый путь (polygon) и окружность |
− | + | (circle). Для системных администраторов будут интересны стандартные типы сетевых IPv4 и IPv6-адресов (cidr или inet) и тип МАС-адреса (macaddr). | |
− | + | ||
− | (circle). Для системных администраторов будут интересны | + | Более сложные типы реализуются как дополнения. Яркими примерами служат поддержка географических объектов GIS (http://postgis.refractions.net/) и иерархический тип данных ltree (contrib/ltree). |
− | + | ||
− | + | ||
− | Более сложные типы реализуются как дополнения. Яркими | + | |
− | + | ||
− | refractions.net/) и иерархический тип данных ltree (contrib/ltree). | + | |
==== Определение пользовательских типов ==== | ==== Определение пользовательских типов ==== | ||
− | Прежде всего следует упомянуть, что PostgreSQL поддерживает | + | Прежде всего следует упомянуть, что PostgreSQL поддерживает массивы. Можно создать массив определенного размера или безразмерный, |
− | + | на основе любого стандартного типа или типа, определенного пользователем. Поддерживаются многомерные массивы и операции над ними, | |
− | на основе любого стандартного типа или типа, определенного | + | |
− | + | ||
например, «срезы». | например, «срезы». | ||
<source lang="sql"> | <source lang="sql"> | ||
Строка 186: | Строка 207: | ||
test=> CREATE TYPE complex AS (Re real,Im real); | test=> CREATE TYPE complex AS (Re real,Im real); | ||
</source> | </source> | ||
− | В отличие от стандартных встроенных типов, использование | + | В отличие от стандартных встроенных типов, использование композитного типа пока имеет некоторые ограничения. Например, из них |
− | + | ||
нельзя создавать массивы. | нельзя создавать массивы. | ||
Строка 197: | Строка 217: | ||
=== Функции === | === Функции === | ||
Все стандартные типы имеют свои функции: ведь если есть тип, то | Все стандартные типы имеют свои функции: ведь если есть тип, то | ||
− | с ним нужно работать. Стандартные функций | + | с ним нужно работать. Стандартные функций многочисленны<ref>Их больше 1500. Полный список можно вывести, набрав в psql команду \df.</ref> и разнообразны. Одних операторов поиска с использованием регулярных |
− | + | выражений — целых три штуки: собственное расширение PostgreSQL | |
− | + | ||
(LIKE и ILIKE), оператор, соответствующий стандарту SQL (SIMILAR TO) | (LIKE и ILIKE), оператор, соответствующий стандарту SQL (SIMILAR TO) | ||
и POSIX-совместимый оператор (~ и ~*). Все, что только можно было | и POSIX-совместимый оператор (~ и ~*). Все, что только можно было | ||
− | быстро придумать, уже реализовано. А более сложные случаи, | + | быстро придумать, уже реализовано. А более сложные случаи, например, модуль для полнотекстового поиска tsearch2 (contrib/tsearch2) |
− | + | находятся в процессе совершенствования. Изобрести что-то, выходящее за рамки стандарта тяжело, но если это случится, вы всегда можете создать свою собственную функцию. При желании, ссылаясь на уже | |
− | находятся в процессе совершенствования. Изобрести что-то, | + | |
− | + | ||
− | + | ||
имеющуюся функцию, с помощью команды CREATE OPERATOR можно | имеющуюся функцию, с помощью команды CREATE OPERATOR можно | ||
определить оператор для своих типов данных. | определить оператор для своих типов данных. | ||
Строка 213: | Строка 229: | ||
Для создания новых функций используется оператор CREATE FUNCTION, | Для создания новых функций используется оператор CREATE FUNCTION, | ||
что вполне предсказуемо. Создаваемые таким образом функции | что вполне предсказуемо. Создаваемые таким образом функции | ||
− | исполняются и хранятся на сервере, отсюда и | + | исполняются и хранятся на сервере, отсюда и название — «хранимые |
процедуры»: | процедуры»: | ||
<source lang="sql"> | <source lang="sql"> | ||
Строка 233: | Строка 249: | ||
(записей: 3) | (записей: 3) | ||
</source> | </source> | ||
− | PostgreSQL поддерживает перегрузку функций: объектно- | + | PostgreSQL поддерживает перегрузку функций: объектно-ориентированность имеет свои плюсы. Кроме SQL, для создания новых |
− | + | ||
функций можно использовать процедурные языки программирования. | функций можно использовать процедурные языки программирования. | ||
− | Для начала работы с процедурным языком его необходимо | + | Для начала работы с процедурным языком его необходимо инициализировать. По умолчанию, интерфейсы к языкам, отличным от SQL и C, |
− | + | недоступны по соображениям безопасности. Для инициализации языка используется команда createlang. Запустить ее может только администратор базы данных — тот, кто имеет право создавать базы: | |
− | недоступны по соображениям безопасности. Для инициализации | + | |
− | + | ||
− | + | ||
<source lang="sql"> | <source lang="sql"> | ||
# Инициализируем язык PL/pgSQL для базы данных test | # Инициализируем язык PL/pgSQL для базы данных test | ||
Строка 247: | Строка 259: | ||
> createlang plperl test | > createlang plperl test | ||
</source> | </source> | ||
− | Теперь можно создавать функции с использованием всех | + | Теперь можно создавать функции с использованием всех прелестей процедурного программирования, вместе с циклами, каковые по |
− | + | понятным причинам отсутствуют в SQL. Ниже продублирована простейшая функция, которая была описана выше, но теперь уже на PL/pgSQL и на PL/Perl: | |
− | понятным причинам отсутствуют в SQL. Ниже продублирована | + | |
− | + | ||
− | pgSQL и на PL/Perl: | + | |
<source lang="sql"> | <source lang="sql"> | ||
test=> -- Создаем новую функцию с использование PL/pgSQL | test=> -- Создаем новую функцию с использование PL/pgSQL | ||
Строка 272: | Строка 281: | ||
</source> | </source> | ||
В стандартной документации подробно описаны идущие вместе с | В стандартной документации подробно описаны идущие вместе с | ||
− | дистрибутивом языки: PL/pgSQL, PL/Tcl, PL/Perl, PL/Python и, | + | дистрибутивом языки: PL/pgSQL, PL/Tcl, PL/Perl, PL/Python и, естественно, C/C++ с SQL. Кроме перечисленных здесь, есть поддержка |
− | + | ||
* plPHP http://plphp.commandprompt.com/, | * plPHP http://plphp.commandprompt.com/, | ||
* PL/java http://gborg.PostgreSQL.org/project/pljava/projdisplay.php, | * PL/java http://gborg.PostgreSQL.org/project/pljava/projdisplay.php, | ||
Строка 279: | Строка 287: | ||
* PL/Ruby http://raa.ruby-lang.org/project/pl-ruby, | * PL/Ruby http://raa.ruby-lang.org/project/pl-ruby, | ||
* PL/sh http://plsh.projects.PostgreSQL.org/. | * PL/sh http://plsh.projects.PostgreSQL.org/. | ||
+ | |||
Также есть возможность подключения вашего любимого языка. | Также есть возможность подключения вашего любимого языка. | ||
==== Триггеры ==== | ==== Триггеры ==== | ||
− | Обычно для решения несложных задач можно удовлетвориться | + | Обычно для решения несложных задач можно удовлетвориться сценарием: «что сказано — то и сделано», но в более сложных случаях от |
− | + | ||
СУБД хотелось бы получать более сложные реакции в ответ на внешнее | СУБД хотелось бы получать более сложные реакции в ответ на внешнее | ||
«раздражение». Для управления реакцией СУБД на изменение данных | «раздражение». Для управления реакцией СУБД на изменение данных | ||
Строка 296: | Строка 304: | ||
</source> | </source> | ||
Реакция на «событие», которое может быть вставкой (INSERT), | Реакция на «событие», которое может быть вставкой (INSERT), | ||
− | изменением (UPDATE), или удалением (DELETE) может | + | изменением (UPDATE), или удалением (DELETE) может производится, по выбору, до (BEFORE) или после (AFTER) изменения данных. |
− | + | ||
Выполнение процедуры может производиться для каждой записи | Выполнение процедуры может производиться для каждой записи | ||
(ROW) или для каждого запроса (STATEMENT). Для показательного | (ROW) или для каждого запроса (STATEMENT). Для показательного | ||
Строка 335: | Строка 342: | ||
==== Rules ==== | ==== Rules ==== | ||
− | Кроме триггеров, PostgreSQL обладает еще одним способом | + | Кроме триггеров, PostgreSQL обладает еще одним способом управления реакции СУБД на запросы — это rules, или «правила». Для создания |
− | + | «правил» используется команда CREATE RULE. Основное отличие «правила» от триггера в том, что триггер — это реакция системы на изменение данных, а «правило» позволяет изменять сам запрос, в том числе | |
− | «правил» используется команда CREATE RULE. Основное отличие | + | и запрос на получение данных (SELECT). В частности, одно из довольно удобных расширений PostgreSQL — представление или виртуальная |
− | + | ||
− | + | ||
− | и запрос на получение данных (SELECT). В частности, одно из | + | |
− | + | ||
таблица (view), реализовано с помощью «правил». | таблица (view), реализовано с помощью «правил». | ||
=== Индексы === | === Индексы === | ||
Традиционно, для ускорения поиска информацию индексируют. Если | Традиционно, для ускорения поиска информацию индексируют. Если | ||
− | данных немного, то можно прожить и так. Серьезные же задачи | + | данных немного, то можно прожить и так. Серьезные же задачи требуют серьезных объемов, поэтому без индексов не обойтись. |
− | + | ||
− | Создание | + | Создание индексов — это ответственность создателя БД. Создание |
индекса, как можно догадаться, производится с помощью команды | индекса, как можно догадаться, производится с помощью команды | ||
<source lang="sql"> | <source lang="sql"> | ||
Строка 357: | Строка 360: | ||
[ WHERE «условие» ] | [ WHERE «условие» ] | ||
</source> | </source> | ||
− | Индекс может быть уникальным (UNIQUE). В этом случае при | + | Индекс может быть уникальным (UNIQUE). В этом случае при создании индекса и при добавлении данных накладывается дополнительное |
− | + | ||
требование на уникальность параметра, по которому создается индекс. | требование на уникальность параметра, по которому создается индекс. | ||
+ | |||
При создании индекса можно выбрать алгоритм индексации. По | При создании индекса можно выбрать алгоритм индексации. По | ||
умолчанию используется B-tree, но доступны также Hash, R-tree или | умолчанию используется B-tree, но доступны также Hash, R-tree или | ||
GiST. Алгоритм GiST (http://www.sai.msu.su/~megera/postgres/gist/) был | GiST. Алгоритм GiST (http://www.sai.msu.su/~megera/postgres/gist/) был | ||
− | создан Олегом Бартуновым на пару с Федором Сигаевым. GiST | + | создан Олегом Бартуновым на пару с Федором Сигаевым. GiST является не просто еще одним алгоритмом — это целый конструктор, позволяющим создавать индексы для принципиально новых типов данных. |
− | + | ||
− | + | ||
В PostgreSQL 8.2 будут добавлены еще два метода: bitmap и GIN. Если | В PostgreSQL 8.2 будут добавлены еще два метода: bitmap и GIN. Если | ||
− | судить по алгоритмам создания индексов, то | + | судить по алгоритмам создания индексов, то PostgreSQL — это одна из |
самых продвинутых СУБД. | самых продвинутых СУБД. | ||
− | Индекс можно создавать по какому-то из | + | |
− | простой метод. При указании нескольких колонок создаются | + | Индекс можно создавать по какому-то из столбцов — это самый |
− | + | простой метод. При указании нескольких колонок создаются многоколоночные индексы. Особо следует отметить возможность создания | |
− | функциональных | + | функциональных индексов — в качестве индекса указывается функция |
− | от данных таблицы. С помощью функциональных индексов можно | + | от данных таблицы. С помощью функциональных индексов можно реализовать еще один алгоритм индексации: Reverse index (обращает поле |
− | + | переменной — первый символ считается последним). | |
− | + | ||
Условие (WHERE), накладываемое при создании индекса, позволяет | Условие (WHERE), накладываемое при создании индекса, позволяет | ||
создавать частичные индексы (partial indices). Это полезно в тех случаях, | создавать частичные индексы (partial indices). Это полезно в тех случаях, | ||
− | когда индексируемый столбец содержит большое число одинаковых | + | когда индексируемый столбец содержит большое число одинаковых значений, а поиск надо производить по редким «чужеродным» вкраплениям. |
− | + | ||
Для того, чтобы индекс работал, как надо, необходимо следить, | Для того, чтобы индекс работал, как надо, необходимо следить, | ||
чтобы в базе данных регулярно запускалась процедура ANALYZE, | чтобы в базе данных регулярно запускалась процедура ANALYZE, | ||
Строка 386: | Строка 387: | ||
принимать решение о порядке выполнения запроса. Для оптимизации | принимать решение о порядке выполнения запроса. Для оптимизации | ||
поиска информации временами может оказаться полезна собственная | поиска информации временами может оказаться полезна собственная | ||
− | команда PostgreSQL CLUSTER. С ее помощью можно упорядочить | + | команда PostgreSQL CLUSTER. С ее помощью можно упорядочить записи в таблице согласно указанному индексу. |
− | + | ||
=== Целостность данных === | === Целостность данных === | ||
− | Сохранить, записать, а затем быстро достать | + | Сохранить, записать, а затем быстро достать данные — вещь полезная, |
− | но как отследить, что они записаны правильно и без ошибок? Для | + | но как отследить, что они записаны правильно и без ошибок? Для этого необходимо постоянно следить за целостностью данных в условиях |
− | + | ||
многопользовательской системы. | многопользовательской системы. | ||
==== Транзакции ==== | ==== Транзакции ==== | ||
− | + | Транзакция — это единый блок операций, который нельзя разорвать. | |
Блок либо выполняется целиком, либо все отменяется. В условиях | Блок либо выполняется целиком, либо все отменяется. В условиях | ||
параллельного доступа, PostgreSQL распространяет информацию об | параллельного доступа, PostgreSQL распространяет информацию об | ||
операциях только по завершению транзакции. Транзакция начинается | операциях только по завершению транзакции. Транзакция начинается | ||
− | с оператора BEGIN и заканчивается оператором COMMIT ( | + | с оператора BEGIN и заканчивается оператором COMMIT (подтверждение транзакции) или ROLLBACK (отмена транзакции). Возможен режим, |
− | + | ||
когда каждый запрос сам себе является транзакцией: например, такой | когда каждый запрос сам себе является транзакцией: например, такой | ||
режим по умолчанию используется в pSQL. Для отмены этого режима | режим по умолчанию используется в pSQL. Для отмены этого режима | ||
− | достаточно набрать BEGIN. Неудобством при использовании | + | достаточно набрать BEGIN. Неудобством при использовании транзакций является то, что в случае ошибки какого-то из запросов приходится отменять всю транзакцию. Для устранения этого недостатка в |
− | + | ||
− | + | ||
PostgreSQL 8.x были добавлены точки сохранения (savepoints). | PostgreSQL 8.x были добавлены точки сохранения (savepoints). | ||
<source lang="sql"> | <source lang="sql"> | ||
Строка 427: | Строка 423: | ||
Целостность данных обеспечивает не только многоверсионностью | Целостность данных обеспечивает не только многоверсионностью | ||
(MVCC) PostgreSQL, но и «архитектором» таблиц базы данных. При | (MVCC) PostgreSQL, но и «архитектором» таблиц базы данных. При | ||
− | создании таблицы (CREATE TABLE) или позже можно добавить | + | создании таблицы (CREATE TABLE) или позже можно добавить ограничение (CONSTRAINT) на диапазон записываемых в таблицу данных. |
− | + | ||
Ограничением могут быть как простые арифметические условные | Ограничением могут быть как простые арифметические условные | ||
выражения, требования уникальности (UNIQUE или PRIMARY KEY), так | выражения, требования уникальности (UNIQUE или PRIMARY KEY), так | ||
и более сложные ограничения в виде внешних ключей (FOREIGN KEY). | и более сложные ограничения в виде внешних ключей (FOREIGN KEY). | ||
+ | |||
Если какой-то столбец A является внешним ключом (FOREIGN KEY) | Если какой-то столбец A является внешним ключом (FOREIGN KEY) | ||
по отношению к столбцу B (REFERENCES), то это означает, что только | по отношению к столбцу B (REFERENCES), то это означает, что только | ||
− | данные, представленные в столбце B, могут появиться в качестве | + | данные, представленные в столбце B, могут появиться в качестве значений столбца A. В случае внешних ключей PostgreSQL осуществляет автоматический контроль ссылочной целостности<ref>Ссылочная целостность — гарантированное отсутствие внешних ключей, ссылающихся на несуществующие записи в этой или других таблицах.</ref>. Это довольно |
− | + | ||
− | + | ||
интересный механизм, который, в частности, позволяет моделировать | интересный механизм, который, в частности, позволяет моделировать | ||
иерархические структуры. | иерархические структуры. | ||
Строка 443: | Строка 437: | ||
Поскольку в условиях параллельного доступа к базе данных каждый | Поскольку в условиях параллельного доступа к базе данных каждый | ||
пользователь работает со своим мгновенным снимком (следствие | пользователь работает со своим мгновенным снимком (следствие | ||
− | MVCC), а не с самой БД, то в принципе можно придумать ситуацию, | + | MVCC), а не с самой БД, то в принципе можно придумать ситуацию, когда полученные данные «устаревают», так как они были изменены другим |
− | + | пользователем. Если это обстоятельство важно, то PostgreSQL предоставляет полный ассортимент блокировок. С помощью команды LOCK | |
− | пользователем. Если это обстоятельство важно, то PostgreSQL | + | можно заблокировать таблицу, а инструкция SELECT FOR UPDATE позволяет заблокировать отдельные записи. Следует учитывать, что использование блокировок увеличивает шанс взаимной блокировки (deadlock). |
− | + | ||
− | можно заблокировать таблицу, а инструкция SELECT FOR UPDATE | + | |
− | + | ||
− | + | ||
PostgreSQL умеет определять взаимные блокировки и разрешать их | PostgreSQL умеет определять взаимные блокировки и разрешать их | ||
путем прекращения одной из транзакций, но на это уходит время. | путем прекращения одной из транзакций, но на это уходит время. | ||
Строка 455: | Строка 445: | ||
=== Послесловие === | === Послесловие === | ||
Хотелось бы еще раз сказать, что «нельзя объять необъятное». | Хотелось бы еще раз сказать, что «нельзя объять необъятное». | ||
− | Единственная проблема состоит в том, что конкретно это | + | Единственная проблема состоит в том, что конкретно это рассматриваемое нами «необъятное» уже «объято», поэтому за всеми подробностями следует обратиться к стандартной документации, а в качестве |
− | + | ||
− | + | ||
бонуса рекомендую хорошую обзорную статью от Олега Бартунова: | бонуса рекомендую хорошую обзорную статью от Олега Бартунова: | ||
«Что такое PostgreSQL?»:http://www.sai.msu.su/~Emegera/postgres/talks/what_is_PostgreSQL.html. | «Что такое PostgreSQL?»:http://www.sai.msu.su/~Emegera/postgres/talks/what_is_PostgreSQL.html. | ||
+ | |||
+ | {{Врезка|center| | ||
+ | |Заголовок=PostgreSQL в лицах: Алексей Борзов | ||
+ | |Содержание= | ||
+ | Визитка LXF: | ||
+ | Окончил ВМиК МГУ в | ||
+ | 2000 году, с тех пор | ||
+ | занимается web-программированием. | ||
+ | Место работы: | ||
+ | «свободный художник». | ||
+ | Домашняя страничка | ||
+ | отсутствует – по всей | ||
+ | видимости это уже | ||
+ | давно пройденный | ||
+ | этап. | ||
+ | |||
+ | ;Евгений М. Балдин (ЕМБ): Как вы начали использовать PostgreSQL? | ||
+ | ;Алексей В. Борзов (АВБ): С PostgreSQL я работаю с 2000 года. Тогда меня взяли в Издательский дом «РДВ Медиа» переделывать «слепленный на коленке» сайт газеты «Работа для вас» (ныне http://rabota.ru/). Новый сайт с самого начала разрабатывался на связке PHP+PostgreSQL. Надо признать, PostgreSQL не был моим выбором – мне его порекомендовали. | ||
+ | ;ЕМБ: На сайте PostgreSQL написано, что вы «wrote the majority of the main website’s framework». Что сподвигло на такой подвиг? | ||
+ | ;АВБ: Причина того, что я «впрягся», банальна – на старую версию сайта PostgreSQL нельзя было смотреть без слез, и тенденции к улучшению ситуации не наблюдалось. | ||
+ | |||
+ | На момент «прикладывания рук» к сайту PostgreSQL у меня был уже опыт разработки Open Source. Я поддерживаю/пишу несколько пакетов в репозитории PEAR (http://pear.php.net/user/avb), посему для меня вполне естественно было предложить свои услуги. | ||
+ | ;ЕМБ: Насколько это было сложно? Довольны ли результатом? | ||
+ | ;АВБ: С технической точки зрения, в написании сайта для PostgreSQL была только одна трудность: сайт должен поддерживать возможность быть разнесенным по зеркалам, а требовать от владельцев зеркал, чтобы они поднимали у себя PostgreSQL и реплицировали данные с центрального сервера, практически нереально. Поэтому сайт писался сразу так, чтобы все динамические действия выполнялись на центральном сервере, а зеркала получали только статический HTML. А так – сайт далеко не самый сложный из тех, которые мне приходилось делать. | ||
+ | |||
+ | С организационной же точки зрения, группа поддержки web-сайтов PostgreSQL отличается немалым разгильдяйством. Информацию о том, что и как надо сделать, приходилось | ||
+ | «выбивать». | ||
+ | |||
+ | В целом, получилось неплохо. Нашлись профессиональные дизайнеры, и ключевая в истории проекта PostgreSQL версия 8.0 анонсировалась уже на респектабельно выглядящем сайте, а не на убогой домашней страничке. | ||
+ | ;ЕМБ: Вы активно используете в своей работе связку PHP+PostgreSQL. На сколько это связка естественна? Что мешает PostgreSQL потеснить M (MySQL) из LAMP<ref>Один из вариантов расшифровки LAMP=Linux+Apache+MySQL+PHP.</ref>? | ||
+ | ;АВБ: Язык PHP позволяет работать с огромным количеством различных СУБД, причем, как правило, используя их «родные» интерфейсы. Поэтому связка PHP+PostgreSQL вполне естественна, так же как и связка PHP+Oracle и т.д. Тот факт, что PHP упоминается обычно в виде PHP+MySQL или в аббревиатуре LAMP – исключительно результат маркетинга. На тему помех «вытеснению буквы M» у меня есть пара очевидных соображений: | ||
+ | * Версия PostgreSQL для Windows вышла не так давно, а большая часть разработчиков все же сидят под Windows. Я понимаю, не очень хорошая фраза для журнала Linux Format, но… | ||
+ | * Опять же, большая часть разработчиков имеет очень плохую подготовку, поэтому легко «ведется» на рассказы о том, что одна СУБД может всегда работать в 10 раз быстрее другой, что транзакции и внешние ключи придумали трусы и т.д., и т.п. К тому же, для этих товарищей выучить даже что-то одно – практически непосильный труд, поэтому речь об изучении другой технологии уже просто не идет. | ||
+ | |Ширина=}} | ||
---- | ---- | ||
<references /> | <references /> |
Текущая версия на 16:34, 29 июня 2008
|
|
|
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Содержание |
[править] Работа с базой
ЧАСТЬ 3: Вы уже неоднократно слышали, что PostgreSQL — это одна из самых мощных открытых СУБД, и сегодня Евгений Балдин расскажет вам, почему.
«Познание бесконечности требует бесконечного времени».
Девиз отдела Абсолютного Знания
«Понедельник начинается в субботу» |
В этой статье мы предпримем попытку сделать краткий обзор возможностей PostgreSQL. Не надо иллюзий — «объять необъятное невозможно», поэтому многое из интересного осталось за кадром, но все же «попытка — не пытка».
[править] Немного об основах
Применительно к базам данных часто упоминается принцип ACID: атомарность (Аtomicity), целостность (Consistency), локализация пользовательских процессов (Isolation) и устойчивость к ошибкам (Durability).
Для обеспечения совместной работы множества пользователей (concurrency) в целях следования заветам ACID, PostgreSQL использует систему управления версиями или MVCC (Multi-Version Concurrency Control). При подсоединении пользователя MVCC «подсовывает» ему собственную версию или мгновенный снимок (snapshot) базы данных. В этом случае изменения, производимые пользователем, невидимы другими пользователями до тех пор, пока текущая транзакция[1] (transaction) не подтверждается (commit). Кроме проблем, связанных с ACID, многоверсионность позволяет уменьшить или даже, во многих случаях, исключить необходимость блокировки данных (locks) при чтении. Надежность[2] (reliability) сохранения данных является одним из основных показателей качества СУБД. Сохранение измененных данных — очень нетривиальная процедура. Дело в том, что диски очень «ме-е-едленные», поэтому прежде чем попасть на диск, данные проходят через промежуточные буферы (cache), начиная от системного кэша файловой системы, заканчивая кэшем на самом диске. Никто не сможет гарантировать, что все в них положенное, в случае возникновения каких-либо проблем, окажется в безопасном постоянном хранилище. Для максимального уменьшения вероятности потери данных PostgreSQL использует журнал транзакций или Write Ahead Log (WAL). Прежде чем записать данные о проведенной транзакции на диск, информация об изменениях заносится в WAL. Если что-то случилось, то данные можно восстановить по журналу. Если данные не попали в журнал, то, соответственно, исчезнет вся транзакция — жалко, конечно, зато целостность не нарушается. Следствием использования WAL является отсутствие необходимости «скидывать» данные на диск с помощью fsync, так как достаточно убедиться, что записан WAL. Это значительно увеличивает производительность в многопользовательской среде с множеством мелких запросов на изменение данных, так как записать один последовательный файл WAL гораздо проще, чем изменять множество таблиц по всем диску. В качестве бонуса журнал транзакций позволяет организовать непрерывное резервное копирование данных (on-line backup) — мечту администратора и возможность «отката» базы данных на любой момент в прошлом (point-in-time recovery) — своеобразную машину времени.
[править] Типы данных
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
Как и положено базе данных, PostgreSQL поддерживает довольно много стандартных типов данных. Более того, пользователь может определять свои собственные типы данных, если он не найдет необходимых примитивов среди стандартных.
[править] Числовые типы
Обычные числовые (numeric) типы представлены целыми числами в два (smallint), четыре (integer) или восемь (bigint) байт длиной, числа с плавающей точкой — в четыре (real) и восемь байт (double precision) длиной. Кроме обычных чисел, в случае real и double поддерживаются значения Infinity, -Infinity и NaN — бесконечность (), минус бесконечность (-) и «не число» (not-a-number), соответственно.
PostgreSQL поддерживает числа с произвольной точностью numeric(precision, scale), где precision — число всех знаков в определяемой величине, а scale — число знаков в дробной части. PostgreSQL позволяет выполнять действия без накопления ошибки с подобными величинами с точностью вплоть до 1000 знаков. Этим типом данных не следует злоупотреблять, так как операции над подобными числами занимают очень много времени.
Битовые поля представлены типами bit(size) — битовая строка фиксированной длины size и bit varying(size) — битовая строка переменной длины с ограничением по размеру size.
К числовым типам PostgreSQL относятся и «псевдотипы» serial и bigserial. Эти типы соответствуют типам integer и bigint, за исключением того, что при записи новых данных в таблицу с колонкой этого типа, значение по умолчанию в ней увеличивается на единицу — то есть это автоматически создаваемая упорядоченная последовательность.
[править] Символьные типы
В стандарте SQL символьный тип определяется как строка определенной длины character(size), где size — длина строки. В дополнение к стандарту, PostgreSQL поддерживает строки переменной длины с ограничением varchar(size) и без ограничения — text.
[править] Бинарные типы
Бинарную строку можно сохранить, используя тип bytea. SQL предполагает, что вся информация передается как текст, поэтому при передаче данных следует экранировать некоторые из символов.
В PostgreSQL есть специальный тип данных Large Objects. По сути дела, это просто способ сохранять любые файлы размером вплоть до 2 Гб прямо в базе данных. Операции с подобными объектами выходит за рамки SQL. Для доступа к Large Objects есть специальный программный интерфейс, смоделированный по образу и подобию обычного чтения/записи файла.
[править] Типы даты/времени
Временем в PostgreSQL заведует тип timestamp или timestamp with time zone — он может хранить дату и время, начиная с 4713 г. до н. э. вплоть до 5874897 г., с точностью в одну микросекунду (μс), занимая восемь байт. Второй упомянутый тип включает часовой пояс и позволяет автоматически учитывать переход на летнее/зимнее время. С таким диапазоном и точностью проблема типа широко разрекламированной Y2K случится не скоро.
Разница между двумя датами представлена типом interval длиной в двенадцать байт, что позволяет хранить информацию о событиях, связанных даже с рождением и смертью Вселенной.
Также есть отдельный тип для календарного времени (date) и просто для времени (time или time with timezone).
PostgreSQL поддерживает множество способов ввода даты и времени. С моей точки зрения, в некоторых случаях СУБД проявляет излишний интеллект, поэтому рекомендую выбрать стандартный ISO, который выглядит примерно так:
test=> -- узнаем текущее время с точностью до секунды test=> SELECT date_trunc(‘seconds’,timestamp WITH time zone ‘now’); date_trunc ------------------------ 2006-08-26 21:08:14+07
В таком случае ошибиться в порядке месяца и дня становится весьма затруднительно, независимо от того, какая локаль используется системой.
Для типа timestamp определены дополнительные константы:
- epoch — начало эпохи с точки зрения времени Unix (четырехбайтовый time_t): 1970-01-01 00:00:00+00;
- infinity — позже, чем любое возможное из времен;
- -infinity — раньше, чем любое возможное из времен;
- now — здесь и сейчас;
- today — сегодняшняя полночь; аналогично, yesterday — вчерашняя полночь и, tomorrow — завтрашняя полночь.
[править] Логические типы
Логические типы представлены типом boolean. Логично, что он принимает значения либо TRUE (‘t’, ‘true’, ‘y’,’yes’, ‘1’) — «истина», либо FALSE (‘f’, ‘false’, ‘n’, ‘no’, ‘0’) — «ложь». Все просто, за исключением одного «но» — есть еще одна возможность: «значение не определено» (NULL). Собственно говоря, это не особенность типа boolean. При использовании SQL, с тем, что значение может быть не определено, необходимо считаться всегда и везде. Вот такая вот логика — вовсе не двоичная.
[править] Остальные стандартные типы
К оставшимся стандартным типа относятся различные геометрические типы данных: точка (point), линия (line), отрезок (lseg), прямоугольник (box), путь (path), замкнутый путь (polygon) и окружность (circle). Для системных администраторов будут интересны стандартные типы сетевых IPv4 и IPv6-адресов (cidr или inet) и тип МАС-адреса (macaddr).
Более сложные типы реализуются как дополнения. Яркими примерами служат поддержка географических объектов GIS (http://postgis.refractions.net/) и иерархический тип данных ltree (contrib/ltree).
[править] Определение пользовательских типов
Прежде всего следует упомянуть, что PostgreSQL поддерживает массивы. Можно создать массив определенного размера или безразмерный, на основе любого стандартного типа или типа, определенного пользователем. Поддерживаются многомерные массивы и операции над ними, например, «срезы».
test=> --- создаем массив для игры в «крестики-нолики» test=> CREATE TABLE tictactoe (squares integer[3][3]); test=> --- |x00| x = 1, 0 = -1 test=> --- |0xx| вставляем информацию о варианте игры test=> --- | x| крестики начинают и выигрывают test=> INSERT INTO tictactoe test-> VALUES (‘{{1,-1,-1},{-1,1,1},{0,0,1}}’); test=> --- распечатываем сохраненную позицию test=> SELECT * FROM tictactoe ; squares ------------------------------ {{1,-1,-1},{-1,1,1},{0,0,1}} test=> -- распечатываем значение первого столбца test=> SELECT squares[1:3][1:1] FROM tictactoe ; squares ---------------- {{1},{-1},{0}}
Композитный тип (composite type) представляет из себя аналог структуры:
test=> CREATE TYPE complex AS (Re real,Im real);
В отличие от стандартных встроенных типов, использование композитного типа пока имеет некоторые ограничения. Например, из них нельзя создавать массивы.
PostgreSQL позволяет выйти за рамки стандартного SQL в целях создания пользовательских типов данных и операций над ними. Подробнее об этом можно узнать, изучив документацию по команде CREATE TYPE.
[править] Функции
Все стандартные типы имеют свои функции: ведь если есть тип, то с ним нужно работать. Стандартные функций многочисленны[3] и разнообразны. Одних операторов поиска с использованием регулярных выражений — целых три штуки: собственное расширение PostgreSQL (LIKE и ILIKE), оператор, соответствующий стандарту SQL (SIMILAR TO) и POSIX-совместимый оператор (~ и ~*). Все, что только можно было быстро придумать, уже реализовано. А более сложные случаи, например, модуль для полнотекстового поиска tsearch2 (contrib/tsearch2) находятся в процессе совершенствования. Изобрести что-то, выходящее за рамки стандарта тяжело, но если это случится, вы всегда можете создать свою собственную функцию. При желании, ссылаясь на уже имеющуюся функцию, с помощью команды CREATE OPERATOR можно определить оператор для своих типов данных.
[править] Хранимые процедуры
Для создания новых функций используется оператор CREATE FUNCTION, что вполне предсказуемо. Создаваемые таким образом функции исполняются и хранятся на сервере, отсюда и название — «хранимые процедуры»:
test=> -- Создаем и заполняем таблицу test=> CREATE TABLE AplusB (A integer, B integer); test=> INSERT INTO AplusB VALUES (1,1); test=> INSERT INTO AplusB VALUES (2,2); test=> INSERT INTO AplusB VALUES (3,3); test=> -- Создаем новую функцию test=> CREATE FUNCTION plus(integer, integer) RETURNS integer test-> LANGUAGE SQL AS ‘SELECT $1 + $2;’; CREATE FUNCTION test=> SELECT A,B,plus(A,B) FROM AplusB; a | b | plus -----+-----+------ 1 | 1 | 2 2 | 2 | 4 3 | 3 | 6 (записей: 3)
PostgreSQL поддерживает перегрузку функций: объектно-ориентированность имеет свои плюсы. Кроме SQL, для создания новых функций можно использовать процедурные языки программирования. Для начала работы с процедурным языком его необходимо инициализировать. По умолчанию, интерфейсы к языкам, отличным от SQL и C, недоступны по соображениям безопасности. Для инициализации языка используется команда createlang. Запустить ее может только администратор базы данных — тот, кто имеет право создавать базы:
# Инициализируем язык PL/pgSQL для базы данных test > createlang plpgsql test # делаем то же самое, но для языка PL/Perl > createlang plperl test
Теперь можно создавать функции с использованием всех прелестей процедурного программирования, вместе с циклами, каковые по понятным причинам отсутствуют в SQL. Ниже продублирована простейшая функция, которая была описана выше, но теперь уже на PL/pgSQL и на PL/Perl:
test=> -- Создаем новую функцию с использование PL/pgSQL test=> CREATE FUNCTION pgsql_plus(integer, integer) RETURNS integer test-> LANGUAGE PLPGSQL AS ‘BEGIN RETURN $1+$2; END;’; CREATE FUNCTION test=> -- Создаем новую функцию с использование PL/Perl test=> CREATE FUNCTION perl_plus(integer, integer) RETURNS integer test-> LANGUAGE PLPERL AS ‘RETURN $_[0]+$_[1]’; CREATE FUNCTION test=> -- Проверяем, что все работает test=> SELECT pgsql_plus(A,B) FROM AplusB; test=> SELECT plus(A,B),pgsql_plus(A,B),perl_plus(A,B) FROM AplusB; plus | pgsql_plus | perl_plus ------+------------+----------- 2 | 2 | 2 4 | 4 | 4 6 | 6 | 6 (записей: 3)
В стандартной документации подробно описаны идущие вместе с дистрибутивом языки: PL/pgSQL, PL/Tcl, PL/Perl, PL/Python и, естественно, C/C++ с SQL. Кроме перечисленных здесь, есть поддержка
- plPHP http://plphp.commandprompt.com/,
- PL/java http://gborg.PostgreSQL.org/project/pljava/projdisplay.php,
- PL/R http://www.joeconway.com/plr/,
- PL/Ruby http://raa.ruby-lang.org/project/pl-ruby,
- PL/sh http://plsh.projects.PostgreSQL.org/.
Также есть возможность подключения вашего любимого языка.
[править] Триггеры
Обычно для решения несложных задач можно удовлетвориться сценарием: «что сказано — то и сделано», но в более сложных случаях от СУБД хотелось бы получать более сложные реакции в ответ на внешнее «раздражение». Для управления реакцией СУБД на изменение данных используются триггеры. Для создания триггера используется команда CREATE TRIGGER. Полное описание команды в форме Бэкуса-Наура таково:
CREATE TRIGGER «имя триггера» { BEFORE | AFTER } { «событие» [ OR ... ] } ON «имя таблицы» [ FOR [ EACH ] { ROW | STATEMENT } ] EXECUTE PROCEDURE «исполняемая функция - реакция»
Реакция на «событие», которое может быть вставкой (INSERT), изменением (UPDATE), или удалением (DELETE) может производится, по выбору, до (BEFORE) или после (AFTER) изменения данных. Выполнение процедуры может производиться для каждой записи (ROW) или для каждого запроса (STATEMENT). Для показательного примера создания триггера возьмем следующую выдуманную задачу: при изменении данных в описанной уже таблице AplusB сумма A и B должна автоматически обновляться в таблице ABresult. Следующее решение чрезвычайно неоптимально, зато работает:
test=> -- Создаем «результирующую» таблицу test=> CREATE TABLE ABresult (result integer); test=> -- Создаем функцию, очищающую ABresult и test=> -- заполняющую все суммой A и B из AplusB. test=> CREATE FUNCTION ABsumm() returns TRIGGER AS test-> ‘BEGIN test’> DELETE FROM ABresult; test’> INSERT INTO ABresult VALUES (AplusB.A+AplusB.B); test’> RETURN NULL; test’> END;’ test-> LANGUAGE ‘plpgsql’; test=> -- Создаем триггер test=> CREATE TRIGGER makeABresult test=> AFTER INSERT OR UPDATE OR DELETE ON AplusB test=> FOR EACH STATEMENT execute procedure ABsumm(); CREATE TRIGGER test=> -- Добавляем данных в таблицу AplusB test=> INSERT INTO AplusB VALUES (100,200); test=> -- проверяем, что триггер сработал test=> SELECT * FROM AplusB,ABresult WHERE A+B=result; a | b | result -----+-----+-------- 1 | 1 | 2 2 | 2 | 4 3 | 3 | 6 100 | 200 | 300 (записей: 4)
[править] Rules
Кроме триггеров, PostgreSQL обладает еще одним способом управления реакции СУБД на запросы — это rules, или «правила». Для создания «правил» используется команда CREATE RULE. Основное отличие «правила» от триггера в том, что триггер — это реакция системы на изменение данных, а «правило» позволяет изменять сам запрос, в том числе и запрос на получение данных (SELECT). В частности, одно из довольно удобных расширений PostgreSQL — представление или виртуальная таблица (view), реализовано с помощью «правил».
[править] Индексы
Традиционно, для ускорения поиска информацию индексируют. Если данных немного, то можно прожить и так. Серьезные же задачи требуют серьезных объемов, поэтому без индексов не обойтись.
Создание индексов — это ответственность создателя БД. Создание индекса, как можно догадаться, производится с помощью команды
CREATE INDEX: CREATE [ UNIQUE ] INDEX «имя индекса» ON TABLE [ USING «алгоритм» ] ( { «имя столбца» | ( «выражение» ) } [, ...] ) [ WHERE «условие» ]
Индекс может быть уникальным (UNIQUE). В этом случае при создании индекса и при добавлении данных накладывается дополнительное требование на уникальность параметра, по которому создается индекс.
При создании индекса можно выбрать алгоритм индексации. По умолчанию используется B-tree, но доступны также Hash, R-tree или GiST. Алгоритм GiST (http://www.sai.msu.su/~megera/postgres/gist/) был создан Олегом Бартуновым на пару с Федором Сигаевым. GiST является не просто еще одним алгоритмом — это целый конструктор, позволяющим создавать индексы для принципиально новых типов данных. В PostgreSQL 8.2 будут добавлены еще два метода: bitmap и GIN. Если судить по алгоритмам создания индексов, то PostgreSQL — это одна из самых продвинутых СУБД.
Индекс можно создавать по какому-то из столбцов — это самый простой метод. При указании нескольких колонок создаются многоколоночные индексы. Особо следует отметить возможность создания функциональных индексов — в качестве индекса указывается функция от данных таблицы. С помощью функциональных индексов можно реализовать еще один алгоритм индексации: Reverse index (обращает поле переменной — первый символ считается последним).
Условие (WHERE), накладываемое при создании индекса, позволяет создавать частичные индексы (partial indices). Это полезно в тех случаях, когда индексируемый столбец содержит большое число одинаковых значений, а поиск надо производить по редким «чужеродным» вкраплениям.
Для того, чтобы индекс работал, как надо, необходимо следить, чтобы в базе данных регулярно запускалась процедура ANALYZE, которая собирает статистику о распределении значений в индексах. Собранная статистика, в свою очередь, позволяет планировщику верно принимать решение о порядке выполнения запроса. Для оптимизации поиска информации временами может оказаться полезна собственная команда PostgreSQL CLUSTER. С ее помощью можно упорядочить записи в таблице согласно указанному индексу.
[править] Целостность данных
Сохранить, записать, а затем быстро достать данные — вещь полезная, но как отследить, что они записаны правильно и без ошибок? Для этого необходимо постоянно следить за целостностью данных в условиях многопользовательской системы.
[править] Транзакции
Транзакция — это единый блок операций, который нельзя разорвать. Блок либо выполняется целиком, либо все отменяется. В условиях параллельного доступа, PostgreSQL распространяет информацию об операциях только по завершению транзакции. Транзакция начинается с оператора BEGIN и заканчивается оператором COMMIT (подтверждение транзакции) или ROLLBACK (отмена транзакции). Возможен режим, когда каждый запрос сам себе является транзакцией: например, такой режим по умолчанию используется в pSQL. Для отмены этого режима достаточно набрать BEGIN. Неудобством при использовании транзакций является то, что в случае ошибки какого-то из запросов приходится отменять всю транзакцию. Для устранения этого недостатка в PostgreSQL 8.x были добавлены точки сохранения (savepoints).
test=> -- начинаем транзакцию test=> BEGIN; test=> -- здесь идет блок операторов, который удачно завершается test=> -- ставим метку test=> SAVEPOINT savepoint_one; test=> -- здесь идет блок операторов, в котором произошла ошибка test=> -- откатываемся до установленной метки, test=> -- а не отменяем всю транзакцию test=> ROLLBACK TO savepoint_one; test=> -- повторяем последний блок test=> -- завершаем транзакцию test=> COMMIT; test=> -- все, теперь изменения доступны всем
[править] Ограничения
Целостность данных обеспечивает не только многоверсионностью (MVCC) PostgreSQL, но и «архитектором» таблиц базы данных. При создании таблицы (CREATE TABLE) или позже можно добавить ограничение (CONSTRAINT) на диапазон записываемых в таблицу данных. Ограничением могут быть как простые арифметические условные выражения, требования уникальности (UNIQUE или PRIMARY KEY), так и более сложные ограничения в виде внешних ключей (FOREIGN KEY).
Если какой-то столбец A является внешним ключом (FOREIGN KEY) по отношению к столбцу B (REFERENCES), то это означает, что только данные, представленные в столбце B, могут появиться в качестве значений столбца A. В случае внешних ключей PostgreSQL осуществляет автоматический контроль ссылочной целостности[4]. Это довольно интересный механизм, который, в частности, позволяет моделировать иерархические структуры.
[править] Блокировки
Поскольку в условиях параллельного доступа к базе данных каждый пользователь работает со своим мгновенным снимком (следствие MVCC), а не с самой БД, то в принципе можно придумать ситуацию, когда полученные данные «устаревают», так как они были изменены другим пользователем. Если это обстоятельство важно, то PostgreSQL предоставляет полный ассортимент блокировок. С помощью команды LOCK можно заблокировать таблицу, а инструкция SELECT FOR UPDATE позволяет заблокировать отдельные записи. Следует учитывать, что использование блокировок увеличивает шанс взаимной блокировки (deadlock). PostgreSQL умеет определять взаимные блокировки и разрешать их путем прекращения одной из транзакций, но на это уходит время.
[править] Послесловие
Хотелось бы еще раз сказать, что «нельзя объять необъятное». Единственная проблема состоит в том, что конкретно это рассматриваемое нами «необъятное» уже «объято», поэтому за всеми подробностями следует обратиться к стандартной документации, а в качестве бонуса рекомендую хорошую обзорную статью от Олега Бартунова: «Что такое PostgreSQL?»:http://www.sai.msu.su/~Emegera/postgres/talks/what_is_PostgreSQL.html.
- Метамодернизм в позднем творчестве В.Г. Сорокина
- ЛитРПГ - последняя отрыжка постмодерна
- "Ричард III и семиотика"
- 3D-визуализация обложки Ridero создаем обложку книги при работе над самиздатом.
- Архитектура метамодерна - говоря о современном искусстве, невозможно не поговорить об архитектуре. В данной статье будет отмечено несколько интересных принципов, характерных для построек "новой волны", столь притягательных и скандальных.
- Литература
- Метамодерн
- Рокер-Прометей против изначального зла в «Песне про советскую милицию» Вени Дркина, Автор: Нина Ищенко, к.ф.н, член Союза Писателей ЛНР - перепубликация из журнала "Топос".
- Как избавиться от комаров? Лучшие типы ловушек.
- Что делать если роблокс вылетает на windows
- Что делать, если ребенок смотрит порно?
- Почему собака прыгает на людей при встрече?
- Какое масло лить в Задний дифференциал (мост) Visco diff 38434AA050
- О чем может рассказать хвост вашей кошки?
- Верветки
- Отчетность бюджетных учреждений при закупках по Закону № 223-ФЗ
- Срок исковой давности как правильно рассчитать
- Дмитрий Патрушев минсельхоз будет ли преемником Путина
- Кто такой Владислав Поздняков? Что такое "Мужское Государство" и почему его признали экстремистским в России?
- Как правильно выбрать машинное масло в Димитровграде?
- Как стать богатым и знаменитым в России?
- Почему фильм "Пипец" (Kick-Ass) стал популярен по всему миру?
- Как стать мудрецом?
- Как правильно установить FreeBSD
- Как стать таким как Путин?
- Где лучше жить - в Димитровграде или в Ульяновске?
- Почему город Димитровград так называется?
- Что такое метамодерн?
- ВАЖНО! Временное ограничение движения автотранспортных средств в Димитровграде
- Тарифы на электроэнергию для майнеров предложено повысить
- ↑ Транзакция представляет собой последовательность операций, которая обязана либо выполниться полностью, либо отмениться совсем, как будто это единое целое. При этом, независимо от других параллельно идущих транзакций (isolation), должна сохраняться целостность данных (consistency).
- ↑ Этот момент отражен в FAQ fido7.ru.os.cmp следующим образом:
Q51: Народ, а вы стабильным софтом пользоваться не пробовали?
A51: Пробовали, но мэйнфреймы с дизель-генераторами не везде есть. - ↑ Их больше 1500. Полный список можно вывести, набрав в psql команду \df.
- ↑ Ссылочная целостность — гарантированное отсутствие внешних ключей, ссылающихся на несуществующие записи в этой или других таблицах.