SlideShare a Scribd company logo
PostgreSQL
Разработка приложений
Часть вторая.
Зачем нужны СУБД
• Унифицированный доступ к унифицированным данным из
разных систем, платформ и языков.
• LAMP, C#, Java EE…
• Единое представление разнородных данных.
• Разделение представления данных и методов доступа: единый язык
запросов (SQL)/оптимизатор.
• Средство обеспечения целостности данных.
• Внутри СУБД
• Независимо от приложений.
PostgreSQL
• Стандартные объекты СУБД (таблицы, представления, процедуры), но
не только:
• Массивы, типы
• Временные таблицы. Таблицы как переменные.
create temporary table temptable as select…
• Богатый набор встроенных индексируемых типов. (hstore, json, range)
• Функциональные индексы
• Условные индексы
• Богатый диалект SQL (CTE, LATERAL …)
• Транзакционный DDL (!)
• PL/pgSQL
• Полноценный ЯП
• Несколько СУБД-ориентированный
• Другие языки (PL/perl, PL/Java, PL/Python, PL/V8, PL/R, PL/Ruby – ну и С)
• Расширения (extensions)
SQL
• Common table expressions (с DML!)
• WINDOW functions
• User-defined aggregation functions
• MERGE нет L
• Не надо пытаться изобразить MERGE с помощью DML в CTE – не
получится.
• MODEL нет L
CTE
• with qry as(
select * from users where email like '%@gmail.com‘
)
select * from qry
• with recursive qry as(
select 1 as n
union all
select qry.n+1 from qry where n<10
)
select * from qry
Результат
n
----
1
2
3
4
5
6
7
8
9
10
(10 строк)
with recursive qry as(
select 1 as n
union all
select qry.n+1 from qry where n<10
)
select * from qry
WINDOW functions
with recursive qry as(
select 1 as n
union all
select qry.n+1 from qry where n<10
)
select *,
row_number() over(order by n desc),
sum(n) over(order by n),
n/3,
sum(n) over(partition by n/3 order by n)
from qry
order by n
Результат
n | row_number | sum | ?column? | sum
----+------------+-----+----------+-----
1 | 10 | 1 | 0 | 1
2 | 9 | 3 | 0 | 3
3 | 8 | 6 | 1 | 3
4 | 7 | 10 | 1 | 7
5 | 6 | 15 | 1 | 12
6 | 5 | 21 | 2 | 6
7 | 4 | 28 | 2 | 13
8 | 3 | 36 | 2 | 21
9 | 2 | 45 | 3 | 9
10 | 1 | 55 | 3 | 19
select *,
row_number() over(order by n desc),
sum(n) over(order by n),
n/3,
sum(n) over(partition by n/3 order by n)
from qry
order by n
Массивы и типы
• create table atable(
id int,
vals text[]
)
• create type auser as(
name text,
email text
)
• declare var auser;
var.name:=’Vasya’;
• Другие типы – enum, range, базовый
Временные таблицы
• Временные таблицы как глобальные табличные переменные.
• create or replace function fun1() returns void as
$code$
begin
create temporary table if not exists t(id int) on commit drop;
end; $code$
language plpgsql;
explain analyze
select count(fun1()) from generate_series(1,1000);
"Aggregate (cost=262.50..262.51 rows=1 width=0) (actual time=5.511..5.512 rows=1 loops=1)“
insert into t select n from generate_series(1,1000) as gs(n);
"Aggregate (cost=262.50..262.51 rows=1 width=0) (actual time=702.723..702.723 rows=1
loops=1)"
Отдельная
транзакция
Ограничения (constraints)
• Являются ЧРЕЗВЫЙЧАЙНО критичной частью и единственным
критерием оценки верности введенных данных.
• Пример: проверка валидности телефона произвоится в приложении,
загрузка данных с неверным телефоном – в итоге невозможно из
приложения изменить, скажем, фамилию (телефон не редактируется), а
то и показать данные.
• Все стандартные (NOT NULL, PRIMARY KEY, UNIQUE, CHECK,
FOREIGN KEY с каскадированием)
• EXCLUDE – более общая версия уникальности (можно, например,
запретить пересекающиеся интервалы)
• DEFERRABLE/NOT DEFERRABLE
Триггеры
• Триггерные функции и почему это хорошо
• Одна функция для нескольких триггеров.
• Более удачная модель, чем в некоторых других СУБД – исключение в
триггере откатывает всю транзакцию.
• FOR EACH ROW/STATEMENT
• CONSTRAINT TRIGGER может быть DEFERRABLE/NOT DEFERRABLE
• Несколько триггеров – вызываются в алфавитном порядке.
• Не надо опасаться триггеров – они нередко незаменимы для
контроля целостности
Event triggers
• Триггеры на CREATE/ALTER/DROP
• CREATE EVENT TRIGGER name
ON event
[ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ]
EXECUTE PROCEDURE function_name()
• Транзакционный DDL позволяет делать интересные вещи.
• Пока только в будущем – мало чего доступно, если писать на PL/
pgSQL.
Представления
• Все как обычно, можно UNION
• Обновляемые VIEW
• INSTEAD OF триггеры – вызываются при попытке использовать
DML со VIEW
hstore, json, range
• hstore – плоский key->value
• JSON – JSON он и есть JSON
• Range types (int4range, int8range, numrange, tsrange, tstzrange,
daterange)
• Индексы
• create index ”tbl[fn(col)]” on tbl(fn(col))
• create index ”tbl[fn(col->’key’)]” on tbl(fn(col))
• create index ”tbl[fn(col)]” on tbl(fn(col)) where age>18
Схемы
• create schema ”schema_name”
• Таблицы
• Представления
• Функции
• и т.д.
• search_path
• Да, нет пакетов. Зато в пакетах нет таблиц.
• А по-хорошему было бы неплохо иметь и то, и другое.
• Схема как логическая единица.
• Extensions в схемах
• create extension with schema <schema_name>
PL/PgSQL
• Описываются функции. Тело функции задается строкой.
CREATE [ OR REPLACE ] FUNCTION
name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = }
default_expr ] [, ...] ] )
[ RETURNS rettype
| RETURNS TABLE ( column_name column_type [, ...] ) ]
{ LANGUAGE lang_name
| WINDOW
| IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF
| CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT
| [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER
| COST execution_cost
| ROWS result_rows
| SET configuration_parameter { TO value | = value | FROM CURRENT }
| AS 'definition‘
| AS 'obj_file', 'link_symbol‘
} ...
[ WITH ( attribute [, ...] ) ]
PL/pgSQL
• Параметры
• Просто параметры
• create or replace function([IN] email text);
• Значения по умолчанию
• create or replace function([IN] email text default ‘root@localhost’);
• Переменный список
• Вызов
• select func(p1,p2,p3) [ INTO var1, var2,… ];
• perform func(p1,p2,p3);
• perform/select func(par1:=p1, par2:=p2, par3:=p3);
• perform/select func(par1:=p1, variadic array[1,2,3]);
PL/pgSQL
• Возвращаемые значения
• Скалярные типы (в т.ч. и hstore или json)
• Массивы
• Таблицы
• INOUT и OUT или TABLE(…)
• Create or replace function returnstable()
returns table(col1 text, col2 int) as
$code$
…
col1:=“text”; col2:=100;
return next;
return query select “text”, 200;
return query execute $Q$select '---'::text, 0::int$Q$;
Атрибуты функции
• IMMUTABLE
• Не модифицирует данные и всегда возвращает один и тот же результат для тех же
самых данных
• STABLE
• Не модифицирует данные и в течении одного сканирования таблицы ведет себя как
IMMUTABLE
• VOLATILE
• Ничего из перечисленного
• Надо внимательно смотреть, может негативно повлиять на
производительность.
• SECURITY INVOKER
• Выполняется с правами вызывающего пользователя
• SECURITY DEFINER
• С правами создателя
• И т.д.
Управляющие структуры
• Ничего необычного или странного
• IF-ELSE-END IF, CASE-END CASE, LOOP – END LOOP и т.п.
• SELECT INTO/PERFORM
Исключения
• <<code>>
declare
begin
. . .
raise exception sqlstate ‘XX001’;
. . .
exception
when division_by_zero . . .
when sqlstate ’XX000’ . . .
else
end;
CREATE OR REPLACE FUNCTION www.ext_admin_models(q hstore)
RETURNS refcursor AS
$BODY$
/* begin; select www.ext_models('') */
declare rv refcursor;
models refcursor;
ids integer[];
page integer:=coalesce((q->'pg')::integer,1);
begin
select array_agg(m.id order by m.name)
into ids
from fd2.producer_model m;
open models for
select m.id as model_id, p.name as producer_name_hidden,
m.price, m.name as model_name,
(select v.descr2
from fd2.v_disks v
where v.model_id=m.id limit 1) as description
from fd2.producer_model m, fd2.producer as p
where m.producer_id=p.id
and m.id=any(ids[(page-1)*SCREEN_PAGE_SIZE()+1:(page)*SCREEN_PAGE_SIZE()])
order by m.name;
open rv for select 'ok'::text as status, models as models,
array_length(ids,1) as total;
return rv;
end;$BODY$
LANGUAGE plpgsql VOLATILE COST 100;
Курсоры
Собираем массив id
$$ - нотация
$$, $BODY$, $Q$ и т.д.
PL/pgSQL и транзакции
• Невозможно управлять транзакциями
• И это правильно!
• Транзакции инициируются клиентом СУБД
• Если транзакция не начата, каждый вызов функции
оборачивается в транзакцию, иначе все выполняется в контексте
одной транзакции.
SAVEPOINT
• SAVEPOINT <savepoint name>
• ROLLBACK TO SAVEPOINT
• Из PL/pgSQL нельзя как ни начать, ни завершить транзакцию, так
и ни установить savepoint, ни откатиться к какому-либо.
• При возникновении исключения в блоке при наличии
обработчика осуществятся откат к неявно установленному при
входе в блок savepoint’у.
do $code$
begin
insert into t values(1);
raise notice '1:%', (select count(*) from t);
begin
insert into t values(1);
raise notice '2:%', (select count(*) from t);
raise exception sqlstate 'ZQ001';
exception
when sqlstate 'ZQ000' then
raise notice '3:%', (select count(*) from t);
end;
raise notice '4:%', (select count(*)from t);
end;
$code$
1:1
1:2
3:1
4:1
Уровни изоляции
• READ UNCOMMITED – отсутствует
• READ COMMITED
• REPEATABLE READ
• SERIALIZABLE
• Можно получить ошибку serialization_failure
• DEFERRABLE READ ONLY – отчеты, бекапы и т.д.
Расширения
• Достаточно большое количество стандартных расширений
(42 шт.)
• Не установлены по умолчанию.
• dblink
• earthdistance & PostGIS
• pg_trgm
• pgcrypto

More Related Content

PDF
Лекция #5. Введение в язык программирования Python 3
PPTX
Javascript 1
PDF
Олег Бартунов, Федор Сигаев, Александр Коротков (PostgreSQL)
KEY
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
PPT
Толстая модель. История разработки ORM
PPT
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
PDF
Лекция 2. Всё, что вы хотели знать о функциях в Python.
PDF
Decorators' recipes
Лекция #5. Введение в язык программирования Python 3
Javascript 1
Олег Бартунов, Федор Сигаев, Александр Коротков (PostgreSQL)
Курсы по мобильной разработке. 1 лекция. Знакомство с iOS
Толстая модель. История разработки ORM
ZFConf 2011: Толстая модель: История разработки собственного ORM (Михаил Шамин)
Лекция 2. Всё, что вы хотели знать о функциях в Python.
Decorators' recipes

What's hot (20)

PDF
Лекция 4. Строки, байты, файлы и ввод/вывод.
PDF
Лекция 3. Декораторы и модуль functools.
PPT
Web весна 2013 лекция 9
PDF
Лекция 12. Быстрее, Python, ещё быстрее.
PDF
Лекция 10. Классы 2.
PDF
Влад Ковташ — Yap Database
PDF
Лекция 9. Модули, пакеты и система импорта.
PPTX
C#. От основ к эффективному коду
PDF
Красота и изящность стандартной библиотеки Python
PDF
Систематизация экспрешнов в IE
PDF
Лекция 11. Тестирование.
PDF
SQL Tricky (Иван Фролков)
PDF
Haskell
PDF
Лекция 5. Встроенные коллекции и модуль collections.
PPT
Javascript
PDF
Лекция 13. Многопоточность и GIL
PDF
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
PDF
Groovy presentation.
PDF
Лекция 1. Начало.
PPTX
Clojure: Lisp for the modern world (русская версия)
Лекция 4. Строки, байты, файлы и ввод/вывод.
Лекция 3. Декораторы и модуль functools.
Web весна 2013 лекция 9
Лекция 12. Быстрее, Python, ещё быстрее.
Лекция 10. Классы 2.
Влад Ковташ — Yap Database
Лекция 9. Модули, пакеты и система импорта.
C#. От основ к эффективному коду
Красота и изящность стандартной библиотеки Python
Систематизация экспрешнов в IE
Лекция 11. Тестирование.
SQL Tricky (Иван Фролков)
Haskell
Лекция 5. Встроенные коллекции и модуль collections.
Javascript
Лекция 13. Многопоточность и GIL
Школа-студия разработки приложений для iOS. Лекция 1. Objective-C
Groovy presentation.
Лекция 1. Начало.
Clojure: Lisp for the modern world (русская версия)
Ad

Viewers also liked (9)

PDF
Typical Telugu Jokes
PPTX
Facebookrajesh
PDF
2015 drill-head vs piercing-plier
PPTX
Widget's Parts of a Computer
PPTX
All about france
PDF
Cmrw technical
PPTX
Статистика обращений предпринимателей за Июнь
PPTX
Parts of circle secant tangent
PPTX
Cтатистика обращений предпринимателей
Typical Telugu Jokes
Facebookrajesh
2015 drill-head vs piercing-plier
Widget's Parts of a Computer
All about france
Cmrw technical
Статистика обращений предпринимателей за Июнь
Parts of circle secant tangent
Cтатистика обращений предпринимателей
Ad

Similar to PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2, Иван Фролков (20)

PPTX
Расширение библиотеки Slick
PDF
Иван Фролков. Tricky SQL
ODP
Использование хранимых процедур в MySQL (Константин Осипов)
PDF
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
PDF
Hacking PostgreSQL. Обзор исходного кода
PPTX
разработка бизнес приложений (8)
PPTX
Зачем нужна Scala?
PDF
C++ осень 2012 лекция 9
PDF
GAE - плюсы/минусы/подводные камни
PDF
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
PDF
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
PDF
Народные средства оптимизации PostgreSQL
PPTX
Взломать Web-сайт на ASP.NET? Сложно, но можно!
PDF
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
KEY
Sequel — механизм доступа к БД, написанный на Ruby
PPT
лабраб 7
PDF
Web осень 2013 лекция 6
PPTX
особенности программирования на с++
PPTX
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
PPTX
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков
Расширение библиотеки Slick
Иван Фролков. Tricky SQL
Использование хранимых процедур в MySQL (Константин Осипов)
Расширяемость PostgreSQL для хакеров и архитекторов / Олег Бартунов, Александ...
Hacking PostgreSQL. Обзор исходного кода
разработка бизнес приложений (8)
Зачем нужна Scala?
C++ осень 2012 лекция 9
GAE - плюсы/минусы/подводные камни
Функциональное программирование с использованием библиотеки fp-ts | Odessa Fr...
Хранение данных в iPhone. (FMDB, SQL-Persistence, CoreData)
Народные средства оптимизации PostgreSQL
Взломать Web-сайт на ASP.NET? Сложно, но можно!
Time series data in a relational database. TimescaleDB and PipelineDB extensi...
Sequel — механизм доступа к БД, написанный на Ruby
лабраб 7
Web осень 2013 лекция 6
особенности программирования на с++
"AnnotatedSQL - провайдер с плюшками за 5 минут" - Геннадий Дубина, Senior So...
Никита Глушков, К вопросу о реализации кроссплатформенных фреймворков

More from pgdayrussia (12)

PDF
PG Day'14 Russia, Secure PostgreSQL Deployment, Magnus Hagander
PDF
PG Day'14 Russia, Работа со слабо-структурированными данными в PostgreSQL, Ол...
PDF
PG Day'14 Russia, Социальная сеть, которая просто работает, Владислав Коваль
PDF
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
PDF
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PDF
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 1...
PDF
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PDF
PG Day'14 Russia, PostgreSQL: архитектура, настройка и оптимизация, Илья Косм...
PDF
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PDF
PG Day'14 Russia, GIN — Stronger than ever in 9.4 and further, Александр Коро...
PDF
PG Day'14 Russia, Нетрадиционный PostgreSQL: хранение бинарных данных в БД, А...
PDF
PG Day'14 Russia, Модуль anyarray, Федор Сигаев
PG Day'14 Russia, Secure PostgreSQL Deployment, Magnus Hagander
PG Day'14 Russia, Работа со слабо-структурированными данными в PostgreSQL, Ол...
PG Day'14 Russia, Социальная сеть, которая просто работает, Владислав Коваль
PG Day'14 Russia, PostgreSQL в avito.ru, Михаил Тюрин
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 3...
PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 1...
PG Day'14 Russia, PostgreSQL System Architecture, Heikki Linnakangas
PG Day'14 Russia, PostgreSQL: архитектура, настройка и оптимизация, Илья Косм...
PG Day'14 Russia, Индексный поиск по регулярным выражениям, Александр Коротков
PG Day'14 Russia, GIN — Stronger than ever in 9.4 and further, Александр Коро...
PG Day'14 Russia, Нетрадиционный PostgreSQL: хранение бинарных данных в БД, А...
PG Day'14 Russia, Модуль anyarray, Федор Сигаев

PG Day'14 Russia, PostgreSQL как платформа для разработки приложений, часть 2, Иван Фролков

  • 2. Зачем нужны СУБД • Унифицированный доступ к унифицированным данным из разных систем, платформ и языков. • LAMP, C#, Java EE… • Единое представление разнородных данных. • Разделение представления данных и методов доступа: единый язык запросов (SQL)/оптимизатор. • Средство обеспечения целостности данных. • Внутри СУБД • Независимо от приложений.
  • 3. PostgreSQL • Стандартные объекты СУБД (таблицы, представления, процедуры), но не только: • Массивы, типы • Временные таблицы. Таблицы как переменные. create temporary table temptable as select… • Богатый набор встроенных индексируемых типов. (hstore, json, range) • Функциональные индексы • Условные индексы • Богатый диалект SQL (CTE, LATERAL …) • Транзакционный DDL (!) • PL/pgSQL • Полноценный ЯП • Несколько СУБД-ориентированный • Другие языки (PL/perl, PL/Java, PL/Python, PL/V8, PL/R, PL/Ruby – ну и С) • Расширения (extensions)
  • 4. SQL • Common table expressions (с DML!) • WINDOW functions • User-defined aggregation functions • MERGE нет L • Не надо пытаться изобразить MERGE с помощью DML в CTE – не получится. • MODEL нет L
  • 5. CTE • with qry as( select * from users where email like '%@gmail.com‘ ) select * from qry • with recursive qry as( select 1 as n union all select qry.n+1 from qry where n<10 ) select * from qry
  • 6. Результат n ---- 1 2 3 4 5 6 7 8 9 10 (10 строк) with recursive qry as( select 1 as n union all select qry.n+1 from qry where n<10 ) select * from qry
  • 7. WINDOW functions with recursive qry as( select 1 as n union all select qry.n+1 from qry where n<10 ) select *, row_number() over(order by n desc), sum(n) over(order by n), n/3, sum(n) over(partition by n/3 order by n) from qry order by n
  • 8. Результат n | row_number | sum | ?column? | sum ----+------------+-----+----------+----- 1 | 10 | 1 | 0 | 1 2 | 9 | 3 | 0 | 3 3 | 8 | 6 | 1 | 3 4 | 7 | 10 | 1 | 7 5 | 6 | 15 | 1 | 12 6 | 5 | 21 | 2 | 6 7 | 4 | 28 | 2 | 13 8 | 3 | 36 | 2 | 21 9 | 2 | 45 | 3 | 9 10 | 1 | 55 | 3 | 19 select *, row_number() over(order by n desc), sum(n) over(order by n), n/3, sum(n) over(partition by n/3 order by n) from qry order by n
  • 9. Массивы и типы • create table atable( id int, vals text[] ) • create type auser as( name text, email text ) • declare var auser; var.name:=’Vasya’; • Другие типы – enum, range, базовый
  • 10. Временные таблицы • Временные таблицы как глобальные табличные переменные. • create or replace function fun1() returns void as $code$ begin create temporary table if not exists t(id int) on commit drop; end; $code$ language plpgsql; explain analyze select count(fun1()) from generate_series(1,1000); "Aggregate (cost=262.50..262.51 rows=1 width=0) (actual time=5.511..5.512 rows=1 loops=1)“ insert into t select n from generate_series(1,1000) as gs(n); "Aggregate (cost=262.50..262.51 rows=1 width=0) (actual time=702.723..702.723 rows=1 loops=1)" Отдельная транзакция
  • 11. Ограничения (constraints) • Являются ЧРЕЗВЫЙЧАЙНО критичной частью и единственным критерием оценки верности введенных данных. • Пример: проверка валидности телефона произвоится в приложении, загрузка данных с неверным телефоном – в итоге невозможно из приложения изменить, скажем, фамилию (телефон не редактируется), а то и показать данные. • Все стандартные (NOT NULL, PRIMARY KEY, UNIQUE, CHECK, FOREIGN KEY с каскадированием) • EXCLUDE – более общая версия уникальности (можно, например, запретить пересекающиеся интервалы) • DEFERRABLE/NOT DEFERRABLE
  • 12. Триггеры • Триггерные функции и почему это хорошо • Одна функция для нескольких триггеров. • Более удачная модель, чем в некоторых других СУБД – исключение в триггере откатывает всю транзакцию. • FOR EACH ROW/STATEMENT • CONSTRAINT TRIGGER может быть DEFERRABLE/NOT DEFERRABLE • Несколько триггеров – вызываются в алфавитном порядке. • Не надо опасаться триггеров – они нередко незаменимы для контроля целостности
  • 13. Event triggers • Триггеры на CREATE/ALTER/DROP • CREATE EVENT TRIGGER name ON event [ WHEN filter_variable IN (filter_value [, ... ]) [ AND ... ] ] EXECUTE PROCEDURE function_name() • Транзакционный DDL позволяет делать интересные вещи. • Пока только в будущем – мало чего доступно, если писать на PL/ pgSQL.
  • 14. Представления • Все как обычно, можно UNION • Обновляемые VIEW • INSTEAD OF триггеры – вызываются при попытке использовать DML со VIEW
  • 15. hstore, json, range • hstore – плоский key->value • JSON – JSON он и есть JSON • Range types (int4range, int8range, numrange, tsrange, tstzrange, daterange) • Индексы • create index ”tbl[fn(col)]” on tbl(fn(col)) • create index ”tbl[fn(col->’key’)]” on tbl(fn(col)) • create index ”tbl[fn(col)]” on tbl(fn(col)) where age>18
  • 16. Схемы • create schema ”schema_name” • Таблицы • Представления • Функции • и т.д. • search_path • Да, нет пакетов. Зато в пакетах нет таблиц. • А по-хорошему было бы неплохо иметь и то, и другое. • Схема как логическая единица. • Extensions в схемах • create extension with schema <schema_name>
  • 17. PL/PgSQL • Описываются функции. Тело функции задается строкой. CREATE [ OR REPLACE ] FUNCTION name ( [ [ argmode ] [ argname ] argtype [ { DEFAULT | = } default_expr ] [, ...] ] ) [ RETURNS rettype | RETURNS TABLE ( column_name column_type [, ...] ) ] { LANGUAGE lang_name | WINDOW | IMMUTABLE | STABLE | VOLATILE | [ NOT ] LEAKPROOF | CALLED ON NULL INPUT | RETURNS NULL ON NULL INPUT | STRICT | [ EXTERNAL ] SECURITY INVOKER | [ EXTERNAL ] SECURITY DEFINER | COST execution_cost | ROWS result_rows | SET configuration_parameter { TO value | = value | FROM CURRENT } | AS 'definition‘ | AS 'obj_file', 'link_symbol‘ } ... [ WITH ( attribute [, ...] ) ]
  • 18. PL/pgSQL • Параметры • Просто параметры • create or replace function([IN] email text); • Значения по умолчанию • create or replace function([IN] email text default ‘root@localhost’); • Переменный список • Вызов • select func(p1,p2,p3) [ INTO var1, var2,… ]; • perform func(p1,p2,p3); • perform/select func(par1:=p1, par2:=p2, par3:=p3); • perform/select func(par1:=p1, variadic array[1,2,3]);
  • 19. PL/pgSQL • Возвращаемые значения • Скалярные типы (в т.ч. и hstore или json) • Массивы • Таблицы • INOUT и OUT или TABLE(…) • Create or replace function returnstable() returns table(col1 text, col2 int) as $code$ … col1:=“text”; col2:=100; return next; return query select “text”, 200; return query execute $Q$select '---'::text, 0::int$Q$;
  • 20. Атрибуты функции • IMMUTABLE • Не модифицирует данные и всегда возвращает один и тот же результат для тех же самых данных • STABLE • Не модифицирует данные и в течении одного сканирования таблицы ведет себя как IMMUTABLE • VOLATILE • Ничего из перечисленного • Надо внимательно смотреть, может негативно повлиять на производительность. • SECURITY INVOKER • Выполняется с правами вызывающего пользователя • SECURITY DEFINER • С правами создателя • И т.д.
  • 21. Управляющие структуры • Ничего необычного или странного • IF-ELSE-END IF, CASE-END CASE, LOOP – END LOOP и т.п. • SELECT INTO/PERFORM
  • 22. Исключения • <<code>> declare begin . . . raise exception sqlstate ‘XX001’; . . . exception when division_by_zero . . . when sqlstate ’XX000’ . . . else end;
  • 23. CREATE OR REPLACE FUNCTION www.ext_admin_models(q hstore) RETURNS refcursor AS $BODY$ /* begin; select www.ext_models('') */ declare rv refcursor; models refcursor; ids integer[]; page integer:=coalesce((q->'pg')::integer,1); begin select array_agg(m.id order by m.name) into ids from fd2.producer_model m; open models for select m.id as model_id, p.name as producer_name_hidden, m.price, m.name as model_name, (select v.descr2 from fd2.v_disks v where v.model_id=m.id limit 1) as description from fd2.producer_model m, fd2.producer as p where m.producer_id=p.id and m.id=any(ids[(page-1)*SCREEN_PAGE_SIZE()+1:(page)*SCREEN_PAGE_SIZE()]) order by m.name; open rv for select 'ok'::text as status, models as models, array_length(ids,1) as total; return rv; end;$BODY$ LANGUAGE plpgsql VOLATILE COST 100; Курсоры Собираем массив id $$ - нотация $$, $BODY$, $Q$ и т.д.
  • 24. PL/pgSQL и транзакции • Невозможно управлять транзакциями • И это правильно! • Транзакции инициируются клиентом СУБД • Если транзакция не начата, каждый вызов функции оборачивается в транзакцию, иначе все выполняется в контексте одной транзакции.
  • 25. SAVEPOINT • SAVEPOINT <savepoint name> • ROLLBACK TO SAVEPOINT • Из PL/pgSQL нельзя как ни начать, ни завершить транзакцию, так и ни установить savepoint, ни откатиться к какому-либо. • При возникновении исключения в блоке при наличии обработчика осуществятся откат к неявно установленному при входе в блок savepoint’у.
  • 26. do $code$ begin insert into t values(1); raise notice '1:%', (select count(*) from t); begin insert into t values(1); raise notice '2:%', (select count(*) from t); raise exception sqlstate 'ZQ001'; exception when sqlstate 'ZQ000' then raise notice '3:%', (select count(*) from t); end; raise notice '4:%', (select count(*)from t); end; $code$ 1:1 1:2 3:1 4:1
  • 27. Уровни изоляции • READ UNCOMMITED – отсутствует • READ COMMITED • REPEATABLE READ • SERIALIZABLE • Можно получить ошибку serialization_failure • DEFERRABLE READ ONLY – отчеты, бекапы и т.д.
  • 28. Расширения • Достаточно большое количество стандартных расширений (42 шт.) • Не установлены по умолчанию. • dblink • earthdistance & PostGIS • pg_trgm • pgcrypto