- PVSM.RU - https://www.pvsm.ru -
В мире баз данных существует сложная проблема рефакторинга и апгрейда хранимых процедур.
Проблема состоит в противоречии:
Большой проект традиционно состоит из множества относительно независимых друг от друга приложений, использующих одну и ту же базу данных.
Как правило, развитие проекта происходит неравномерно и итеративно: каждое новое изменение затрагивает лишь несколько составляющих проекта.
Предположим, у вас имеется хранимая процедура user.profile
, которая возвращает профиль пользователя по его идентификатору. Развивая одну из частей проекта, вы решаете, что эта функция отныне должна возвращать меньшее число параметров. Производите рефакторинг функции и кода, ее использующего. При интеграционном тестировании выясняется, что хранимая процедура user.profile
также используется в других подпроектах, а изменение привело к багам или неприятным последствиям.
Когда сроки поджимают (т. е. практически всегда), разработчик стоит на распутье:
Способы выбора пути варьируются от проекта к проекту.
Многие компании создают внутреннюю полиси (зачастую подкреплённую скриптами CI), которая требует называть хранимые процедуры по определённому правилу.
Например, указанную функцию user.profile
мы переименовываем в user.profile_0001
, где 0001
— номер её версии. Программист, которому потребовался рефакторинг этой функции, пишет новую — user.profile_0002
, а user.profile_0001
продолжает существовать в системе до тех пор, пока весь зависимый от неё код не перепишут.
Достоинства и недостатки такого подхода очевидны.
Я видел многие SQL- и не SQL-проекты, сознательно отказывающиеся от хранимых процедур («кроме тех случаев, когда совсем уж без них нельзя»).
Разрешение противоречия в пользу разработчиков.
Довольно редкий подход, но тоже встречается. Полная противоположность предыдущего случая. Разные приложения при этом не имеют общих хранимых процедур.
Многие БД имеют сессионное хранилище, но немногие предоставляют возможность хранить в нём функции/процедуры.
БД Tarantool имеет сессионное хранилище [1], позволяющее хранить в нём в том числе и функции.
Что такое сессионное хранилище? Это хранилище, которое будет полностью очищено сразу после того, как клиент отсоединится от базы данных.
Как можно использовать сессионное хранилище для решения поставленных проблем? Алгоритм приблизительно следующий:
Некоторые драйверы к Tarantool позволяют сразу после коннекта автоматически выполнять набор Lua-файлов из заданной директории.
Например, используя Perl-коннектор DR::Tnt [2], вы можете указать опцию lua_dir
.
Размещаем в директории проекта каталог lua
, в который можем положить несколько файлов. Например user.lua
из этого каталога будет выглядеть так:
function box.session.storage.user.profile(id)
local user = box.space.users:get{id}
local profile = box.space.profiles:get{id}
-- do something
return { user, profile }
end
function box.session.storage.user.add(o)
return box.space.users:insert{uuid(), o.name, o.surname }
end
function box.session.storage.user.get(id)
return box.space.users:get{id}
end
В приложении коннектимся и работаем, используя процедуры box.session.storage
:
my $tnt = tarantool
host => $host,
port => $port,
user => $user,
password => $password,
lua_dir => "lua"
;
# Создание пользователя с именем «Вася»
my $new_user = $tnt->call_lua('box.session.storage.user.add', { name => 'Вася' });
# Получение пользователя
my $user = $tnt->call_lua('box.session.storage.user.get', 123);
Относительно длинный неймспейс box.session.storage
можно сократить до минимального размера, поместив в глобальном справочнике его алиас:
_G.ss = box.session.storage
В «больших» БД, в PostgreSQL, например, существует сессионное хранилище (аналог) для данных CREATE TEMPORARY TABLE
. Было бы замечательно, если бы там появилась возможность создавать и временные функции CREATE TEMPORARY FUNCTION
, которые были бы видны только приконнектившемуся клиенту и удалялись бы после отсоединения.
Автор: linuxover
Источник [5]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/blog-kompanii-mail-ru-group/276938
Ссылки в тексте:
[1] сессионное хранилище: https://tarantool.io/en/doc/1.9/book/box/box_session.html#box-session-storage
[2] DR::Tnt: http://search.cpan.org/~unera/DR-Tnt/lib/DR/Tnt.pm
[3] Эта статья на GitHub: https://github.com/unera/session-storage-article
[4] Проект Tarantool: http://tarantool.org
[5] Источник: https://habrahabr.ru/post/352756/?utm_campaign=352756
Нажмите здесь для печати.