постгрес
Upsert в PostgreSQL
Ура, появился коммит, добавляющий к оператору INSERT «Постгреса» конструкцию, которая позволяет использовать его как upsert (в «Оракле» это конструкция MERGE, в «Майэскуэеле» — INSERT… ON DUPLICATE KEY UPDATE):
-- Обновить, если не удалась вставка
INSERT INTO distributors AS d (did, dname) VALUES (8, 'Anvil Distribution')
ON CONFLICT (did) DO UPDATE
SET dname = EXCLUDED.dname || ' (formerly ' || d.dname || ')'
WHERE d.zipcode != '21201';
-- Если не удалась вставка, ничего не делать
INSERT INTO distributors (did, dname) VALUES (10, 'Conrad International')
ON CONFLICT (did) WHERE is_active DO NOTHING;PostgreSQL: сортировка без учёта регистра
Мы переводим свои некоторые продукты с «Оракла» на «Постргрес» и постоянно сталкиваемся
test=# SELECT * FROM (SELECT 'Ба' UNION ALL SELECT 'бб' UNION ALL SELECT 'Бв') _ ORDER BY 1;
?column?
----------
Ба
бб
Бв
(3 строки)Ни в одном описании опыта такого же перехода я
test=# SELECT * FROM (SELECT 'Ба' AS str UNION ALL SELECT 'бб' UNION ALL SELECT 'Бв') _ ORDER BY str COLLATE "C";
str
-----
Ба
Бв
бб
(3 строки)Либо преобразовать строку к бинарному типу:
test=# SELECT * FROM (SELECT 'Ба' AS str UNION ALL SELECT 'бб' UNION ALL SELECT 'Бв') _ ORDER BY str::bytea;
str
-----
Ба
Бв
бб
(3 строки)Правда в последнем случае неясно сможет ли «Постгрес» использовать индекс — мы пока таких испытаний не проводили.
POSTQUEL
POSTQUEL — это язык запросов, который
POSTQUEL расшифровывается как «POSTgres QUEry Language», «язык запросов Постгреса», он был разработам в 1985 году в Калифорнийском университете в Беркли под руководством Майкла Стоунбрейкера, POSTQUEL основан на языке запросов QUEL, который использовался на тот момент в БД «Ингрес».
Примеры того на что был похож POSTQUEL есть в польской Википедии:
Получить размер заработной платы сотрудника Ковальски (pracownicy — сотрудники, płace — зарплата):
retrieve (PRACOWNICY.placa) from PRACOWNICY where PRACOWNICY.nazwisko = "Kowalski"Все сотрудники старше 40 лет (wiek — возраст, nazwisko — имя):
retrieve (P.nazwisko) from P in PRACOWNICY where P.wiek > 40Найти все департаменты, целиком занимающие один этаж (pietro — этаж, dnazwa — сокращение от «название департамента»):
retrieve (DEPART.dnazwa)
where DEPART.pietro NOT-IN {D.pietro from D in DEPART where D.dnazwa != DEPART.dnazwa}«Постквел» был более формализованным языком, чем Эскюэль, все команды строились по одному образцу и не допускали вариаций. Других подробностей я не нашёл, к сожалению, детального описания языка мне обнаружить пока не удалось, было бы любопытно посмотреть на него и проанализировать сильные стороны.
Добавлено позднее. Я обнаружил документацию 1992 года на «Постгрес», где довольно подробно упоминается и «Постквел» (ссылка есть в комментариях). Интересный
Например, оперировал он объектами, поддерживал наследование (все примеры из упомянутой документации):
create STUD_EMP (location = point) inherits (EMP)Поддерживал массивы (индексы начинаются с единицы):
create SAL_EMP (name = char[], pay_by_quarter = int4[4])
append SAL_EMP (name = "bill", pay_by_quarter="{10000, 10000, 10000, 10000}")
retrieve (SAL_EMP.name) where SAL_EMP.pay_by_quarter[1] !=SAL_EMP.pay_by_quarter[2]Поддерживал историю, вот, например, срез данных с первого января 1970 по наши дни:
retrieve (E.salary)
from E in EMP["Jan 1 00:00:00 1970 GMT", "now"]
where E.name = "Sam"Была возможность создавать пользовательские типы (тут создаётся новый тип массива):
define type int_array
(element = int4, internallength = variable,
input = array_in, output = array_out)Так же как и пользовательские функции:
define function eq_area_circle
(language = "c", returntype = bool)
arg is (circle, circle)
as "/usr/postgres/tutorial/circle.o"
define function manager
(language = "postquel", returntype = EMP)
arg is (EMP)
as "retrieve (E.all) from E in EMP
where E.name = DEPT.manager
and DEPT.name = $1.dept"
retrieve (EMP.name)
where name(manager(EMP)) = "Joe"Была даже перегрузка операторов!
define operator =
(arg1 = circle, arg2 = circle,
procedure = eq_area_circle)И так далее.
Базы данных. Наведем порядок
Устав бороться со своей и чужой ленью, я решил принять
Естественно, что файл предназначен для описания достаточно небольших баз данных (менее 7—10 таблиц). В этом случае больших баз без хорошо составленной наглядной документации все равно не обойтись. Не надейтесь. :)
Четкий формат представления имеют пока только таблицы, в силу того, что остальными объектами приходится пользоваться достаточно редко, да и синтаксис их описания различается для разных СУБД, но, возможно, в следующих версиях формата появятся правила и их описания тоже.
Вот пример описания двух таблиц, связанных между собой
[/usr/local/pgsql/bin/psql eshop]
items / товары
-----------------------
id serial / идентификатор
gid int4 / категория товара -> group.id
name text / наименование
price real / цена
comment text / описание товара
CREATE INDEX items_price_idx ON items (price)
group / категории
-----------------------
id serial / идентификатор -> items.gid
parent int4 / родитель в дереве. -1, если верхний уровень -> id
name text / наименованиеДумаю из примера и так все понятно, но я
Строчка, заключенная в квадратные скобки, — команда, принимающая данные. Пустые строки и строки, начинающиеся с двух минусов игнорируются. В абзаце, где описывается таблица, первым идет ее имя, ниже — описания ее полей: наименования, через табуляцию тип. В конце каждой значимой строки через пробел и слеш находится ее краткое описание.
Инструкции заведения секвенсоров, представлений и хранимых процедур записываются в одну строку.
Так как формат файла представлений достаточно легко может быть разобран и преобразован в команды мониторов mSQL, PostgreSQL и MySQL я, пару дней назад, выбрав время, написал небольшую программку на Перле. Правда толком ее еще не обкатал, но не думаю, что с ее эксплуатацией возникнут
Интепретатор файлов таблиц: intp.pl
#!/usr/bin/perl
sub StripComment
{
my ($line) = @_;
unless ($line=~s{^([^/]*)\s+/.+}{$1}o)
{
print "Предупреждение: не указан комментарий [ $line ].\n"
unless ($line=~/^CREATE/o);
};
return $line;
};
sub AddData
{
my ($table, @query) = @_;
my $query = join ',', @query;
my $result = '';
if ($todrop)
{
for (@query)
{
if (/([^ ]+) serial$/)
{
$result.= "DROP SEQUENCE ${table}_${1}_seq\\g\n";
last;
};
};
$result.= "DROP TABLE $table\\g\n";
};
$result.= "CREATE TABLE $table ($query)\\g\n";
return $result."\n";
};
sub AddDrop
{
my $table = $_[0];
if ($todrop && $table=~/^CREATE ([^ ]+ +[^ ]+)/o)
{
return "DROP $1\\g\n$table\\g\n";
} else
{
return "$table\\g\n";
};
};
unless (open F, (shift or '.tables'))
{
print <DATA>;
die "\n"
};
@query = ();
$table = '';
$result = '';
$comm = '';
$todrop = shift or 0;
while (<F>)
{
chomp;
next if ($_ eq '' || /^\-\-/);
if (/^\[(.+?)\]$/)
{
$comm = $1;
next;
};
@data = split (/ +/,StripComment $_);
if (@data < 2)
{
$result.= @query?AddData($table, @query):AddDrop ($table)
if ($table ne '');
$table = $data[0];
@query = ();
} else
{
push @query, "$data[0] $data[1]";
};
};
close F;
$result.= AddData ($table, @query) if (@query);
if ($result ne '')
{
if ($comm ne '')
{
open F, "|$comm";
print F "$result\\q";
close F;
} else
{
print "Ошибка: не указана команда для приема данных.";
};
} else
{
print "Ошибка: файл для обработки пуст.";
};
__END__
Интерпретатор файлов таблиц для СУБД.
Написал Евгений Степанищев (2000 год).
Использование: inpt.pl имя_файла [DROP]
DROP - предварительно сделать DROP для таблиц и SEQUENCE
Формат:
-- БД stat комментарий
tablename / описание имя таблицы
--------------------- оформительский элемент
поле1 тип / описание поля таблицы,
поле2 тип / описание описание интепретатор игнорирует
и т.д.
[/usr/local/mysql/bin/mysql stat] комманда, принимающая данныеP.S. Если
P.P.S. Вышеописанное ни в коем случае не претендует на панацею и всеобъемлющий инструмент, а всего лишь на роль мелочи, которая поможет избежать некоторых возможных трудностей.
Софт. FAR 1.70b2, MySQL, PostgreSQL…
Новость дня — вышел FAR 1.70b2 build 321. С некоторый пор этот, один из лучших (скажу лучший — заклюют :) файловых менеджеров, разрабатывается не одним человеком, а группой разработчиков (FAR Team). С этих же самых пор список WhatsNew каждой новой версии поражает своим размером. Вот и на этот раз, я насчитал 64 пункта! Приставки Beta бояться не нужно, FAR Team обещает выпустить release только в случае полного отсутствия багов. То есть никогда :). Так что — качать!
Продолжая тему FARa.
Смешно, но факт — я знаю людей, которые пользуются FARом, начиная чуть ли не с первой версии и не знают о существовании такий вещи, как плагины. На всякий случай, сообщу. Сам FAR — это еще не все. К нему существуют «довески», называемые плагинами, которые сильно расширяют его функциональность. Например, есть плагины для чтения почты, работы с FTP через Proxy-сервер, проигрывания музыкальных файлов (точнее управления WinAMP’ом) и многого другого. Плагины можно взять на сайте PlugRing, ссылка на который есть в конце статьи (см. «ссылки по теме»).
Из других новостей мира вареза — появление MySQL
Так что, если будете выбирать СУБД для Веба… вы знаете, что я бы посоветовал.