Что такое исключение таблиц?
Основная идея исключения таблиц заключается в том, что иногда можно выполнить запрос, даже не обращаясь к некоторым таблицам, на которые он ссылается. Можно придумать множество таких случаев, но в исключении таблиц мы сосредоточились только на определенном классе SQL-конструкций, которые пишут при запросе к высоконормализованным данным.
Образцы запросов были взяты из «моделирования с якорем» — техники моделирования базы данных, которая доводит нормализацию до предела. Слайды на сайте моделирования с якорем содержат подробное объяснение моделирования с якорем и его достоинств, но часть, важная для исключения таблиц, может быть показана на примере.
Предположим, база данных хранит информацию об актерах, включая их имена, даты рождения и рейтинги, которые могут меняться со временем:
Согласно моделированию с якорем, каждый атрибут должен храниться в своей собственной таблице:
- таблица 'якорь', которая содержит только синтетический первичный ключ:
create table ac_anchor(AC_ID int primary key);
- таблица для атрибута 'имя':
create table ac_name(AC_ID int, ACNAM_name char(N),
primary key(AC_ID));
- таблица для атрибута 'дата рождения':
create table ac_dob(AC_ID int,
ACDOB_birthdate date,
primary key(AC_ID));
- таблица для атрибута 'рейтинг', которая историзирована:
create table ac_rating(AC_ID int,
ACRAT_rating int,
ACRAT_fromdate date,
primary key(AC_ID, ACRAT_fromdate));
Этот подход упрощает добавление/изменение/удаление атрибутов, но это сопровождается усложнением запросов к данным: для ответа на самый простой запрос SELECT всех данных, отображающий актеров и их текущие рейтинги, необходимо использовать внешние соединения:
Отображение актеров с их именами и текущими рейтингами:
select
ac_anchor.AC_ID, ACNAM_Name, ACDOB_birthdate, ACRAT_rating
from
ac_anchor
left join ac_name on ac_anchor.AC_ID=ac_name.AC_ID
left join ac_dob on ac_anchor.AC_ID=ac_dob.AC_ID
left join ac_rating on (ac_anchor.AC_ID=ac_rating.AC_ID and
ac_rating.ACRAT_fromdate =
(select max(sub.ACRAT_fromdate)
from ac_rating sub where sub.AC_ID = ac_rating.AC_ID))
Мы не хотим каждый раз писать соединения, когда нам нужно получить свойства актера, поэтому создадим представление:
create view actors as select ac_anchor.AC_ID, ACNAM_Name, ACDOB_birthdate, ACRAT_rating from <see the select above>
Это позволит нам получить доступ к данным так, как будто они хранятся обычным способом:
select ACRAT_rating from actors where ACNAM_name='Gary Oldman'
Именно здесь потребуется исключение таблиц.
См. также
- Эта страница основана на следующей статье блога об исключении таблиц: http://s.petrunia.net/blog/?p=58
© 2023 MariaDB
Licensed under the Creative Commons Attribution 3.0 Unported License and the GNU Free Documentation License.
https://mariadb.com/kb/en/what-is-table-elimination/