<?xml version="1.0" encoding="utf-8"?>
<?xml-stylesheet type="text/css" href="http://wiki2.linuxformat.ru/skins/common/feed.css?97"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="ru">
		<id>http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF87-88%3APostgreSQL</id>
		<title>LXF87-88:PostgreSQL - История изменений</title>
		<link rel="self" type="application/atom+xml" href="http://wiki2.linuxformat.ru/index.php?action=history&amp;feed=atom&amp;title=LXF87-88%3APostgreSQL"/>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;action=history"/>
		<updated>2026-05-13T23:41:15Z</updated>
		<subtitle>История изменений этой страницы в вики</subtitle>
		<generator>MediaWiki 1.11.1</generator>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4913&amp;oldid=prev</id>
		<title>Yaleks: /* Работа с базой */</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4913&amp;oldid=prev"/>
				<updated>2008-06-29T13:34:22Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;span class=&quot;autocomment&quot;&gt;Работа с базой&lt;/span&gt;&lt;/p&gt;

			&lt;table style=&quot;background-color: white; color:black;&quot;&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;col class='diff-marker' /&gt;
			&lt;col class='diff-content' /&gt;
			&lt;tr&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;← Предыдущая&lt;/td&gt;
				&lt;td colspan='2' style=&quot;background-color: white; color:black;&quot;&gt;Версия 13:34, 29 июня 2008&lt;/td&gt;
			&lt;/tr&gt;
		&lt;tr&gt;&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 4:&lt;/td&gt;
