Обращение в несколько баз данных в одном запросе
Префикс
Один запрос может обращаться в несколько баз данных одновременно,
если расположение объекта указано с помощью префикса,
который располагается перед именем объекта через двоеточие.
Префикс может быть
Как следствие появляется новый вид системной информации -
поле, ссылающееся с помощью внешнего ключа на другое поле,
в действительности содержит два значения:
- обычное значение, присвоенное полю пользователем
select FieldFK, ...
insert into ... values (FieldFK, ...)
- системное значение, которое содержит идентификатор внешней базы данных
(если запись, на которую поле ссылается, находится во внешней базе данных)
и на которое можно сослаться, если после имени поля, содержащего обычное значение,
написать "#sys":
select FieldFK#sys, ...
insert into ... values (FieldFK#sys, ...)
И как следствие при создании или изменении таблицы
мы можем дать возможность внешнему ключу ссылаться во внешнюю базу данных,
или не дать (отнять такую возможность) -
это делается созданием (добавлением) или несозданием (удалением) поля,
имя которого заканчивается на "#sys":
create/alter table ... (
...
FieldFK num3,
FieldFK#sys num2,
...
)
Также как следствие можно создавать хранимые процедуры,
которые, будучи запущенными не автором,
будут выполняться в удаленной базе данных:
- под логином пользователя, запустившего процедуру
- под логином автора процедуры
create sticky procedure ...
Системная таблица прозвищ
Для выполнения хранимых процедур и таймеров
каждая база данных в системной таблице 'sys-nicknames'
хранит все прозвища, известные ее пользователям
(некоторые из прозвищ могут именовать базу данных,
в которой само перечисление прозвищ находится).
sys-nicknames
IdUser |
al |
an |
username |
password |
IdDb |
nickname |
datatime |
101 |
database.remote.com |
|
Smith |
pwds |
31 |
db1 |
|
101 |
|
123.123.123.123 |
|
|
33 |
db2 |
|
105 |
data.storage.com |
234.234.234.234 |
Tomson |
|
34 |
db1 |
|
- 'IdUser' - уникальный идентификатор пользователя в данной базе данных
- 'al' (address literal) - DNS-адрес
- 'an' (address numeric) - IP-адрес
- если 'al'≠null, то используется он
- если поле 'al'=null, то используется 'an'
- 'username' - имя пользователя во внешней базе данных
- 'password' - пароль пользователя во внешней базе данных.
При этом:
- SQL-команда или хранимая процедура, обращающиеся во внешнюю базу данных,
запрошивают в программе-терминале имя пользователя
(если у данного 'IdUser' для данного прозвища 'username'=null)
и пароль (если 'password'=null) той внешней базы данных
- таймер, обращающийся во внешнюю базу данных,
не начнет свое выполнение, если 'username'=null или 'password'=null,
и никаких вопросов не будет
- 'IdDb' - идентификатор внешней базы данных,
уникальный в пределах данной базы данных
(если 'IdDb'=null, то это - база данных, в которой сама эта запись находится)
- 'nickname' - прозвище внешней базы данных
(несколько разных 'IdUser' могут иметь одинаковый 'nickname'
с одинаковыми или разными 'al' и 'an',
но один 'IdUser' не может иметь двух одинаковых 'nickname')
- 'datatime' - дата последнего изменения этой записи таблицы 'sys-nicknames'
(используется для репликации таблиц 'sys-nicknames')
Командой 'connect',
в которой не указаны имя пользователя, пароль и адрес базы данных,
можно изменить базу данных, в которой пользователь "находится" -
имя пользователя, пароль и адрес базы данных будут взяты из таблицы 'sys-nicknames'
(поcледующая команда 'connect' будет использовать таблицу 'sys-nicknames'
новой базы данных, т.е. 'db2'):
Команда 'connect' воздействует на таблицу 'sys-nicknames' базы данных,
в которой пользователь находится: она
- обновляет поле 'an' значением, полученным от DNS-сервера
(само поле 'an' существует на случай поломки DNS-сервера)
- добавляет новые записи (в которых поле 'password'=null),
когда пользователь выполняет ее во внешнюю базу данных,
которая еще не зарегистрирована в 'sys-nicknames' с новыми 'ra' и 'username'
(зачение поля 'password' устанавливается командой 'update',
права доступа предоставляются пользователю
на каждую запись отдельно,
в т.ч. на каждую запись системной таблицы)
connect
ra="data.storage.com" username="Johnson" password="pwdj" nickname="db4";
update sys-nicknames set password=pwdj where
ra="data.storage.com" username="Johnson" nickname="db4";
sys-nicknames
IdUser |
al |
an |
username |
password |
IdDb |
nickname |
datatime |
101 |
data.storage.com |
234.234.234.234 |
Johnson |
pwdj |
38 |
db4 |
|
Репликация
После всего сказанного репликация баз данных с помощью фирменных программ
теряет всякий смысл -
ее всегда можно выполнить с помощью расширения SQL,
описанного выше.
Тюрин Дмитрий