SELECT [DEFER] * FROM…

Я тут подумал, что было бы очень круто как помечать запросы флагом, который бы говорил СУБД «если такой же запрос уже выполняется, то меня устроят его результаты, новый запускать не надо». Было бы очень полезно для запросов, в которых не нужна оперативность и которые заказываются большим числом пользователей.

Конечно такое можно кешировать со стороны приложения (что у нас и делается в продукте), но встают вопросы инвалидации кеша, предотвращения одновременного выполнения одного и того же запроса несколько раз, если в кеше что-то не нашлось, обработки ошибок от базы и так далее.

Со стороны СУБД было бы интереснее такое увидеть.
9 комментариев
1 августа 2017 18:18

POSTQUEL

POSTQUEL — это язык запросов, который когда-то поддерживала СУБД «Постгрес». Наверняка многие задумывались почему языков программирования так много, а языков в базах данных, кроме SQL и его диалектов, не видать; SQL оказался исключительно удачным, но у него были когда-то и соперники. «Постквел» один из них.

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)
И так далее.
23 комментария
25 января 2013 21:50

Поиск пропусков в таблице

У нас тут сегодня на работе возникла гипотетическая потребность найти пропуски в конкретной таблице базы данных. Так как я кроме как с MySQL в последнее время ни с чем не имел, прикинул как бы я решил эту задачу там. Получилось что-то такое:
SELECT id FROM (
    SELECT id, id-@prev AS diff, @prev:=id
    FROM
        (SELECT @prev:=NULL) ``,
        sourceofdata
   ORDER BY id
) `` WHERE diff>1
Внутри есть напрасный запрос «SELECT @prev:=NULL», который там только затем, чтобы решение получилось в одну строку.

В общем-то, у меня вопрос. Это не очень изящно и сверху есть запрос, который перебирает всю таблицу, не знаю что там делает с ним оптимизатор, сгружает ли данные во временную или фильтрует поверх. Если рассматривать худший случай, стоимость такого запроса может быть немаленькой.

Может кто-то придумать проще? Не важно для какой СУБД.
9 комментариев
21 января 2013 21:08