&lt;td colspan=&quot;2&quot; class=&quot;diff-lineno&quot;&gt;Строка 4:&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;''ЧАСТЬ 3: Вы уже неоднократно слышали, что PostgreSQL — это одна из самых мощных открытых СУБД, и сегодня '''Евгений Балдин''' расскажет вам, почему.''&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;''ЧАСТЬ 3: Вы уже неоднократно слышали, что PostgreSQL — это одна из самых мощных открытых СУБД, и сегодня '''Евгений Балдин''' расскажет вам, почему.''&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;{| align=&amp;quot;right&amp;quot;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt; | «Познание бесконечности требует бесконечного времени».&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;&amp;lt;div align=&amp;quot;right&amp;quot;&amp;gt;Девиз отдела Абсолютного Знания&amp;lt;br /&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;«Понедельник начинается в субботу»&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td colspan=&quot;2&quot;&gt;&amp;nbsp;&lt;/td&gt;&lt;td class='diff-marker'&gt;+&lt;/td&gt;&lt;td style=&quot;background: #cfc; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;|}&amp;lt;div style=&amp;quot;clear:both;&amp;quot;&amp;gt;&amp;lt;/div&amp;gt;&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;В этой статье мы предпримем попытку сделать краткий обзор&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;В этой статье мы предпримем попытку сделать краткий обзор&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;tr&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;возможностей PostgreSQL. Не надо иллюзий — «объять необъятное невозможно», поэтому многое из интересного осталось&lt;/div&gt;&lt;/td&gt;&lt;td class='diff-marker'&gt; &lt;/td&gt;&lt;td style=&quot;background: #eee; color:black; font-size: smaller;&quot;&gt;&lt;div&gt;возможностей PostgreSQL. Не надо иллюзий — «объять необъятное невозможно», поэтому многое из интересного осталось&lt;/div&gt;&lt;/td&gt;&lt;/tr&gt;
&lt;/table&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4911&amp;oldid=prev</id>
		<title>Yaleks: викификация</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4911&amp;oldid=prev"/>
				<updated>2008-06-29T13:18:56Z</updated>
		
		<summary type="html">&lt;p&gt;викификация&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;amp;diff=4911&amp;amp;oldid=4910&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4910&amp;oldid=prev</id>
		<title>Yaleks в 13:18, 29 июня 2008</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4910&amp;oldid=prev"/>
				<updated>2008-06-29T13:18:03Z</updated>
		
		<summary type="html">&lt;p&gt;&lt;/p&gt;
&lt;a href=&quot;http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;amp;diff=4910&amp;amp;oldid=4907&quot;&gt;(Различия между версиями)&lt;/a&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	<entry>
		<id>http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4907&amp;oldid=prev</id>
		<title>Yaleks: uncomplete</title>
		<link rel="alternate" type="text/html" href="http://wiki2.linuxformat.ru/index.php?title=LXF87-88:PostgreSQL&amp;diff=4907&amp;oldid=prev"/>
				<updated>2008-06-28T18:39:46Z</updated>
		
		<summary type="html">&lt;p&gt;uncomplete&lt;/p&gt;
&lt;p&gt;&lt;b&gt;Новая статья&lt;/b&gt;&lt;/p&gt;&lt;div&gt;{{цикл/PostgreSQL}}&lt;br /&gt;
&lt;br /&gt;
== Работа с базой ==&lt;br /&gt;
''ЧАСТЬ 3: Вы уже неоднократно слышали, что PostgreSQL – это одна из самых мощных открытых СУБД, и сегодня '''Евгений Балдин''' расскажет вам, почему.''&lt;br /&gt;
&lt;br /&gt;
В этой статье мы предпримем попытку сделать краткий обзор&lt;br /&gt;
возможностей PostgreSQL. Не надо иллюзий – «объять необъ-&lt;br /&gt;
ятное невозможно», поэтому многое из интересного осталось&lt;br /&gt;
за кадром, но все же «попытка – не пытка».&lt;br /&gt;
&lt;br /&gt;
=== Немного об основах ===&lt;br /&gt;
Применительно к базам данных часто упоминается принцип ACID: ато-&lt;br /&gt;
марность (Аtomicity), целостность (Consistency), локализация пользо-&lt;br /&gt;
вательских процессов (Isolation) и устойчивость к ошибкам (Durability).&lt;br /&gt;
&lt;br /&gt;
Для обеспечения совместной работы множества пользователей&lt;br /&gt;
(concurrency) в целях следования заветам ACID, PostgreSQL использу-&lt;br /&gt;
ет систему управления версиями или MVCC (Multi-Version Concurrency&lt;br /&gt;
Control). При подсоединении пользователя MVCC «подсовывает» ему&lt;br /&gt;
собственную версию или мгновенный снимок (snapshot) базы дан-&lt;br /&gt;
ных. В этом случае изменения, производимые пользователем, неви-&lt;br /&gt;
димы другими пользователями до тех пор, пока текущая транзакция&amp;lt;ref&amp;gt;Транзакция представляет собой последовательность операций, которая обязана либо&lt;br /&gt;
выполниться полностью, либо отмениться совсем, как будто это единое целое. При этом,&lt;br /&gt;
независимо от других параллельно идущих транзакций (isolation), должна сохраняться&lt;br /&gt;
целостность данных (consistency).&amp;lt;/ref&amp;gt;&lt;br /&gt;
(transaction) не подтверждается (commit). Кроме проблем, связанных&lt;br /&gt;
с ACID, многоверсионность позволяет уменьшить или даже, во мно-&lt;br /&gt;
гих случаях, исключить необходимость блокировки данных (locks)&lt;br /&gt;
при чтении.&lt;br /&gt;
Надежность&amp;lt;ref&amp;gt;Этот момент отражен в FAQ fido7.ru.os.cmp следующим образом:&amp;lt;br /&amp;gt;&lt;br /&gt;
Q51: Народ, а вы стабильным софтом пользоваться не пробовали?&amp;lt;br /&amp;gt;&lt;br /&gt;
A51: Пробовали, но мэйнфреймы с дизель-генераторами не везде есть.&amp;lt;/ref&amp;gt; (reliability) сохранения данных является одним из&lt;br /&gt;
основных показателей качества СУБД. Сохранение измененных дан-&lt;br /&gt;
ных – очень нетривиальная процедура. Дело в том, что диски очень&lt;br /&gt;
«ме-е-едленные», поэтому прежде чем попасть на диск, данные про-&lt;br /&gt;
ходят через промежуточные буферы (cache), начиная от системного&lt;br /&gt;
кэша файловой системы, заканчивая кэшем на самом диске. Никто&lt;br /&gt;
не сможет гарантировать, что все в них положенное, в случае воз-&lt;br /&gt;
никновения каких-либо проблем, окажется в безопасном постоянном&lt;br /&gt;
хранилище. Для максимального уменьшения вероятности потери дан-&lt;br /&gt;
ных PostgreSQL использует журнал транзакций или Write Ahead Log&lt;br /&gt;
(WAL). Прежде чем записать данные о проведенной транзакции на&lt;br /&gt;
диск, информация об изменениях заносится в WAL. Если что-то слу-&lt;br /&gt;
чилось, то данные можно восстановить по журналу. Если данные не&lt;br /&gt;
попали в журнал, то, соответственно, исчезнет вся транзакция – жалко,&lt;br /&gt;
конечно, зато целостность не нарушается. Следствием использования&lt;br /&gt;
WAL является отсутствие необходимости «скидывать» данные на диск&lt;br /&gt;
с помощью fsync, так как достаточно убедиться, что записан WAL. Это&lt;br /&gt;
значительно увеличивает производительность в многопользователь-&lt;br /&gt;
ской среде с множеством мелких запросов на изменение данных, так&lt;br /&gt;
как записать один последовательный файл WAL гораздо проще, чем&lt;br /&gt;
изменять множество таблиц по всем диску. В качестве бонуса журнал&lt;br /&gt;
транзакций позволяет организовать непрерывное резервное копиро-&lt;br /&gt;
вание данных (on-line backup) – мечту администратора и возможность&lt;br /&gt;
«отката» базы данных на любой момент в прошлом (point-in-time&lt;br /&gt;
recovery) – своеобразную машину времени.&lt;br /&gt;
&lt;br /&gt;
=== Типы данных ===&lt;br /&gt;
Как и положено базе данных, PostgreSQL поддерживает довольно мно-&lt;br /&gt;
го стандартных типов данных. Более того, пользователь может опреде-&lt;br /&gt;
лять свои собственные типы данных, если он не найдет необходимых&lt;br /&gt;
примитивов среди стандартных.&lt;br /&gt;
==== Числовые типы ====&lt;br /&gt;
Обычные числовые (numeric) типы представлены целыми числами в&lt;br /&gt;
два (smallint), четыре (integer) или восемь (bigint) байт длиной, числа&lt;br /&gt;
с плавающей точкой – в четыре (real) и восемь байт (double precision)&lt;br /&gt;
длиной. Кроме обычных чисел, в случае real и double поддерживаются&lt;br /&gt;
значения Infinity, -Infinity и NaN – бесконечность ( ), минус бесконеч-&lt;br /&gt;
ность (- ) и «не число» (not-a-number), соответственно.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL поддерживает числа с произвольной точностью&lt;br /&gt;
numeric(precision,scale), где precision – число всех знаков в опреде-&lt;br /&gt;
ляемой величине, а scale – число знаков в дробной части. PostgreSQL&lt;br /&gt;
позволяет выполнять действия без накопления ошибки с подобными&lt;br /&gt;
величинами с точностью вплоть до 1000 знаков. Этим типом данных&lt;br /&gt;
не следует злоупотреблять, так как операции над подобными числами&lt;br /&gt;
занимают очень много времени.&lt;br /&gt;
Битовые поля представлены типами bit(size) – битовая строка фик-&lt;br /&gt;
сированной длины size и bit varying(size) – битовая строка переменной&lt;br /&gt;
длины с ограничением по размеру size.&lt;br /&gt;
К числовым типам PostgreSQL относятся и «псевдотипы» serial и&lt;br /&gt;
bigserial. Эти типы соответствуют типам integer и bigint, за исключени-&lt;br /&gt;
ем того, что при записи новых данных в таблицу с колонкой этого типа,&lt;br /&gt;
значение по умолчанию в ней увеличивается на единицу – то есть это&lt;br /&gt;
автоматически создаваемая упорядоченная последовательность.&lt;br /&gt;
&lt;br /&gt;
==== Символьные типы ====&lt;br /&gt;
В стандарте SQL символьный тип определяется как строка опреде-&lt;br /&gt;
ленной длины character(size), где size – длина строки. В дополнение к&lt;br /&gt;
стандарту, PostgreSQL поддерживает строки переменной длины с огра-&lt;br /&gt;
ничением varchar(size) и без ограничения – text.&lt;br /&gt;
&lt;br /&gt;
==== Бинарные типы ====&lt;br /&gt;
Бинарную строку можно сохранить, используя тип bytea. SQL предпо-&lt;br /&gt;
лагает, что вся информация передается как текст, поэтому при переда-&lt;br /&gt;
че данных следует экранировать некоторые из символов.&lt;br /&gt;
В PostgreSQL есть специальный тип данных Large Objects. По сути&lt;br /&gt;
дела, это просто способ сохранять любые файлы размером вплоть до&lt;br /&gt;
2 Гб прямо в базе данных. Операции с подобными объектами выходит&lt;br /&gt;
за рамки SQL. Для доступа к Large Objects есть специальный програм-&lt;br /&gt;
мный интерфейс, смоделированный по образу и подобию обычного&lt;br /&gt;
чтения/записи файла.&lt;br /&gt;
&lt;br /&gt;
==== Типы даты/времени ====&lt;br /&gt;
Временем в PostgreSQL заведует тип timestamp или timestamp with time&lt;br /&gt;
zone – он может хранить дату и время, начиная с 4713 г. до н.э. вплоть&lt;br /&gt;
до 5874897 г., с точностью в одну микросекунду (μс), занимая восемь&lt;br /&gt;
байт. Второй упомянутый тип включает часовой пояс и позволяет авто-&lt;br /&gt;
матически учитывать переход на летнее/зимнее время. С таким диапа-&lt;br /&gt;
зоном и точностью проблема типа широко разрекламированной Y2K&lt;br /&gt;
случится не скоро.&lt;br /&gt;
Разница между двумя датами представлена типом interval длиной в&lt;br /&gt;
двенадцать байт, что позволяет хранить информацию о событиях, свя-&lt;br /&gt;
занных даже с рождением и смертью Вселенной.&lt;br /&gt;
Также есть отдельный тип для календарного времени (date) и прос-&lt;br /&gt;
то для времени (time или time with timezone).&lt;br /&gt;
PostgreSQL поддерживает множество способов ввода даты и вре-&lt;br /&gt;
мени. С моей точки зрения, в некоторых случаях СУБД проявляет&lt;br /&gt;
излишний интеллект, поэтому рекомендую выбрать стандартный ISO,&lt;br /&gt;
который выглядит примерно так:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; -- узнаем текущее время с точностью до секунды&lt;br /&gt;
test=&amp;gt; select date_trunc(‘seconds’,timestamp with time zone ‘now’);&lt;br /&gt;
date_trunc&lt;br /&gt;
------------------------&lt;br /&gt;
2006-08-26 21:08:14+07&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В таком случае ошибиться в порядке месяца и дня становится весь-&lt;br /&gt;
ма затруднительно, независимо от того, какая локаль используется&lt;br /&gt;
системой.&lt;br /&gt;
Для типа timestamp определены дополнительные константы:&lt;br /&gt;
* epoch – начало эпохи с точки зрения времени Unix (четырехбайтовый time_t): 1970-01-01 00:00:00+00;&lt;br /&gt;
* infinity – позже, чем любое возможное из времен;&lt;br /&gt;
* -infinity – раньше, чем любое возможное из времен;&lt;br /&gt;
* now – здесь и сейчас;&lt;br /&gt;
* today – сегодняшняя полночь; аналогично, yesterday – вчерашняя полночь и, tomorrow – завтрашняя полночь.&lt;br /&gt;
&lt;br /&gt;
==== Логические типы ====&lt;br /&gt;
Логические типы представлены типом boolean. Логично, что он прини-&lt;br /&gt;
мает значения либо TRUE (‘t’, ‘true’, ‘y’,’yes’, ‘1’) – «истина», либо FALSE&lt;br /&gt;
(‘f’, ‘false’, ‘n’, ‘no’, ‘0’) – «ложь». Все просто, за исключением одного&lt;br /&gt;
«но» – есть еще одна возможность: «значение не определено» (NULL).&lt;br /&gt;
Собственно говоря, это не особенность типа boolean. При использова-&lt;br /&gt;
нии SQL, с тем, что значение может быть не определено, необходимо&lt;br /&gt;
считаться всегда и везде. Вот такая вот логика – вовсе не двоичная.&lt;br /&gt;
&lt;br /&gt;
==== Остальные стандартные типы ====&lt;br /&gt;
К оставшимся стандартным типа относятся различные геометричес-&lt;br /&gt;
кие типы данных: точка (point), линия (line), отрезок (lseg), прямо-&lt;br /&gt;
угольник (box), путь (path), замкнутый путь (polygon) и окружность&lt;br /&gt;
(circle). Для системных администраторов будут интересны стандарт-&lt;br /&gt;
ные типы сетевых IPv4 и IPv6-адресов (cidr или inet) и тип МАС-адре-&lt;br /&gt;
са (macaddr).&lt;br /&gt;
Более сложные типы реализуются как дополнения. Яркими приме-&lt;br /&gt;
рами служат поддержка географических объектов GIS (http://postgis.&lt;br /&gt;
refractions.net/) и иерархический тип данных ltree (contrib/ltree).&lt;br /&gt;
&lt;br /&gt;
==== Определение пользовательских типов ====&lt;br /&gt;
Прежде всего следует упомянуть, что PostgreSQL поддерживает масси-&lt;br /&gt;
вы. Можно создать массив определенного размера или безразмерный,&lt;br /&gt;
на основе любого стандартного типа или типа, определенного пользо-&lt;br /&gt;
вателем. Поддерживаются многомерные массивы и операции над ними,&lt;br /&gt;
например, «срезы».&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; --- создаем массив для игры в «крестики-нолики»&lt;br /&gt;
test=&amp;gt; create table tictactoe (squares integer[3][3]);&lt;br /&gt;
test=&amp;gt; --- |x00| x = 1, 0 = -1&lt;br /&gt;
test=&amp;gt; --- |0xx| вставляем информацию о варианте игры&lt;br /&gt;
test=&amp;gt; --- | x| крестики начинают и выигрывают&lt;br /&gt;
test=&amp;gt; insert into tictactoe&lt;br /&gt;
test-&amp;gt; values (‘{{1,-1,-1},{-1,1,1},{0,0,1}}’);&lt;br /&gt;
test=&amp;gt; --- распечатываем сохраненную позицию&lt;br /&gt;
test=&amp;gt; select * from tictactoe ;&lt;br /&gt;
squares&lt;br /&gt;
------------------------------&lt;br /&gt;
{{1,-1,-1},{-1,1,1},{0,0,1}}&lt;br /&gt;
test=&amp;gt; -- распечатываем значение первого столбца&lt;br /&gt;
test=&amp;gt; select squares[1:3][1:1] from tictactoe ;&lt;br /&gt;
squares&lt;br /&gt;
----------------&lt;br /&gt;
{{1},{-1},{0}}&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Композитный тип (composite type) представляет из себя аналог&lt;br /&gt;
структуры:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; CREATE TYPE complex AS (Re real,Im real);&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В отличие от стандартных встроенных типов, использование ком-&lt;br /&gt;
позитного типа пока имеет некоторые ограничения. Например, из них&lt;br /&gt;
нельзя создавать массивы.&lt;br /&gt;
&lt;br /&gt;
PostgreSQL позволяет выйти за рамки стандартного SQL в целях&lt;br /&gt;
создания пользовательских типов данных и операций над ними.&lt;br /&gt;
Подробнее об этом можно узнать, изучив документацию по команде&lt;br /&gt;
CREATE TYPE.&lt;br /&gt;
&lt;br /&gt;
=== Функции ===&lt;br /&gt;
Все стандартные типы имеют свои функции: ведь если есть тип, то&lt;br /&gt;
с ним нужно работать. Стандартные функций многочисленны3 и раз-&lt;br /&gt;
нообразны. Одних операторов поиска с использованием регулярных&lt;br /&gt;
выражений – целых три штуки: собственное расширение PostgreSQL&lt;br /&gt;
(LIKE и ILIKE), оператор, соответствующий стандарту SQL (SIMILAR TO)&lt;br /&gt;
и POSIX-совместимый оператор (~ и ~*). Все, что только можно было&lt;br /&gt;
быстро придумать, уже реализовано. А более сложные случаи, напри-&lt;br /&gt;
мер, модуль для полнотекстового поиска tsearch2 (contrib/tsearch2)&lt;br /&gt;
находятся в процессе совершенствования. Изобрести что-то, выходя-&lt;br /&gt;
щее за рамки стандарта тяжело, но если это случится, вы всегда може-&lt;br /&gt;
те создать свою собственную функцию. При желании, ссылаясь на уже&lt;br /&gt;
имеющуюся функцию, с помощью команды CREATE OPERATOR можно&lt;br /&gt;
определить оператор для своих типов данных.&lt;br /&gt;
&lt;br /&gt;
==== Хранимые процедуры ====&lt;br /&gt;
Для создания новых функций используется оператор CREATE FUNCTION,&lt;br /&gt;
что вполне предсказуемо. Создаваемые таким образом функции&lt;br /&gt;
исполняются и хранятся на сервере, отсюда и название – «хранимые&lt;br /&gt;
процедуры»:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; -- Создаем и заполняем таблицу&lt;br /&gt;
test=&amp;gt; create table AplusB (A integer, B integer);&lt;br /&gt;
test=&amp;gt; insert INTO AplusB VALUES (1,1);&lt;br /&gt;
test=&amp;gt; insert INTO AplusB VALUES (2,2);&lt;br /&gt;
test=&amp;gt; insert INTO AplusB VALUES (3,3);&lt;br /&gt;
test=&amp;gt; -- Создаем новую функцию&lt;br /&gt;
test=&amp;gt; CREATE FUNCTION plus(integer, integer) RETURNS integer&lt;br /&gt;
test-&amp;gt; LANGUAGE SQL as ‘SELECT $1 + $2;’;&lt;br /&gt;
CREATE FUNCTION&lt;br /&gt;
test=&amp;gt; select A,B,plus(A,B) from AplusB;&lt;br /&gt;
a | b | plus&lt;br /&gt;
-----+-----+------&lt;br /&gt;
1 | 1 | 2&lt;br /&gt;
2 | 2 | 4&lt;br /&gt;
3 | 3 | 6&lt;br /&gt;
(записей: 3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
PostgreSQL поддерживает перегрузку функций: объектно-ори-&lt;br /&gt;
ентированность имеет свои плюсы. Кроме SQL, для создания новых&lt;br /&gt;
функций можно использовать процедурные языки программирования.&lt;br /&gt;
Для начала работы с процедурным языком его необходимо инициали-&lt;br /&gt;
зировать. По умолчанию, интерфейсы к языкам, отличным от SQL и C,&lt;br /&gt;
недоступны по соображениям безопасности. Для инициализации язы-&lt;br /&gt;
ка используется команда createlang. Запустить ее может только адми-&lt;br /&gt;
нистратор базы данных – тот, кто имеет право создавать базы:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
# Инициализируем язык PL/pgSQL для базы данных test&lt;br /&gt;
&amp;gt; createlang plpgsql test&lt;br /&gt;
# делаем то же самое, но для языка PL/Perl&lt;br /&gt;
&amp;gt; createlang plperl test&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Теперь можно создавать функции с использованием всех прелес-&lt;br /&gt;
тей процедурного программирования, вместе с циклами, каковые по&lt;br /&gt;
понятным причинам отсутствуют в SQL. Ниже продублирована про-&lt;br /&gt;
стейшая функция, которая была описана выше, но теперь уже на PL/&lt;br /&gt;
pgSQL и на PL/Perl:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; -- Создаем новую функцию с использование PL/pgSQL&lt;br /&gt;
test=&amp;gt; CREATE FUNCTION pgsql_plus(integer, integer) RETURNS integer&lt;br /&gt;
test-&amp;gt; LANGUAGE PLPGSQL as ‘BEGIN return $1+$2; END;’;&lt;br /&gt;
CREATE FUNCTION&lt;br /&gt;
test=&amp;gt; -- Создаем новую функцию с использование PL/Perl&lt;br /&gt;
test=&amp;gt; CREATE FUNCTION perl_plus(integer, integer) RETURNS integer&lt;br /&gt;
test-&amp;gt; LANGUAGE PLPERL as ‘return $_[0]+$_[1]’;&lt;br /&gt;
CREATE FUNCTION&lt;br /&gt;
test=&amp;gt; -- Проверяем, что все работает&lt;br /&gt;
test=&amp;gt; select pgsql_plus(A,B) from AplusB;&lt;br /&gt;
test=&amp;gt; select plus(A,B),pgsql_plus(A,B),perl_plus(A,B) from AplusB;&lt;br /&gt;
plus | pgsql_plus | perl_plus&lt;br /&gt;
------+------------+-----------&lt;br /&gt;
2 | 2 | 2&lt;br /&gt;
4 | 4 | 4&lt;br /&gt;
6 | 6 | 6&lt;br /&gt;
(записей: 3)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
В стандартной документации подробно описаны идущие вместе с&lt;br /&gt;
дистрибутивом языки: PL/pgSQL, PL/Tcl, PL/Perl, PL/Python и, естест-&lt;br /&gt;
венно, C/C++ с SQL. Кроме перечисленных здесь, есть поддержка&lt;br /&gt;
* plPHP http://plphp.commandprompt.com/,&lt;br /&gt;
* PL/java http://gborg.PostgreSQL.org/project/pljava/projdisplay.php,&lt;br /&gt;
* PL/R http://www.joeconway.com/plr/,&lt;br /&gt;
* PL/Ruby http://raa.ruby-lang.org/project/pl-ruby,&lt;br /&gt;
* PL/sh http://plsh.projects.PostgreSQL.org/.&lt;br /&gt;
Также есть возможность подключения вашего любимого языка.&lt;br /&gt;
&lt;br /&gt;
==== Триггеры ====&lt;br /&gt;
Обычно для решения несложных задач можно удовлетвориться сце-&lt;br /&gt;
нарием: «что сказано – то и сделано», но в более сложных случаях от&lt;br /&gt;
СУБД хотелось бы получать более сложные реакции в ответ на внешнее&lt;br /&gt;
«раздражение». Для управления реакцией СУБД на изменение данных&lt;br /&gt;
используются триггеры. Для создания триггера используется команда&lt;br /&gt;
CREATE TRIGGER.&lt;br /&gt;
Полное описание команды в форме Бэкуса-Наура таково:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE TRIGGER «имя триггера»&lt;br /&gt;
{ BEFORE | AFTER } { «событие» [ OR ... ] }&lt;br /&gt;
ON «имя таблицы» [ FOR [ EACH ] { ROW | STATEMENT } ]&lt;br /&gt;
EXECUTE PROCEDURE «исполняемая функция - реакция»&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Реакция на «событие», которое может быть вставкой (INSERT),&lt;br /&gt;
изменением (UPDATE), или удалением (DELETE) может производит-&lt;br /&gt;
ся, по выбору, до (BEFORE) или после (AFTER) изменения данных.&lt;br /&gt;
Выполнение процедуры может производиться для каждой записи&lt;br /&gt;
(ROW) или для каждого запроса (STATEMENT). Для показательного&lt;br /&gt;
примера создания триггера возьмем следующую выдуманную задачу:&lt;br /&gt;
при изменении данных в описанной уже таблице AplusB сумма A и B&lt;br /&gt;
должна автоматически обновляться в таблице ABresult. Следующее&lt;br /&gt;
решение чрезвычайно неоптимально, зато работает:&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; -- Создаем «результирующую» таблицу&lt;br /&gt;
test=&amp;gt; create table ABresult (result integer);&lt;br /&gt;
test=&amp;gt; -- Создаем функцию, очищающую ABresult и&lt;br /&gt;
test=&amp;gt; -- заполняющую все суммой A и B из AplusB.&lt;br /&gt;
test=&amp;gt; create function ABsumm() returns trigger as&lt;br /&gt;
test-&amp;gt; ‘BEGIN&lt;br /&gt;
test’&amp;gt; delete from ABresult;&lt;br /&gt;
test’&amp;gt; insert into ABresult values (AplusB.A+AplusB.B);&lt;br /&gt;
test’&amp;gt; return NULL;&lt;br /&gt;
test’&amp;gt; END;’&lt;br /&gt;
test-&amp;gt; language ‘plpgsql’;&lt;br /&gt;
test=&amp;gt; -- Создаем триггер&lt;br /&gt;
test=&amp;gt; CREATE TRIGGER makeABresult&lt;br /&gt;
test=&amp;gt; AFTER INSERT or UPDATE or DELETE on AplusB&lt;br /&gt;
test=&amp;gt; FOR EACH STATEMENT execute procedure ABsumm();&lt;br /&gt;
CREATE TRIGGER&lt;br /&gt;
test=&amp;gt; -- Добавляем данных в таблицу AplusB&lt;br /&gt;
test=&amp;gt; insert into AplusB VALUES (100,200);&lt;br /&gt;
test=&amp;gt; -- проверяем, что триггер сработал&lt;br /&gt;
test=&amp;gt; select * from AplusB,ABresult where A+B=result;&lt;br /&gt;
a | b | result&lt;br /&gt;
-----+-----+--------&lt;br /&gt;
1 | 1 | 2&lt;br /&gt;
2 | 2 | 4&lt;br /&gt;
3 | 3 | 6&lt;br /&gt;
100 | 200 | 300&lt;br /&gt;
(записей: 4)&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Rules ====&lt;br /&gt;
Кроме триггеров, PostgreSQL обладает еще одним способом управле-&lt;br /&gt;
ния реакции СУБД на запросы – это rules, или «правила». Для создания&lt;br /&gt;
«правил» используется команда CREATE RULE. Основное отличие «пра-&lt;br /&gt;
вила» от триггера в том, что триггер – это реакция системы на измене-&lt;br /&gt;
ние данных, а «правило» позволяет изменять сам запрос, в том числе&lt;br /&gt;
и запрос на получение данных (SELECT). В частности, одно из доволь-&lt;br /&gt;
но удобных расширений PostgreSQL – представление или виртуальная&lt;br /&gt;
таблица (view), реализовано с помощью «правил».&lt;br /&gt;
&lt;br /&gt;
=== Индексы ===&lt;br /&gt;
Традиционно, для ускорения поиска информацию индексируют. Если&lt;br /&gt;
данных немного, то можно прожить и так. Серьезные же задачи требу-&lt;br /&gt;
ют серьезных объемов, поэтому без индексов не обойтись.&lt;br /&gt;
Создание индексов – это ответственность создателя БД. Создание&lt;br /&gt;
индекса, как можно догадаться, производится с помощью команды&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
CREATE INDEX:&lt;br /&gt;
CREATE [ UNIQUE ] INDEX «имя индекса» ON table [ USING «алгоритм»&lt;br /&gt;
]&lt;br /&gt;
( { «имя столбца» | ( «выражение» ) } [, ...] )&lt;br /&gt;
[ WHERE «условие» ]&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
Индекс может быть уникальным (UNIQUE). В этом случае при созда-&lt;br /&gt;
нии индекса и при добавлении данных накладывается дополнительное&lt;br /&gt;
требование на уникальность параметра, по которому создается индекс.&lt;br /&gt;
При создании индекса можно выбрать алгоритм индексации. По&lt;br /&gt;
умолчанию используется B-tree, но доступны также Hash, R-tree или&lt;br /&gt;
GiST. Алгоритм GiST (http://www.sai.msu.su/~megera/postgres/gist/) был&lt;br /&gt;
создан Олегом Бартуновым на пару с Федором Сигаевым. GiST являет-&lt;br /&gt;
ся не просто еще одним алгоритмом – это целый конструктор, позво-&lt;br /&gt;
ляющим создавать индексы для принципиально новых типов данных.&lt;br /&gt;
В PostgreSQL 8.2 будут добавлены еще два метода: bitmap и GIN. Если&lt;br /&gt;
судить по алгоритмам создания индексов, то PostgreSQL – это одна из&lt;br /&gt;
самых продвинутых СУБД.&lt;br /&gt;
Индекс можно создавать по какому-то из столбцов – это самый&lt;br /&gt;
простой метод. При указании нескольких колонок создаются много-&lt;br /&gt;
колоночные индексы. Особо следует отметить возможность создания&lt;br /&gt;
функциональных индексов – в качестве индекса указывается функция&lt;br /&gt;
от данных таблицы. С помощью функциональных индексов можно реа-&lt;br /&gt;
лизовать еще один алгоритм индексации: Reverse index (обращает поле&lt;br /&gt;
переменной – первый символ считается последним).&lt;br /&gt;
Условие (WHERE), накладываемое при создании индекса, позволяет&lt;br /&gt;
создавать частичные индексы (partial indices). Это полезно в тех случаях,&lt;br /&gt;
когда индексируемый столбец содержит большое число одинаковых зна-&lt;br /&gt;
чений, а поиск надо производить по редким «чужеродным» вкраплениям.&lt;br /&gt;
Для того, чтобы индекс работал, как надо, необходимо следить,&lt;br /&gt;
чтобы в базе данных регулярно запускалась процедура ANALYZE,&lt;br /&gt;
которая собирает статистику о распределении значений в индексах.&lt;br /&gt;
Собранная статистика, в свою очередь, позволяет планировщику верно&lt;br /&gt;
принимать решение о порядке выполнения запроса. Для оптимизации&lt;br /&gt;
поиска информации временами может оказаться полезна собственная&lt;br /&gt;
команда PostgreSQL CLUSTER. С ее помощью можно упорядочить запи-&lt;br /&gt;
си в таблице согласно указанному индексу.&lt;br /&gt;
&lt;br /&gt;
=== Целостность данных ===&lt;br /&gt;
Сохранить, записать, а затем быстро достать данные – вещь полезная,&lt;br /&gt;
но как отследить, что они записаны правильно и без ошибок? Для это-&lt;br /&gt;
го необходимо постоянно следить за целостностью данных в условиях&lt;br /&gt;
многопользовательской системы.&lt;br /&gt;
&lt;br /&gt;
==== Транзакции ====&lt;br /&gt;
Транзакция – это единый блок операций, который нельзя разорвать.&lt;br /&gt;
Блок либо выполняется целиком, либо все отменяется. В условиях&lt;br /&gt;
параллельного доступа, PostgreSQL распространяет информацию об&lt;br /&gt;
операциях только по завершению транзакции. Транзакция начинается&lt;br /&gt;
с оператора BEGIN и заканчивается оператором COMMIT (подтвержде-&lt;br /&gt;
ние транзакции) или ROLLBACK (отмена транзакции). Возможен режим,&lt;br /&gt;
когда каждый запрос сам себе является транзакцией: например, такой&lt;br /&gt;
режим по умолчанию используется в pSQL. Для отмены этого режима&lt;br /&gt;
достаточно набрать BEGIN. Неудобством при использовании транзак-&lt;br /&gt;
ций является то, что в случае ошибки какого-то из запросов прихо-&lt;br /&gt;
дится отменять всю транзакцию. Для устранения этого недостатка в&lt;br /&gt;
PostgreSQL 8.x были добавлены точки сохранения (savepoints).&lt;br /&gt;
&amp;lt;source lang=&amp;quot;sql&amp;quot;&amp;gt;&lt;br /&gt;
test=&amp;gt; -- начинаем транзакцию&lt;br /&gt;
test=&amp;gt; BEGIN;&lt;br /&gt;
test=&amp;gt; -- здесь идет блок операторов, который удачно завершается&lt;br /&gt;
test=&amp;gt; -- ставим метку&lt;br /&gt;
test=&amp;gt; SAVEPOINT savepoint_one;&lt;br /&gt;
test=&amp;gt; -- здесь идет блок операторов, в котором произошла ошибка&lt;br /&gt;
test=&amp;gt; -- откатываемся до установленной метки,&lt;br /&gt;
test=&amp;gt; -- а не отменяем всю транзакцию&lt;br /&gt;
test=&amp;gt; ROLLBACK TO savepoint_one;&lt;br /&gt;
test=&amp;gt; -- повторяем последний блок&lt;br /&gt;
test=&amp;gt; -- завершаем транзакцию&lt;br /&gt;
test=&amp;gt; COMMIT;&lt;br /&gt;
test=&amp;gt; -- все, теперь изменения доступны всем&lt;br /&gt;
&amp;lt;/source&amp;gt;&lt;br /&gt;
&lt;br /&gt;
==== Ограничения ====&lt;br /&gt;
Целостность данных обеспечивает не только многоверсионностью&lt;br /&gt;
(MVCC) PostgreSQL, но и «архитектором» таблиц базы данных. При&lt;br /&gt;
создании таблицы (CREATE TABLE) или позже можно добавить огра-&lt;br /&gt;
ничение (CONSTRAINT) на диапазон записываемых в таблицу данных.&lt;br /&gt;
Ограничением могут быть как простые арифметические условные&lt;br /&gt;
выражения, требования уникальности (UNIQUE или PRIMARY KEY), так&lt;br /&gt;
и более сложные ограничения в виде внешних ключей (FOREIGN KEY).&lt;br /&gt;
Если какой-то столбец A является внешним ключом (FOREIGN KEY)&lt;br /&gt;
по отношению к столбцу B (REFERENCES), то это означает, что только&lt;br /&gt;
данные, представленные в столбце B, могут появиться в качестве зна-&lt;br /&gt;
чений столбца A. В случае внешних ключей PostgreSQL осуществля-&lt;br /&gt;
ет автоматический контроль ссылочной целостности4. Это довольно&lt;br /&gt;
интересный механизм, который, в частности, позволяет моделировать&lt;br /&gt;
иерархические структуры.&lt;br /&gt;
&lt;br /&gt;
==== Блокировки ====&lt;br /&gt;
Поскольку в условиях параллельного доступа к базе данных каждый&lt;br /&gt;
пользователь работает со своим мгновенным снимком (следствие&lt;br /&gt;
MVCC), а не с самой БД, то в принципе можно придумать ситуацию, ког-&lt;br /&gt;
да полученные данные «устаревают», так как они были изменены другим&lt;br /&gt;
пользователем. Если это обстоятельство важно, то PostgreSQL предо-&lt;br /&gt;
ставляет полный ассортимент блокировок. С помощью команды LOCK&lt;br /&gt;
можно заблокировать таблицу, а инструкция SELECT FOR UPDATE позво-&lt;br /&gt;
ляет заблокировать отдельные записи. Следует учитывать, что исполь-&lt;br /&gt;
зование блокировок увеличивает шанс взаимной блокировки (deadlock).&lt;br /&gt;
PostgreSQL умеет определять взаимные блокировки и разрешать их&lt;br /&gt;
путем прекращения одной из транзакций, но на это уходит время.&lt;br /&gt;
&lt;br /&gt;
=== Послесловие ===&lt;br /&gt;
Хотелось бы еще раз сказать, что «нельзя объять необъятное».&lt;br /&gt;
Единственная проблема состоит в том, что конкретно это рассматри-&lt;br /&gt;
ваемое нами «необъятное» уже «объято», поэтому за всеми подроб-&lt;br /&gt;
ностями следует обратиться к стандартной документации, а в качестве&lt;br /&gt;
бонуса рекомендую хорошую обзорную статью от Олега Бартунова:&lt;br /&gt;
«Что такое PostgreSQL?»:http://www.sai.msu.su/~Emegera/postgres/talks/what_is_PostgreSQL.html.&lt;br /&gt;
&lt;br /&gt;
----&lt;br /&gt;
&amp;lt;references /&amp;gt;&lt;/div&gt;</summary>
		<author><name>Yaleks</name></author>	</entry>

	</feed>