Частичная зависимость структуры данных от методов доступа к ним
Хотя из теории известно, что структура данных в БД должна быть независима от способов доступа к данным, на практике это обычно не так. Приведем пример.
Пусть в БД, работающей под управлением InterBase, имеется родительская таблица "Бюджетные лимиты подразделения" и подчиненные ей таблицы "Корректировки лимита", "Суммы сверх лимита", "Расходы лимитированных средств". При каждом расходовании лимитных средств (например, на покупку компьютеров) необходимо вычислить текущий остаток по такой формуле:
S1 + S2 +S3 - S4
где
S1 - начальный лимит (ТБД "Бюджетные лимиты подразделения");
S2 - сумма всех корректировок лимита по данному подразделению (таблица "Корректировки лимита");
S3 - сумма всех записей сверх лимита по данному подразделению (таблица "Суммы сверх лимита");
S4 - сумма всех предыдущих расходов подразделения по данному лимиту (таблица "Расходы лимитированных средств").
Пусть это соответственно значения 10000000 + 1000000 + 400000 - 6000000 = 5400000(рублей).
Пусть требуется записать сведения о расходе 3000000 рублей. Однако нужно быть уверенным в том, что другой пользователь в этот же самый момент не изменит ни одну из записей в указанных таблицах, результатом чего будет изменение остатка лимитных средств 5400000 (наверняка в меньшую сторону).
Чтобы блокировать текущий лимит данного подразделения, добавим в таблицу "Бюджетные лимиты подразделения" поле STATUS CHAR(l), и каждую транзакцию на изменение таблиц "Бюджетные лимиты подразделения", "Корректировки лимита", "Суммы сверх лимита", "Расходы лимитированных средств" в приложении будем начинать с изменения этого статуса:
Database1.StartTransaction;
TQuery1.Params[0] := Code;
// Code = код записи в ТБД "Бюджетные лимиты подразделения"
TRY
TQueryl.ExecSQL;
{Текст запроса вида
UPDATE ... SET STATUS = 'A' WHERE CodeZap = :Par1...}
{Вычисление текущего остатка данного бюджетного лимита по данному подразделению}
{Выполнение действий по изменению записей в дочерних таблицах}
EXCEPT
...
Тогда всякая другая транзакция, желающая изменить записи в дочерних таблицах (подчиненных текущей записи в таблице "Бюджетные лимиты подразделения") при выполнении TQuery1.ExecSQL возбудит исключение (deadlock) в связи с тем, что запись изменена другой транзакцией, пока не подтвердившей и не отменившей сделанных ею изменений. Однако эта блокировка не распространяется на другие бюджетные лимиты данного подразделения или других подразделений.
Как видим, введение дополнительного поля способно обеспечить желаемый режим разграничения доступа к данным.
Таким образом, проектируя логическую структуру данных в БД, невозможно абстрагироваться от того, каким образом эти данные будут обрабатываться на сервере и в клиентском приложении.
Заметим, что зависимость между структурой запросов к БД (в основном в операторе SELECT) и структурой и составом индексов таблиц также свидетельствует о связи между структурой данных и методами доступа к ним.