Примеры понятий - "сотрудник"...
Примеры понятий - "сотрудник", "отдел", "проект", "зарплата". Примеры взаимосвязей между понятиями - "сотрудник числится ровно в одном отделе", "сотрудник может выполнять несколько проектов", "над одним проектом может работать несколько сотрудников". Примеры ограничений - "возраст сотрудника не менее 16 и не более 60 лет".
Логическая модель данных является начальным прототипом будущей базы данных. Логическая модель строится в терминах информационных единиц, но без привязки к конкретной СУБД. Более того, логическая модель данных необязательно должна быть выражена средствами именно реляционной модели данных. Основным средством разработки логической модели данных в настоящий момент являются различные варианты ER-диаграмм
(Entity-Relationship, диаграммы сущность-связь). Одну и ту же ER-модель можно преобразовать как в реляционную модель данных, так и в модель данных для иерархических и сетевых СУБД, или в постреляционную модель данных. Однако, т.к. мы рассматриваем именно реляционные СУБД, то можно считать, что логическая модель данных для нас формулируется в терминах реляционной модели данных.
Решения, принятые на предыдущем уровне, при разработке модели предметной области, определяют некоторые границы, в пределах которых можно развивать логическую модель данных, в пределах же этих границ можно принимать различные решения. Например, модель предметной области складского учета содержит понятия "склад", "накладная", "товар". При разработке соответствующей реляционной модели эти термины обязательно должны быть использованы, но различных способов реализации тут много - можно создать одно отношение, в котором будут присутствовать в качестве атрибутов "склад", "накладная", "товар", а можно создать три отдельных отношения, по одному на каждое понятие.
При разработке логической модели данных возникают вопросы: хорошо ли спроектированы отношения? Правильно ли они отражают модель предметной области, а следовательно и саму предметную область?
Физическая модель данных. На еще более низком уровне находится физическая модель данных. Физическая модель данных описывает данные средствами конкретной СУБД. Мы будем считать, что физическая модель данных реализована средствами именно реляционной СУБД, хотя, как уже сказано выше, это необязательно. Отношения, разработанные на стадии формирования логической модели данных, преобразуются в таблицы, атрибуты становятся столбцами таблиц, для ключевых атрибутов создаются уникальные индексы, домены преображаются в типы данных, принятые в конкретной СУБД.
Ограничения, имеющиеся в логической модели данных, реализуются различными средствами СУБД, например, при помощи индексов, декларативных ограничений целостности, триггеров, хранимых процедур. При этом опять-таки решения, принятые на уровне логического моделирования определяют некоторые границы, в пределах которых можно развивать физическую модель данных. Точно также, в пределах этих границ можно принимать различные решения. Например, отношения, содержащиеся в логической модели данных, должны быть преобразованы в таблицы, но для каждой таблицы можно дополнительно объявить различные индексы, повышающие скорость обращения к данным. Многое тут зависит от конкретной СУБД.
При разработке физической модели данных возникают вопросы: хорошо ли спроектированы таблицы? Правильно ли выбраны индексы? Насколько много программного кода в виде триггеров и хранимых процедур необходимо разработать для поддержания целостности данных?
Собственно база данных и приложения. И, наконец, как результат предыдущих этапов появляется собственно сама база данных. База данных реализована на конкретной программно-аппаратной основе, и выбор этой основы позволяет существенно повысить скорость работы с базой данных. Например, можно выбирать различные типы компьютеров, менять количество процессоров, объем оперативной памяти, дисковые подсистемы и т.п. Очень большое значение имеет также настройка СУБД в пределах выбранной программно-аппаратной платформы.
Но опять решения, принятые на предыдущем уровне - уровне физического проектирования, определяют границы, в пределах которых можно принимать решения по выбору программно-аппаратной платформы и настройки СУБД.
Таким образом ясно, что решения, принятые на каждом этапе моделирования и разработки базы данных, будут сказываться на дальнейших этапах. Поэтому особую роль играет принятие правильных решений на ранних этапах моделирования.
Примеры предикатов различного...
Примеры предикатов различного вида приведены в главе 5. Ограничение типа CHECK может быть использовано как часть описания домена, таблицы, столбца таблицы или отдельного ограничения целостности - ASSERTION. Ограничение считается нарушенным, если предикат ограничения принимает значение FALSE.
Пример 15
.
Примитивные реляционные операторы
Примитивные реляционные операторы
Оставшиеся реляционные операторы (объединение, вычитание, декартово произведение, выборка, проекция) являются примитивными операторами - их нельзя выразить друг через друга.
Проблема несовместимого анализа
Проблема несовместимого анализа
Проблема несовместимого анализа включает несколько различных вариантов:
Неповторяемое считывание.
Фиктивные элементы (фантомы).
Собственно несовместимый анализ.
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание)
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание)
Транзакция B изменяет данные в строке. После этого транзакция A читает измененные данные и работает с ними. Транзакция B откатывается и восстанавливает старые данные.
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание)
Транзакция B изменяет данные в строке. После этого транзакция A читает измененные данные и работает с ними. Транзакция B откатывается и восстанавливает старые данные.
Проблема потери результатов обновления
Проблема потери результатов обновления
Две транзакции по очереди записывают некоторые данные в одну и ту же строку и фиксируют изменения.
Проблема потери результатов обновления
Две транзакции по очереди записывают некоторые данные в одну и ту же строку и фиксируют изменения.
Проблемы параллельной работы транзакций
Проблемы параллельной работы транзакций
Каким образом транзакции различных пользователей могут мешать друг другу? Различают три основные проблемы параллелизма:
Проблема потери результатов обновления.
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание).
Проблема несовместимого анализа.
Рассмотрим подробно эти проблемы.
Рассмотрим две транзакции, A и B, запускающиеся в соответствии с некоторыми графиками. Пусть транзакции работают с некоторыми объектами базы данных, например со строками таблицы. Операцию чтение строки , где в строку .
Продолжение алгоритма нормализации (приведение к 5нф)
Продолжение алгоритма нормализации (приведение к 5НФ)
В предыдущей главе был описан алгоритм нормализации как алгоритм приведения отношений к 3НФ. Теперь мы можем продолжить этот алгоритм, доведя его до алгоритма приведения к 5НФ.
Простые типы данных
Простые типы данных
Простые, или атомарные, типы данных не обладают внутренней структурой. Данные такого типа называют скалярами. К простым типам данных относятся следующие типы:
Логический.
Строковый.
Численный.
Различные языки программирования могут расширять и уточнять этот список, добавляя такие типы как:
Целый.
Вещественный.
Дата.
Время.
Денежный.
Перечислимый.
Интервальный.
И т.д.…
Конечно, понятие атомарности довольно относительно. Так, строковый тип данных можно рассматривать как одномерный массив символов, а целый тип данных - как набор битов. Важно лишь то, что при переходе на такой низкий уровень теряется семантика (смысл) данных. Если строку, выражающую, например, фамилию сотрудника, разложить в массив символов, то при этом теряется смысл такой строки как единого целого.
Работа транзакций в смеси
Работа транзакций в смеси
Транзакция рассматривается как последовательность элементарных атомарных операций. Атомарность отдельной элементарной операции состоит в том, что СУБД гарантирует, что, с точки зрения пользователя, будут выполнены два условия:
Эта операция будет выполнена целиком или не выполнена вовсе (атомарность - все или ничего).
Во время выполнения этой операции не выполняются никакие другие операции других транзакций (строгая очередность элементарных операций).
Например, элементарными операциями транзакции будут считывание страницы данных с диска или запись страницы данных на диск (страница данных - это минимальная единица для дисковых операций СУБД). Условие 2 на самом деле является именно логическим условием, т.к. реально система может выполнять несколько различных элементарных операций в один и тот же момент. Например, данные могут храниться на нескольких физически различных дисках и операции чтения-записи на эти диски могут выполняться одновременно.
Элементарные операции различных транзакций могут выполняться в произвольной очередности (конечно, внутри каждой транзакции последовательность элементарных операций этой транзакции является строго определенной). Например, если есть несколько транзакций, состоящих из последовательности операций элементарных:
то реальная последовательность, в которой СУБД выполняет эти транзакции может быть, например, такой:
Разрешение тупиковых ситуаций
Разрешение тупиковых ситуаций
Итак, при использовании протокола доступа к данным с использованием блокировок часть проблем разрешилось (не все), но возникла новая проблема - тупики:
Проблема потери результатов обновления - возник тупик.
Проблема незафиксированной зависимости (чтение "грязных" данных, неаккуратное считывание) - проблема разрешилась.
Неповторяемое считывание - проблема разрешилась.
Появление фиктивных элементов - проблема не разрешилась.
Проблема несовместимого анализа - возник тупик.
Общий вид тупика (dead locks) следующий:
Реализация изолированности транзакций средствами sql
Реализация изолированности транзакций средствами SQL
Реализация реляционной алгебры средствами оператора select (реляционная полнота sql)
Реализация реляционной алгебры средствами оператора SELECT (Реляционная полнота SQL)
Для того, чтобы показать, что язык SQL является реляционно полным, нужно показать, что любой реляционный оператор может быть выражен средствами SQL. На самом деле достаточно показать, что средствами SQL можно выразить любой из примитивных реляционных операторов.
Решение проблем параллелизма при помощи блокировок
Решение проблем параллелизма при помощи блокировок
Рассмотрим, как будут себя вести транзакции, вступающие в конфликт при доступе к данным, если они подчиняются протоколу доступа к данным.
from)
Шаг 1 (FROM)
. Вычисляется прямое декартовое произведение всех таблиц, указанных в обязательном разделе FROM. В результате шага 1 получаем таблицу A.
приведение к 1нф)
Шаг 1 (Приведение к 1НФ)
. На первом шаге задается одно или несколько отношений, отображающих понятия предметной области. По модели предметной области (не по внешнему виду полученных отношений!) выписываются обнаруженные функциональные зависимости. Все отношения автоматически находятся в 1НФ.
синтаксический анализ)
Шаг 1 (Синтаксический анализ)
. Поступивший запрос подвергается синтаксическому анализу. На этом шаге определяется, правильно ли вообще (с точки зрения синтаксиса SQL) сформулирован запрос. В ходе синтаксического анализа вырабатывается некоторое внутренне представление запроса, используемое на последующих шагах.
Вставить сотрудника в таблицу...
Шаг 1. Вставить сотрудника в таблицу PERSON: INSERT INTO PERSON (6, Муфтахов, 1)
Шаг 2. Увеличить значение поля Dept_Kol: UPDATE DEPART SET Dept=Dept+1 WHERE Dept_Id=1
Если после выполнения первой операции и до выполнения второй произойдет сбой системы, то реально будет выполнена только первая операция и база данных остается в нецелостном состоянии.
преобразование в каноническую форму)
Шаг 2 (Преобразование в каноническую форму)
. Запрос во внутреннем представлении подвергается преобразованию в некоторую каноническую форму. При преобразовании к канонической форме используются как синтаксические, так и семантические преобразования. Синтаксические преобразования (например, приведения логических выражений к конъюнктивной или дизъюнктивной нормальной форме, замена выражений "x AND NOT x" на "FALSE", и т.п.) позволяют получить новое внутренне представление запроса, синтаксически эквивалентное исходному, но стандартное в некотором смысле. Семантические преобразования используют дополнительные знания, которыми владеет система, например, ограничения целостности. В результате семантических преобразований получается запрос, синтаксически не эквивалентный исходному, но дающий тот же самый результат.
приведение к 2нф)
Шаг 2 (Приведение к 2НФ)
. Если в некоторых отношениях обнаружена зависимость атрибутов от части сложного ключа, то проводим декомпозицию этих отношений на несколько отношений следующим образом: те атрибуты, которые зависят от части сложного ключа выносятся в отдельное отношение вместе с этой частью ключа. В исходном отношении остаются все ключевые атрибуты:
Исходное отношение:
Ключ:
Функциональные зависимости:
Декомпозированные отношения:
.
.
where)
Шаг 2 (WHERE)
. Если в операторе SELECT присутствует раздел WHERE, то сканируется таблица A, полученная при выполнении шага 1. При этом для каждой строки из таблицы A вычисляется условное выражение, приведенное в разделе WHERE. Только те строки, для которых условное выражение возвращает значение TRUE, включаются в результат. Если раздел WHERE опущен, то сразу переходим к шагу 3. Если в условном выражении участвуют вложенные подзапросы, то они вычисляются в соответствии с данной концептуальной схемой. В результате шага 2 получаем таблицу B.
генерация планов выполнения запроса и выбор оптимального плана)
Шаг 3 (Генерация планов выполнения запроса и выбор оптимального плана)
. На этом шаге оптимизатор генерирует множество возможных планов выполнения запроса. Каждый план строится как комбинация низкоуровневых процедур доступа к данным из таблиц, методам соединения таблиц. Из всех сгенерированных планов выбирается план, обладающий минимальной стоимостью. При этом анализируются данные о наличии индексов у таблиц, статистических данных о распределении значений в таблицах, и т.п. Стоимость плана это, как правило, сумма стоимостей выполнения отдельных низкоуровневых процедур, которые используются для его выполнения. В стоимость выполнения отдельной процедуры могут входить оценки количества обращений к дискам, степень загруженности процессора и другие параметры.
group by)
Шаг 3 (GROUP BY)
. Если в операторе SELECT присутствует раздел GROUP BY, то строки таблицы B, полученной на втором шаге, группируются в соответствии со списком группировки, приведенным в разделе GROUP BY. Если раздел GROUP BY опущен, то сразу переходим к шагу 4. В результате шага 3 получаем таблицу С.
приведение к 3нф)
Шаг 3 (Приведение к 3НФ)
. Если в некоторых отношениях обнаружена зависимость некоторых неключевых атрибутов других неключевых атрибутов, то проводим декомпозицию этих отношений следующим образом: те неключевые атрибуты, которые зависят других неключевых атрибутов выносятся в отдельное отношение. В новом отношении ключом становится детерминант функциональной зависимости:
Исходное отношение:
Ключ:
Функциональные зависимости:
Декомпозированные отношения:
.
.
Замечание. На практике, при создании логической модели данных, как правило, не следуют прямо приведенному алгоритму нормализации. Опытные разработчики обычно сразу строят отношения в 3НФ. Кроме того, основным средством разработки логических моделей данных являются различные варианты ER-диаграмм. Особенность этих диаграмм в том, что они сразу позволяют создавать отношения в 3НФ. Тем не менее, приведенный алгоритм важен по двум причинам. Во-первых, этот алгоритм показывает, какие проблемы возникают при разработке слабо нормализованных отношений. Во-вторых, как правило, модель предметной области никогда не бывает правильно разработана с первого шага. Эксперты предметной области могут забыть о чем-либо упомянуть, разработчик может неправильно понять эксперта, во время разработки могут измениться правила, принятые в предметной области, и т.д. Все это может привести к появлению новых зависимостей, которые отсутствовали в первоначальной модели предметной области. Тут как раз и необходимо использовать алгоритм нормализации хотя бы для того, чтобы убедиться, что отношения остались в 3НФ и логическая модель не ухудшилась.
having)
Шаг 4 (HAVING)
. Если в операторе SELECT присутствует раздел HAVING, то группы, не удовлетворяющие условному выражению, приведенному в разделе HAVING, исключаются. Если раздел HAVING опущен, то сразу переходим к шагу 5. В результате шага 4 получаем таблицу D.
приведение к нфбк)
Шаг 4 (Приведение к НФБК)
. Если имеются отношения, содержащие несколько потенциальных ключей, то необходимо проверить, имеются ли функциональные зависимости, детерминанты которых не являются потенциальными ключами. Если такие функциональные зависимости имеются, то необходимо провести дальнейшую декомпозицию отношений. Те атрибуты, которые зависят от детерминантов, не являющихся потенциальными ключами выносятся в отдельное отношение вместе с детерминантами.
выполнение плана запроса)
Шаг 4. (Выполнение плана запроса)
. На этом шаге план, выбранный на предыдущем шаге, передается на реальное выполнение.
Во многом качество конкретной СУБД определяется качеством ее оптимизатора. Хороший оптимизатор может повысить скорость выполнения запроса на несколько порядков. Качество оптимизатора определяется тем, какие методы преобразований он может использовать, какой статистической и иной информацией о таблицах он располагает, какие методы для оценки стоимости выполнения плана он знает.
приведение к 4нф)
Шаг 5 (Приведение к 4НФ)
. Если в отношениях обнаружены нетривиальные многозначные зависимости, то необходимо провести декомпозицию для исключения таких зависимостей.
приведение к 5нф)
Шаг 5 (Приведение к 5НФ)
. Если в отношениях обнаружены нетривиальные зависимости соединения, то необходимо провести декомпозицию для исключения и таких зависимостей.
select)
Шаг 5 (SELECT)
. Каждая группа, полученная на шаге 4, генерирует одну строку результата следующим образом. Вычисляются все скалярные выражения, указанные в разделе SELECT. По правилам использования раздела GROUP BY, такие скалярные выражения должны быть одинаковыми для всех строк внутри каждой группы. Для каждой группы вычисляются значения агрегатных функций, приведенных в разделе SELECT. Если раздел GROUP BY отсутствовал, но в разделе SELECT есть агрегатные функции, то считается, что имеется всего одна группа. Если нет ни раздела GROUP BY, ни агрегатных функций, то считается, что имеется столько групп, сколько строк отобрано к данному моменту. В результате шага 5 получаем таблицу E, содержащую столько колонок, сколько элементов приведено в разделе SELECT и столько строк, сколько отобрано групп.
Синтаксис ограничений стандарта sql
Синтаксис ограничений стандарта SQL
Понятие ограничения используется во многих операторах определения данных (DDL).
Ограничение check::=
CHECK Предикат
Ограничения таблицы ::=
[CONSTRAINT Имя ограничения]
{
{PRIMARY KEY (Имя столбца.,..)}
| {UNIQUE (Имя столбца.,..)}
| {FOREIGN KEY (Имя столбца.,..) REFERENCES Имя таблицы [(Имя столбца.,..)] [Ссылочная спецификация]}
| { Ограничение check }
}
[Атрибуты ограничения]
Ограничения столбца::=
[CONSTRAINT Имя ограничения]
{
{NOT NULL}
| {PRIMARY KEY}
| {UNIQUE}
| {REFERENCES Имя таблицы [(Имя столбца)] [Ссылочная спецификация]}
| { Ограничение check }
}
[Атрибуты ограничения]
Ссылочная спецификация::=
[MATCH {FULL | PARTIAL}]
[ON UPDATE {CASCADE | SET NULL | SET DEFAULT | NO ACTION}]
[ON DELETE {CASCADE | SET NULL | SET DEFAULT | NO ACTION}]
Атрибуты ограничения::=
{DEFERRABLE [INITIALLY DEFERRED | INITIALLY IMMEDIATE]}
| {NOT DEFERRABLE}
Ограничение типа CHECK. Ограничение типа CHECK содержит предикат, могущий принимать значения TRUE, FALSE и UNKNOWN (NULL).
Синтаксис оператора выборки
Синтаксис оператора выборки
В довольно сильно упрощенном виде оператор выборки данных имеет следующий синтаксис (для некоторых элементов мы дадим не BNF-определения, а словесное описание):
Оператор выборки ::=
Табличное выражение
[ORDER BY
{{Имя столбца-результата [ASC | DESC]} | {Положительное целое [ASC | DESC]}}.,..];
Табличное выражение ::=
Select-выражение
[
{UNION | INTERSECT | EXCEPT} [ALL]
{Select-выражение | TABLE Имя таблицы | Конструктор значений таблицы}
]
Select-выражение ::=
SELECT [ALL | DISTINCT]
{{{Скалярное выражение | Функция агрегирования | Select-выражение} [AS Имя столбца]}.,..}
| {{Имя таблицы|Имя корреляции}.*}
| *
FROM {
{Имя таблицы [AS] [Имя корреляции] [(Имя столбца.,..)]}
| {Select-выражение [AS] Имя корреляции [(Имя столбца.,..)]}
| Соединенная таблица
}.,..
[WHERE Условное выражение]
[GROUP BY {[{Имя таблицы|Имя корреляции}.]Имя столбца}.,..]
[HAVING Условное выражение]
Замечание. Select-выражение в разделе SELECT, используемое в качестве значения для отбираемого столбца, должно возвращать таблицу, состоящую из одной строки и одного столбца, т.е. скалярное выражение.
Замечание. Условное выражение в разделе WHERE должно вычисляться для каждой строки, являющейся кандидатом в результатирующее множество строк. В этом условном выражении можно использовать подзапросы. Синтаксис условных выражений, допустимых в разделе WHERE рассматривается ниже.
Замечание. Раздел HAVING содержит условное выражение, вычисляемое для каждой группы, определяемой списком группировки в разделе GROUP BY. Это условное выражение может содержать функции агрегирования, вычисляемые для каждой группы. Условное выражение, сформулированное в разделе WHERE, может быть перенесено в раздел HAVING. Перенос условий из раздела HAVING в раздел WHERE невозможен, если условное выражение содержит агрегатные функции. Перенос условий из раздела WHERE в раздел HAVING является плохим стилем программирования - эти разделы предназначены для различных по смыслу условий (условия для строк и условия для групп строк).
Замечание. Если в разделе SELECT присутствуют агрегатные функции, то они вычисляются по-разному в зависимости от наличия раздела GROUP BY. Если раздел GROUP BY отсутствует, то результат запроса возвращает не более одной строки. Агрегатные функции вычисляются по всем строкам, удовлетворяющим условному выражению в разделе WHERE. Если раздел GROUP BY присутствует, то агрегатные функции вычисляются по отдельности для каждой группы, определенной в разделе GROUP BY.
Скалярное выражение - в качестве скалярных выражений в разделе SELECT могут выступать либо имена столбцов таблиц, входящих в раздел FROM, либо простые функции, возвращающие скалярные значения.
Функция агрегирования ::=
COUNT (*) |
{
{COUNT | MAX | MIN | SUM | AVG} ([ALL | DISTINCT] Скалярное выражение)
}
Конструктор значений таблицы ::=
VALUES Конструктор значений строки.,..
Конструктор значений строки ::=
Элемент конструктора | (Элемент конструктора.,..) | Select-выражение
Замечание. Select-выражение, используемое в конструкторе значений строки, обязано возвращать ровно одну строку.
Элемент конструктора ::=
Выражение для вычисления значения | NULL | DEFAULT
Синтаксис операторов sql, использующих ограничения
Синтаксис операторов SQL, использующих ограничения
Стандарт SQL описывает следующие операторы, в которых может быть использованы ограничения:
CREATE DOMAIN - создать домен
ALTER DOMAIN - изменить домен
DROP DOMAIN - удалить домен
CREATE TABLE - создать таблицу
ALTER TABLE - изменить таблицу
DROP TABLE - удалить таблицу
CREATE ASSERTION - создать утверждение
DROP ASSERTION - удалить утверждение
COMMIT WORK - зафиксировать транзакцию
SET CONSTRAINTS - установить момент проверки ограничений
CREATE DOMAIN Имя домена [AS] Тип данных
[DEFAULT Значение по умолчанию]
[Имя ограничения] Ограничение check [Атрибуты ограничения]
Этот оператор задает домен, на основе которого можно определять колонки таблиц. Т.к. имя колонки, которая будет основана на этом домене заранее неизвестно, то в ограничении CHECK домена для ссылки на значение этого домена используется ключевое слово VALUE. В конкретной таблице СУБД заменит слово VALUE на имя колонки таблицы.
Синтаксис операторов sql, определяющих уровни изоляции
Синтаксис операторов SQL, определяющих уровни изоляции
Уровень изоляции транзакции задается следующим оператором:
SET TRANSACTION {ISOLATION LEVEL
{READ UNCOMMITTED
| READ COMMITTED
| REPEATABLE READ
| SERIALIZABLE}
| {READ ONLY | READ WRITE}}.,..
Этот оператор определяет режим выполнения следующей транзакции, т.е. этот оператор не влияет на изменение режима той транзакции, в которой он подается. Обычно, выполнение оператора SET TRANSACTION выделяется как отдельная транзакция:
… (предыдущая транзакция выполняется со своим уровнем изоляции)
COMMIT;
SET TRANSACTION ISOLATION LEVEL REPEATABLE READ;
COMMIT;
… (следующая транзакция выполняется с уровнем изоляции REPEATABLE READ)
Если задано предложение ISOLATION LEVEL, то за ним должно следовать один из параметров, определяющих уровень изоляции.
Кроме того, можно задать признаки READ ONLY или READ WRITE. Если указан признак READ ONLY, то предполагается, что транзакция будет только читать данные. При попытке записи для такой транзакции будет сгенерирована ошибка. Признак READ ONLY введен для того, чтобы дать производителям СУБД возможность уменьшать количество блокировок путем использования других методов сериализации (например, метод выделения версий).
Оператор SET TRANSACTION должен удовлетворять следующим условиям:
Если предложение ISOLATION LEVEL отсутствует, то по умолчанию принимается уровень SERIALIZABLE.
Если задан признак READ WRITE, то параметр ISOLATION LEVEL не может принимать значение READ UNCOMMITTED.
Если параметр ISOLATION LEVEL определен как READ UNCOMMITTED, то транзакция становится по умолчанию READ ONLY. В противном случае по умолчанию транзакция считается как READ WRITE.
Синтаксис соединенных таблиц
Синтаксис соединенных таблиц
В разделе FROM оператора SELECT можно использовать соединенные таблицы. Пусть в результате некоторых операций мы получаем таблицы A и B. Такими операциями могут быть, например, оператор SELECT или другая соединенная таблица. Тогда синтаксис соединенной таблицы имеет следующий вид:
Соединенная таблица ::=
Перекрестное соединение
| Естественное соединение
| Соединение посредством предиката
| Соединение посредством имен столбцов
| Соединение объединения
Тип соединения ::=
INNER
| LEFT [OUTER]
| RIGTH [OUTER]
| FULL [OUTER]
Перекрестное соединение ::=
Таблица А CROSS JOIN Таблица В
Естественное соединение ::=
Таблица А [NATURAL] [Тип соединения] JOIN Таблица В
Соединение посредством предиката ::=
Таблица А [Тип соединения] JOIN Таблица В ON Предикат
Соединение посредством имен столбцов ::=
Таблица А [Тип соединения] JOIN Таблица В USING (Имя столбца.,..)
Соединение объединения ::=
Таблица А UNION JOIN Таблица В
Опишем используемые термины.
CROSS JOIN - Перекрестное соединение возвращает просто декартово произведение таблиц. Такое соединение в разделе FROM может быть заменено списком таблиц через запятую.
NATURAL JOIN - Естественное соединение производится по всем столбцам таблиц А и В, имеющим одинаковые имена. В результатирующую таблицу одинаковые столбцы вставляются только один раз.
JOIN … ON - Соединение посредством предиката соединяет строки таблиц А и В посредством указанного предиката.
JOIN … USING - Соединение посредством имен столбцов соединяет отношения подобно естественному соединению по тем общим столбцам таблиц А и Б, которые указаны в списке USING.
OUTER - Ключевое слово OUTER (внешний) не является обязательными, оно не используется ни в каких операциях с данными.
INNER - Тип соединения "внутреннее". Внутренний тип соединения используется по умолчанию, когда тип явно не задан. В таблицах А и В соединяются только те строки, для которых найдено совпадение.
LEFT (OUTER) - Тип соединения "левое (внешнее)". Левое соединение таблиц А и В включает в себя все строки из левой таблицы А и те строки из правой таблицы В, для которых обнаружено совпадение. Для строк из таблицы А, для которых не найдено соответствия в таблице В, в столбцы, извлекаемые из таблицы В, заносятся значения NULL.
RIGHT (OUTER) - Тип соединения "правое (внешнее)". Правое соединение таблиц А и В включает в себя все строки из правой таблицы В и те строки из левой таблицы А, для которых обнаружено совпадение. Для строк из таблицы В, для которых не найдено соответствия в таблице А, в столбцы, извлекаемые из таблицы А заносятся значения NULL.
FULL (OUTER) - Тип соединения "полное (внешнее)". Это комбинация левого и правого соединений. В полное соединение включаются все строки из обеих таблиц. Для совпадающих строк поля заполняются реальными значениями, для несовпадающих строк поля заполняются в соответствии с правилами левого и правого соединений.
UNION JOIN - Соединение объединения является обратным по отношению к внутреннему соединению. Оно включает только те строки из таблиц А и В, для которых не найдено совпадений. В них используются значения NULL для столбцов, полученных из другой таблицы. Если взять полное внешнее соединение и удалить из него строки, полученные в результате внутреннего соединения, то получится соединение объединения.
Использование соединенных таблиц часто облегчает восприятие оператора SELECT, особенно, когда используется естественное соединение. Если не использовать соединенные таблицы, то при выборе данных из нескольких таблиц необходимо явно указывать условия соединения в разделе WHERE. Если при этом пользователь указывает сложные критерии отбора строк, то в разделе WHERE смешиваются семантически различные понятия - как условия связи таблиц, так и условия отбора строк (см. примеры 13, 14, 15 данной главы).
Синтаксис условных выражений раздела where
Синтаксис условных выражений раздела WHERE
Условное выражение, используемое в разделе WHERE оператора SELECT должно вычисляться для каждой строки-кандидата, отбираемой оператором SELECT. Условное выражение может возвращать одно из трех значений истинности: TRUE, FALSE или UNKNOUN. Строка-кандидат отбирается в результатирующее множество строк только в том случае, если для нее условное выражение вернуло значение TRUE.
Условные выражения имеют следующий синтаксис (в целях упрощения изложения приведены не все возможные предикаты):
Условное выражение ::=
[ ( ] [NOT]
{Предикат сравнения
| Предикат between
| Предикат in
| Предикат like
| Предикат null
| Предикат количественного сравнения
| Предикат exist
| Предикат unique
| Предикат match
| Предикат overlaps}
[{AND | OR} Условное выражение] [ ) ]
[IS [NOT] {TRUE | FALSE | UNKNOWN}]
Предикат сравнения ::=
Конструктор значений строки {= | < | > | <= | >= | <>} Конструктор значений строки
Скорость операций обновления данных (вставка, обновление, удаление)
Скорость операций обновления данных (вставка, обновление, удаление)
На уровне логического моделирования мы определяем реляционные отношения и атрибуты этих отношений. На этом уровне мы не можем определять какие-либо физические структуры хранения (индексы, хеширование и т.п.). Единственное, чем мы можем управлять - это распределением атрибутов по различным отношениям. Можно описать мало отношений с большим количеством атрибутов, или много отношений, каждое из которых содержит мало атрибутов. Таким образом, необходимо попытаться ответить на вопрос - влияет ли количество отношений и количество атрибутов в отношениях на скорость выполнения операций обновления данных. Такой вопрос, конечно, не является достаточно корректным, т.к. скорость выполнения операций с базой данных сильно зависит от физической реализации базы данных. Тем не менее, попытаемся качественно оценить это влияние при одинаковых подходах к физическому моделированию.
Основными операциями, изменяющими состояние базы данных, являются операции вставки, обновления и удаления записей. В базах данных, требующих постоянных изменений (складской учет, системы продаж билетов и т.п.) производительность определяется скоростью выполнения большого количества небольших операций вставки, обновления и удаления.
Рассмотрим операцию вставки записи в таблицу. Вставка записи производится в одну из свободных страниц памяти, выделенной для данной таблицы. СУБД постоянно хранит информацию о наличии и расположении свободных страниц. Если для таблицы не созданы индексы, то операция вставки выполняется фактически с одинаковой скоростью независимо от размера таблицы и от количества атрибутов в таблице. Если в таблице имеются индексы, то при выполнении операции вставки записи индексы должны быть перестроены. Таким образом, скорость выполнения операции вставки уменьшается при увеличении количества индексов у таблицы и мало зависит от числа строк в таблице.
Рассмотрим операции обновления и удаления записей из таблицы. Прежде, чем обновить или удалить запись, ее необходимо найти. Если таблица не индексирована, то единственным способом поиска является последовательное сканирование таблицы в поиске нужной записи. В этом случае, скорость операций обновления и удаления существенно увеличивается с увеличением количества записей в таблице и не зависит от количества атрибутов. Но на самом деле неиндексированные таблицы практически никогда не используются. Для каждой таблицы обычно объявляется один или несколько индексов, соответствующий потенциальным ключам. При помощи этих индексов поиск записи производится очень быстро и практически не зависит от количества строк и атрибутов в таблице (хотя, конечно, некоторая зависимость имеется). Если для таблицы объявлено несколько индексов, то при выполнении операций обновления и удаления эти индексы должны быть перестроены, на что тратится дополнительное время. Таким образом, скорость выполнения операций обновления и удаления также уменьшается при увеличении количества индексов у таблицы и мало зависит от числа строк в таблице.
Можно предположить, что чем больше атрибутов имеет таблица, тем больше для нее будет объявлено индексов. Эта зависимость, конечно, не прямая, но при одинаковых подходах к физическому моделированию обычно так и происходит. Таким образом, можно принять допущение, что чем больше атрибутов имеют отношения, разработанные в ходе логического моделирования, тем медленнее будут выполняться операции обновления данных, за счет затраты времени на перестройку большего количества индексов.
Дополнительные соображения в пользу приведенного тезиса о замедлении выполнения операций обновления данных (влияние журнализации, длины строк таблиц) приведены в работе А.Прохорова [27].
Скорость операций выборки данных
Скорость операций выборки данных
Одно из назначений базы данных - предоставление информации пользователям. Информация извлекается из реляционной базы данных при помощи оператора SQL - SELECT. Одной из наиболее дорогостоящих операций при выполнении оператора SELECT является операция соединение таблиц. Таким образом, чем больше взаимосвязанных отношений было создано в ходе логического моделирования, тем больше вероятность того, что при выполнении запросов эти отношения будут соединяться, и, следовательно, тем медленнее будут выполняться запросы. Таким образом, увеличение количества отношений приводит к замедлению выполнения операций выборки данных, особенно, если запросы заранее неизвестны.
Собственно несовместимый анализ
Собственно несовместимый анализ
Эффект собственно несовместимого анализа также отличается от предыдущих примеров тем, что в смеси присутствуют две транзакции - одна длинная, другая короткая.
Длинная транзакция выполняет некоторый анализ по всей таблице, например, подсчитывает общую сумму денег на счетах клиентов банка для главного бухгалтера. Пусть на всех счетах находятся одинаковые суммы, например, по $100. Короткая транзакция в этот момент выполняет перевод $50 с одного счета на другой так, что общая сумма по всем счетам не меняется.
Соединение
Соединение
Операция соединения отношений, наряду с операциями выборки и проекции, является одной из наиболее важных реляционных операций.
Обычно рассматривается несколько разновидностей операции соединения:
Общая операция соединения
Экви-соединение
Естественное соединение
Наиболее важным из этих частных случаев является операция естественного соединения. Все разновидности соединения являются частными случаями общей операции соединения.
Сравнение нормализованных и ненормализованных моделей
Сравнение нормализованных и ненормализованных моделей
Соберем воедино результаты анализа критериев, по которым мы хотели оценить влияние логического моделирования данных на качество физических моделей данных и производительность базы данных:
Ссылочные типы данных
Ссылочные типы данных
Ссылочный тип данных (указатели) предназначен для обеспечения возможности указания на другие данные. Указатели характерны для языков процедурного типа, в которых есть понятие области памяти для хранения данных. Ссылочный тип данных предназначен для обработки сложных изменяющихся структур, например деревьев, графов, рекурсивных структур.
Стадия 1. Выполнение одиночного оператора select
Стадия 1. Выполнение одиночного оператора SELECT
Если в операторе присутствуют ключевые слова UNION, EXCEPT и INTERSECT, то запрос разбивается на несколько независимых запросов, каждый из которых выполняется отдельно:
Стадия 2. Выполнение операций union, except, intersect
Стадия 2. Выполнение операций UNION, EXCEPT, INTERSECT
Если в операторе SELECT присутствовали ключевые слова UNION, EXCEPT и INTERSECT, то таблицы, полученные в результате выполнения 1-й стадии, объединяются, вычитаются или пересекаются.
Стадия 3. Упорядочение результата
Стадия 3. Упорядочение результата
Если в операторе SELECT присутствует раздел ORDER BY, то строки полученной на предыдущих шагах таблицы упорядочиваются в соответствии со списком упорядочения, приведенном в разделе ORDER BY.
Стратегии поддержания ссылочной целостности
Стратегии поддержания ссылочной целостности
Существуют две основные стратегии поддержания ссылочной целостности:
RESTRICT (ОГРАНИЧИТЬ)- не разрешать выполнение операции, приводящей к нарушению ссылочной целостности. Это самая простая стратегия, требующая только проверки, имеются ли кортежи в дочернем отношении, связанные с некоторым кортежем в родительском отношении.
CASCADE (КАСКАДИРОВАТЬ)- разрешить выполнение требуемой операции, но внести при этом необходимые поправки в других отношениях так, чтобы не допустить нарушения ссылочной целостности и сохранить все имеющиеся связи. Изменение начинается в родительском отношении и каскадно выполняется в дочернем отношении. В реализации этой стратегии имеется одна тонкость, заключающаяся в том, что дочернее отношение само может быть родительским для некоторого третьего отношения. При этом может дополнительно потребоваться выполнение какой-либо стратегии и для этой связи и т.д. Если при этом какая-либо из каскадных операций (любого уровня) не может быть выполнена, то необходимо отказаться от первоначальной операции и вернуть базу данных в исходное состояние. Это самая сложная стратегия, но она хороша тем, что при этом не нарушается связь между кортежами родительского и дочернего отношений.
Эти стратегии являются стандартными и присутствуют во всех СУБД, в которых имеется поддержка ссылочной целостности.
Можно рассмотреть дополнительные стратегии поддержания ссылочной целостности:
SET NULL (УСТАНОВИТЬ В NULL) - разрешить выполнение требуемой операции, но все возникающие некорректные значения внешних ключей изменять на null-значения. Эта стратегия имеет два недостатка. Во-первых, для нее требуется допустить использование null-значений. Во-вторых, кортежи дочернего отношения теряют всякую связь с кортежами родительского отношения. Установить, с каким кортежем родительского отношения были связаны измененные кортежи дочернего отношения, после выполнения операции уже нельзя.
SET DEFAULT (УСТАНОВИТЬ ПО УМОЛЧАНИЮ) - разрешить выполнение требуемой операции, но все возникающие некорректные значения внешних ключей изменять на некоторое значение, принятое по умолчанию. Достоинство этой стратегии по сравнению с предыдущей в том, что она позволяет не пользоваться null-значеними. Недостатки заключаются в следующем. Во-первых, в родительском отношении должен быть некий кортеж, потенциальный ключ которого принят как значение по умолчанию для внешних ключей. В качестве такого "кортежа по умолчанию" обычно принимают специальный кортеж, заполненный нулевыми значениями (не null-значениями!). Этот кортеж нельзя удалять из родительского отношения, и в этом кортеже нельзя изменять значение потенциального ключа. Таким образом, не все кортежи родительского отношения становятся равнозначными, поэтому приходится прилагать дополнительные усилия для отслеживания этой неравнозначности. Это плата за отказ от использования null-значений. Во-вторых, как и в предыдущем случае, кортежи дочернего отношения теряют всякую связь с кортежами родительского отношения. Установить, с каким кортежем родительского отношения были связаны измененные кортежи дочернего отношения, после выполнения операции уже нельзя.
В некоторых реализация СУБД рассматривается еще одна стратегия поддержания ссылочной целостности:
IGNORE (ИГНОРИРОВАТЬ) - выполнять операции, не обращая внимания на нарушения ссылочной целостности.
Конечно, это не стратегия, а отказ от поддержки ссылочной целостности. В этом случае в дочернем отношении могут появляться некорректные значения внешних ключей, и вся ответственность за целостность базы данных ложится на пользователя.
В дополнение к приведенным стратегиям пользователь может придумать свою уникальную стратегию поддержания ссылочной целостности.
Структурированные типы данных
Структурированные типы данных
Структурированные типы данных предназначены для задания сложных структур данных. Структурированные типы данных конструируются из составляющих элементов, называемых компонентами, которые, в свою очередь, могут обладать структурой. В качестве структурированных типов данных можно привести следующие типы данных:
Массивы
Записи (Структуры)
С математической точки зрения массив представляет собой функцию с конечной областью определения. Например, рассмотрим конечное множество натуральных чисел
называемое множеством индексов. Отображение
из множества задает одномерный вещественный массив. Значение этой функции для некоторого значения индекса . Аналогично можно задавать многомерные массивы.
Запись (или структура) представляет собой кортеж из некоторого декартового произведения множеств. Действительно, запись представляет собой именованный упорядоченный набор элементов . Таким образом, запись . Объявляя новые типы записей на основе уже имеющихся типов, пользователь может конструировать сколь угодно сложные типы данных.
Общим для структурированных типов данных является то, что они имеют внутреннюю структуру, используемую на том же уровне абстракции, что и сами типы данных.
Поясним это следующим образом. При работе с массивами или записями можно манипулировать массивом или записью и как с единым целым (создавать, удалять, копировать целые массивы или записи), так и поэлементно. Для структурированных типов данных есть специальные функции - конструкторы типов, позволяющие создавать массивы или записи из элементов более простых типов.
Работая же с простыми типами данных, например с числовыми, мы манипулируем ими как неделимыми целыми объектами. Чтобы "увидеть", что числовой тип данных на самом деле сложен (является набором битов), нужно перейти на более низкий уровень абстракции. На уровне программного кода это будет выглядеть как ассемблерные вставки в код на языке высокого уровня или использование специальных побитных операций.
Свойства отношений
Свойства отношений
Свойства отношений непосредственно следуют из приведенного выше определения отношения. В этих свойствах в основном и состоят различия между отношениями и таблицами.
В отношении нет одинаковых кортежей. Действительно, тело отношения есть множество кортежей и, как всякое множество, не может содержать неразличимые элементы (см. понятие множества в гл.1.). Таблицы в отличие от отношений могут содержать одинаковые строки.
Кортежи не упорядочены (сверху вниз). Действительно, несмотря на то, что мы изобразили отношение "Сотрудники" в виде таблицы, нельзя сказать, что сотрудник Иванов "предшествует" сотруднику Петрову. Причина та же - тело отношения есть множество, а множество не упорядочено. Это вторая причина, по которой нельзя отождествить отношения и таблицы - строки в таблицах упорядочены. Одно и то же отношение может быть изображено разными таблицами, в которых строки идут в различном порядке.
Атрибуты не упорядочены (слева направо). Т.к. каждый атрибут имеет уникальное имя в пределах отношения, то порядок атрибутов не имеет значения. Это свойство несколько отличает отношение от математического определения отношения (см. гл.1 - компоненты кортежей там упорядочены). Это также третья причина, по которой нельзя отождествить отношения и таблицы - столбцы в таблице упорядочены. Одно и то же отношение может быть изображено разными таблицами, в которых столбцы идут в различном порядке.
Все значения атрибутов атомарны. Это следует из того, что лежащие в их основе атрибуты имеют атомарные значения. Это четвертое отличие отношений от таблиц - в ячейки таблиц можно поместить что угодно - массивы, структуры, и даже другие таблицы.
Замечание. Из свойств отношения следует, что не каждая таблица может задавать отношение. Для того, чтобы некоторая таблица задавала отношение, необходимо, чтобы таблица имела простую структуру (содержала бы только строки и столбцы, причем, в каждой строке было бы одинаковое количество полей), в таблице не должно быть одинаковых строк, любой столбец таблицы должен содержать данные только одного типа, все используемые типы данных должны быть простыми.
Замечание. Каждое отношение можно считать классом эквивалентности таблиц, для которых выполняются следующие условия:
Таблицы имеют одинаковое количество столбцов.
Таблицы содержат столбцы с одинаковыми наименованиями.
Столбцы с одинаковыми наименованиями содержат данные из одних и тех же доменов.
Таблицы имеют одинаковые строки с учетом того, что порядок столбцов может различаться.
Все такие таблицы есть различные изображения одного и того же отношения.
и текстовые редакторы позволяют хранить
Таблица 1
ОтделСотрудникиДети сотрудников (интересы)
Цех | Иванов И.И. | Маша | ЛЕГО |
Петя | Книги | Видео |
Саша | Компьютеры |
Дима | Спорт |
Петров П.П. | Артур | Ничем не интересуется |
Сидоров С.С. | Сергей | Компьютеры Книги |
Валерий | Книги |
Станислав | Видео |
Бухгалтерия | … | … |
Таблица 1 Таблица произвольной формыКонечно, и электронные таблицы, и текстовые редакторы позволяют хранить и обрабатывать данные очень гибко, но как быть, если требуется хранить информацию обо всех сотрудниках большого предприятия и периодически выдавать ответы на запросы типа "представить список всех сотрудников, принятых на работу не позднее трех лет назад, имеющих по крайней мере одного ребенка, не имеющих взысканий и с зарплатой не выше 1000 р.". Для получения ответов на подобные запросы и предназначены Системы Управления Базами Данных (СУБД).
Классическая реляционная модель данных требует, чтобы данные хранились в так называемых плоских таблицах. Более точно, пользователи и приложения, обращающиеся к данным, должны работать с данными так, как если бы они размещались в таких таблицах. В упрощенном виде плоская таблица - это таблица, каждая ячейка которой может быть однозначно идентифицирована указанием строки и столбца таблицы. Кроме того, в одном столбце все ячейки должны содержать данные одного простого типа. Точное определение понятия "плоская таблица" дается в реляционной модели данных.
Реляционная модель основана на теории множеств и математической логике. Такой фундамент обеспечивает математическую строгость реляционной модели данных.
В свою очередь, на основе реляционной модели были разработаны различные языки для доступа к реляционным данным, такие как SEQUEL, SQL, QUEL и другие. Фактическим промышленным стандартом в настоящее время стал язык SQL (Structured Query Language - язык структурированных запросов).
Различные фирмы, производители СУБД, предлагают свои реализации языка SQL. Эти реализации отличаются как друг от друга, так и от стандартизованного языка SQL. Это и хорошо и плохо. Хорошо это тем, что конкретная реализация языка, может включать в себя более широкие возможности по сравнению со стандартизованными SQL, например, больше типов данных, большее количество команд, больше дополнительных опций имеющихся команд. Такие возможности делают работу с конкретной СУБД более эффективной. Кроме того, такие нестандартные возможности языка проходят практическую апробацию и со временем могут быть включены в стандарт. Плохо же это тем, что различия в синтаксисе реализаций SQL затрудняют перенос приложений из одной системы в другую. Например, если приложение было написано для базы данных MS SQL Server с использованием своего диалекта SQL - языка Transact-SQL, то при переносе системы в базу данных ORACLE, не все конструкции языка будут понятны соответствующему диалекту SQL - языку PL/SQL.
Взаимосвязь реляционной модели данных, стандарта языка SQL и различных его реализаций можно условно изобразить в виде следующей пирамиды:
Каждый более высокий уровень основывается на понятиях, определенных на более низком уровне. На каждом из уровней используется своя терминология. Например, на уровне теории множеств мы говорим "множество", "подмножество декартового произведения", "кортеж". На уровне реляционной модели используем термины "домен", "отношение", "кортеж". На уровне стандарта SQL и конкретных реализаций используем термины "тип данных", "таблица", "строка таблицы". И каждый раз речь идет об одном и том же.Учебное пособие имеет следующую структуру.
Первая глава содержит небольшое введение в математическую теорию множеств, необходимое для введения фундаментального понятия "отношение".
Следующие три главы содержат описание собственно реляционной модели данных. Во второй главе вводятся базовые понятия реляционной модели данных, такие как "домен", "отношение", "атрибут", "кортеж", "ключ", "внешний ключ". В третьей главе вводится понятие целостности реляционных данных. Даются понятия целостности сущностей и целостности внешних ключей. В четвертой главе описывается язык доступа к реляционным данным - реляционная алгебра.
Пятая глава содержит краткое описание и примеры применения стандартного языка доступа к реляционным данным - языка SQL.
Шестая и седьмая главы посвящены важным вопросам правильного проектирования отношений. В этих главах вводятся нормальные формы отношений. Понятие нормальных форм необходимо для проектирования непротиворечивых и неизбыточных таблиц базы данных.
В восьмой главе описывается альтернативный способ разработки таблиц в нормальной форме - модель "сущность-связь".
Последние три главы посвящены важному для баз данных понятию "транзакция". Понятие транзакции является фундаментальным при рассмотрении таких вопросов как поддержание целостности базы данных, независимой одновременной работы большого количества пользователей, восстановления данных после сбоев системы.
Таблица 1
Кого
Кто |
Вовочка
Петя
Маша
Лена
Вовочка
Любит |
|
|
|
Петя
|
|
Любит |
|
Маша
|
Любит |
Любит |
|
Лена
|
Любит |
|
|
Таблица 1. Матрица взаимоотношенийСпособ 4. При помощи таблицы фактов:
Таблица 1
Номер_сотрудника
Фамилия
Зарплата
Номер_отдела
1 |
Иванов |
1000 |
1 |
2 |
Петров |
2000 |
2 |
3 |
Сидоров |
3000 |
1 |
Таблица 1 Отношение "Сотрудники"
Таблица 1
AND
F
T
U
F
F |
F |
F |
T
F |
T |
U |
U
F |
U |
U |
Таблица 1 Таблица истинности AND
Таблица 1
Табельный номер
Фамилия
Зарплата
1 |
Иванов |
1000 |
2 |
Петров |
2000 |
3 |
Сидоров |
3000 |
Таблица 1 Отношение A
Таблица 1
TNAME
KOL
PRICE
EQU
SUMMA
Болт |
10 |
100 |
= |
1000 |
Гайка |
20 |
200 |
= |
4000 |
Винт |
30 |
300 |
= |
9000 |
Таблица 1
Н_СОТР
ФАМ
Н_ОТД
ТЕЛ
Н_ПРО
ПРОЕКТ
Н_ЗАДАН
1 |
Иванов |
1 |
11-22-33 |
1 |
Космос |
1 |
1 |
Иванов |
1 |
11-22-33 |
2 |
Климат |
1 |
2 |
Петров |
1 |
11-22-33 |
1 |
Космос |
2 |
3 |
Сидоров |
2 |
33-22-11 |
1 |
Космос |
3 |
3 |
Сидоров |
2 |
33-22-11 |
2 |
Климат |
2 |
Таблица 1 Отношение СОТРУДНИКИ_ОТДЕЛЫ_ПРОЕКТЫ
Таблица 1
Номер поставщика
PNUMНаименование поставщика
PNAMEНомер детали
DNUMПоставляемое количество
VOLUME
1 |
Фирма 1 |
1 |
100 |
1 |
Фирма 1 |
2 |
200 |
1 |
Фирма 1 |
3 |
300 |
2 |
Фирма 2 |
1 |
150 |
2 |
Фирма 2 |
2 |
250 |
3 |
Фирма 3 |
1 |
1000 |
Таблица 1 Отношение "Поставки"
Данное отношение содержит два потенциальных ключа - {PNUM, DNUM} и {PNAME, DNUM}. Видно, что данные хранятся в отношении с избыточностью - при изменении наименования поставщика, это наименование нужно изменить во всех кортежах, где оно встречается. Можно ли эту аномалию устранить при помощи алгоритма нормализации, описанного в предыдущей главе? Для этого нужно выявить имеющиеся функциональные зависимости (как обычно, курсивом выделены ключевые атрибуты):
PNUM PNAME - наименование поставщика зависит от номера поставщика.
PNAME PNUM - номер поставщика зависит от наименования поставщика.
{PNUM, DNUM} VOLUME - поставляемое количество зависит от первого ключа отношения.
{PNUM, DNUM} PNAME - наименование поставщика зависит от первого ключа отношения.
{PNAME, DNUM} VOLUME - поставляемое количество зависит от второго ключа отношения.
{PNAME, DNUM} PNUM - номер поставщика зависит от второго ключа отношения.
Данное отношение не содержит неключевых атрибутов, зависящих от части сложного ключа (см. определение 2НФ). Действительно, от части сложного ключа зависят атрибуты PNAME и PNUM, но они сами являются ключевыми. Таким образом, отношение находится в 2НФ.
Кроме того, отношение не содержит зависимых друг от друга неключевых атрибутов, т.к. неключевой атрибут всего один - VOLUME (см. определение 3НФ). Таким образом, показано, что отношение "Поставки" находится в 3НФ.
Таким образом, описанный ранее алгоритм нормализации неприменим к данному отношению. Очевидно, однако, что аномалия данного отношения устраняется путем декомпозиции его на два следующих отношения:
Таблица 1
Dept_Id
Dept_Name
Dept_Kol
1 |
Кафедра алгебры |
3 |
2 |
Кафедра программирования |
2 |
Таблица 1 DEPART
Таблица 1
Транзакция A
Время
Транзакция B
Чтение |
|
--- |
--- |
|
Чтение |
Запись |
|
--- |
--- |
|
Запись |
Фиксация транзакции |
|
--- |
--- |
|
Фиксация транзакции |
Потеря результата обновления
|
|
Результат. После окончания обеих транзакций, строка , занесенное более поздней транзакцией B. Транзакция A ничего не знает о существовании транзакции B, и естественно ожидает, что в строке . Таким образом, транзакция A потеряла результаты своей работы.
Таблица фактовС точки зрения
Таблица 2
Кто любит
Кого любят
Вовочка |
Вовочка |
Петя |
Маша |
Маша |
Петя |
Маша |
Маша |
Лена |
Петя |
Таблица 2 Таблица фактовС точки зрения реляционных баз данных наиболее предпочтительным является четвертый способ, т.к. он допускает наиболее удобный способ хранения и манипулирования информацией. Действительно, перечисление фактов как текстовая форма хранения информации уместна для литературного произведения, но с трудом поддается алгоритмической обработке. Изображение в виде графа наглядно, и его удобно использовать как конечную форму представления информации для пользователя, но хранить данные в графическом виде неудобно. Матрица взаимоотношений уже больше соответствует требованиям информационной системы. Матрица удобна в обработке и компактно хранится. Но одно небольшое изменение, например, появился еще Вася и влюбился в несчастную Лену, требует перестройки всей матрицы, а именно, добавления и колонок, и столбцов. Таблица фактов свободна от всех этих недостатков - при добавлении новых действующих лиц просто добавляются новые строки.
Что касается предиката данного отношения, то он имеет следующий вид (дизъюнктивная нормальная форма):
R(x,y) = {(x = "Вовочка" AND y = "Вовочка") OR (x = "Петя" AND y = "Маша") OR (x = "Маша" AND y = "Петя") OR (x = "Маша" AND y = "Маша") OR (x = "Лена" AND y = "Петя")}
Замечание. Приведенное отношение не является ни транзитивным, ни симметричным или антисимметричным, ни рефлексивным, поэтому оно не является ни отношением эквивалентности, ни отношением порядка, ни каким-либо другим разумным отношением.
Замечание. Большая часть мировой литературы существует и имеет смысл лишь постольку, поскольку бинарное отношение "любить" не является отношением эквивалентности. В частности, по этой причине человечество не разбивается на классы эквивалентности взаимно любящих особей. Изучением характеристик данного отношения и соответствующего ему предиката занималось (и продолжает заниматься) большое количество экспертов, таких как Толстой Л.Н., Шекспир В. и др.
Таблица 2
Реляционный термин
Соответствующий "табличный" термин
База данных |
Набор таблиц |
Схема базы данных |
Набор заголовков таблиц |
Отношение |
Таблица |
Заголовок отношения |
Заголовок таблицы |
Тело отношения |
Тело таблицы |
Атрибут отношения |
Наименование столбца таблицы |
Кортеж отношения |
Строка таблицы |
Степень (-арность) отношения |
Количество столбцов таблицы |
Мощность отношения |
Количество строк таблицы |
Домены и типы данных |
Типы данные в ячейках таблицы |
Таблица 2
OR
F
T
U
F
F |
T |
U |
T
T |
T |
T |
U
U |
T |
U |
Таблица 2 Таблица истинности OR
Таблица 2
Табельный номер
Фамилия
Зарплата
1 |
Иванов |
1000 |
2 |
Пушников |
2500 |
4 |
Сидоров |
3000 |
Таблица 2 Отношение BОбъединение отношений будет иметь вид:
Таблица 2
PNUM
DNUM
VOLUME
1 |
1 |
100 |
2 |
1 |
150 |
3 |
1 |
1000 |
1 |
2 |
200 |
2 |
2 |
250 |
1 |
3 |
300 |
Таблица 2
Н_СОТР
ФАМ
Н_ОТД
ТЕЛ
1 |
Иванов |
1 |
11-22-33 |
2 |
Петров |
1 |
11-22-33 |
3 |
Сидоров |
2 |
33-22-11 |
Таблица 2 Отношение СОТРУДНИКИ_ОТДЕЛЫ
Отношение ПРОЕКТЫ (Н_ПРО, ПРОЕКТ):
Функциональные зависимости:
Н_ПРО ПРОЕКТ
Таблица 2
Номер поставщика
PNUM
Наименование поставщика
PNAME
1
Фирма 1
2
Фирма 2
3
Фирма 3
Таблица 2 Отношение "Поставщики"
Таблица 2
Pers_Id
Pers_Name
Dept_Id
1 |
Иванов |
1 |
2 |
Петров |
2 |
3 |
Сидоров |
1 |
4 |
Пушников |
2 |
5 |
Шарипов |
1 |
Таблица 2 PERSONОграничение целостности этой базы данных состоит в том, что поле Dept_Kol не может заполняться произвольными значениями - это поле должно содержать количество сотрудников, реально числящихся в подразделении.
С учетом этого ограничения можно заключить, что вставка нового сотрудника в таблицу не может быть выполнена одной операцией. При вставке нового сотрудника необходимо одновременно увеличить значение поля Dept_Kol:
Таблица 2
Транзакция AВремяТранзакция B
--- |
|
Чтение |
--- |
|
Запись |
Чтение |
|
--- |
Работа с прочитанными данными |
|
--- |
--- |
|
Откат транзакции |
Фиксация транзакции |
|
--- |
Работа с "грязными" данными
|
|
С чем же работала транзакция A?
Результат. Транзакция A в своей работе использовала данные, которых нет в базе данных. Более того, транзакция A использовала данные, которых нет, и не было в базе данных! Действительно, после отката транзакции B, должна восстановиться ситуация, как если бы транзакция B вообще никогда не выполнялась. Таким образом, результаты работы транзакции A некорректны, т.к. она работала с данными, отсутствовавшими в базе данных.
Для того чтобы отразить факты
Таблица 3
A (Преподаватель)
B (Предмет)
Q (Количество часов)
Пушников |
Алгебра |
40 |
Пушников |
Базы данных |
80 |
Цыганов |
Геометрия |
50 |
Шарипов |
Алгебра |
40 |
Шарипов |
Геометрия |
50 |
Таблица 3 Отношение "Читает лекции по…"
Для того чтобы отразить факты 4-6 (характеризующие посещение студентами лекций), введем отношение . Упорядоченная тройка посещает лекции по предмету . Назовем это отношение "Посещать лекции". Его также представим в виде таблицы:
Таблица 3
Таблица 3 Таблица истинности NOTИмеется несколько парадоксальных следствий применения трехзначной логики.
Парадокс 1. Null-значение не равно самому себе. Действительно, выражение null = null дает значение не ИСТИНА, а НЕИЗВЕСТНО. Значит выражение Парадокс 2. Неверно также, что null-значение не равно самому себе! Действительно, выражение null тоже не обязательно ЛОЖЬ!
Парадокс 3. Таких парадоксов можно построить сколько угодно. Конечно, это на самом деле не парадоксы, а просто следствия из аксиом трехзначной логики.
Таблица 3
Табельный номер
Фамилия
Зарплата
1 |
Иванов |
1000 |
2 |
Петров |
2000 |
3 |
Сидоров |
3000 |
2 |
Пушников |
2500 |
4 |
Сидоров |
3000 |
Таблица 3 Отношение A UNION BЗамечание. Как видно из приведенного примера, потенциальные ключи, которые были в отношениях не наследуются объединением этих отношений. Поэтому, в объединении отношений атрибут "Табельный номер" может содержать дубликаты значений. Если бы это было не так, и ключи наследовались бы, то это противоречило бы понятию объединения как "объединение множеств". Конечно, объединение отношений имеет, как и любое отношение, потенциальный ключ, например, состоящий из всех атрибутов.
Таблица 3
PNUM
DNUM
VOLUME
3 |
1 |
1000 |
2 |
1 |
150 |
1 |
1 |
100 |
2 |
2 |
250 |
1 |
2 |
200 |
1 |
3 |
300 |
Замечание. Если явно не указаны ключевые слова ASC или DESC, то по умолчанию принимается упорядочение по возрастанию (ASC).
Таблица 3
Н_ПРО
ПРОЕКТ
1 |
Космос |
2 |
Климат |
Таблица 3 Отношение ПРОЕКТЫ
Отношение ЗАДАНИЯ (Н_СОТР, Н_ПРО, Н_ЗАДАН):
Функциональные зависимости:
{Н_СОТР, Н_ПРО} Н_ЗАДАН
Таблица 3
Номер поставщика
PNUMНомер детали
DNUMПоставляемое количество
VOLUME
1 |
1 |
100 |
1 |
2 |
200 |
1 |
3 |
300 |
2 |
1 |
150 |
2 |
2 |
250 |
3 |
1 |
1000 |
Таблица 3 Отношение "Поставки-2"
Таблица 3
Наиме-нование атрибута |
Описание атрибута |
Базовый ли атрибут
Формула для вычислимого атрибута |
Name |
Наименование товара |
Да |
|
N |
Количество |
Да |
|
P1 |
Учетная цена товара |
Да |
|
S1 |
Учетная сумма на все количество |
|
S1 = N*P1 |
PerSent |
Процент наценки на единицу товара |
Да |
|
P2 |
Наценка на единицу товара |
|
P2 = P1*PerSent/100 |
S2 | Сумму наценки на все количество |
|
S2 = N*P2 |
P3 |
Цену товара с учетом наценки |
|
P3 = P1+P2 |
S3 |
Сумму на все количество с учетом наценки |
|
S3 = N*P3 |
NDS |
Процент НДС |
Да |
|
P4 |
Сумма НДС на единицу товара |
|
P4 = P2*NDS/100 |
S4 |
Сумма НДС на все количество |
|
S4 = N*P4 |
P5 |
Цена товара с НДС |
|
P5 = P3+P4 |
S5 | Сумма на все количество с НДС |
|
S5 = N*P5 |
Таблица 3 Атрибуты товара
Базовыми, т.е. требующими ввода данных являются всего 5 атрибутов (выделены серым цветом). Все остальные атрибуты вычисляются по базовым. Нужно ли хранить в отношении только базовые атрибуты, или желательно хранить все атрибуты, пересчитывая значения вычислимых атрибутов каждый раз при изменении базовых?
Решение 1. Пусть в отношении решено хранить только базовые атрибуты.
Достоинства решения:
Структура отношения полностью неизбыточна.
Не требуется дополнительного программного кода для поддержания целостности кортежа.
Экономится дисковое пространство.
Уменьшается трафик сети.
Недостатки решения:
В бухгалтерии для формирования проводок используются, как правило, не базовые, а вычислимые атрибуты. Одни и те же формулы используются во многих местах, поэтому все операторы отбора данных будут содержать одинаковые фрагменты кода с одними и теми же формулами. Имеется риск в разных местах вычислять одни и те же данные по разным формулам.
При изменении логики вычислений (что бывает довольно часто при изменении законодательства), необходимо изменить одни и те же фрагменты кода во всех местах, где они встречаются. Это сильно затрудняет модификацию приложений.
Если возникает нерегламентированный запрос, то человек, формулирующий запрос должен помнить все эти формулы.
Решение 2. Предположим, что в отношении решено хранить все атрибуты, в том числе и вычислимые.
Достоинства решения:
Код, поддерживающий целостность кортежа (и содержащий формулы для вычислимых атрибутов), хранится в одном месте, например в триггере, связанном с данным отношением.
При изменении логики вычислений, изменения в формулы требуется внести только в одном месте (в триггере).
Запросы к базе данных содержат меньше формул и поэтому более просты.
Легче формулировать нерегламентированные запросы, т.к. в запросе используются атрибуты, имеющие для бухгалтера конкретный смысл.
Недостатки решения:
При изменении логики расчета надобность в некоторых атрибутах может исчезнуть, зато может появиться потребность в новых атрибутах. Это потребует перестройки структуры отношения, что является весьма болезненной операцией для работающей системы.
Структура отношения становится более сложной и запутанной.
Увеличивается объем базы данных.
Увеличивается трафик сети.
Как видим, оба решения имеют свои достоинства и недостатки. Важно то, что программный код, содержащий эти формулы, не исчезает ни в каком из этих решений (да и куда он денется, раз такова предметная область!). Только в одном случае код хранится в одном месте, а в другом может быть "размазан" по всему приложению.
На самом деле данный пример сильно упрощен, т.к. еще одной неприятной особенностью наших бухгалтерий является то, что все расчеты должны вестись с определенной точностью, а именно - до копеек. Возникает проблема округления, а это еще более усложняет формулы для расчетов цен. Простой пример - вычисление НДС содержит операцию деления, следовательно может приводить к бесконечным дробям типа 15,519999… Такую дробь необходимо округлить до 15.52. Если продается одна единица товара, то это не страшно, но если продается несколько единиц товара, то сумму НДС на все количество можно считать по разным формулам:
S4 = N* ROUND(P2*NDS/100) - СНАЧАЛА округлить при вычислении НДС на единицу товара, а ПОТОМ умножить на все количество, или
S4 = ROUND(N*P2*NDS/100) - СНАЧАЛА умножить на все количество, а ПОТОМ округлить до требуемого знака.
Лирическое отступление. Автор, как математик по образованию (к.ф.-м.н.), считает, что верной, безусловно, является первая формула. Действительно, вычисляя по первой формуле, мы получим одну и ту же сумму НДС независимо от того, продали мы одну партию товара, содержащую 50 единиц, или продали 50 партий по одной единице в каждой. При вычислениях по второй формуле сумма НДС в партии, состоящий из 50 единиц товара отличается от суммы НДС по 50 партиям по одной единице товара в каждой. Разработав несколько складских программ, автор получал разные ответы на этот вопрос в разных бухгалтерия, разные ответы на этот вопрос в одной бухгалтерии в разное время, и разные ответы на этот вопрос в разных налоговых инспекциях. В конечном итоге, автор пришел к грустному выводу, что для того, чтобы стать бухгалтером, его способностей и образования недостаточно.
Другие решения. Можно попытаться использовать и другие решения, для облегчения разработки и сопровождения в данном случае. Например, можно хранить в базовом отношении только базовые атрибуты, а для работы бухгалтерии использовать заранее подготовленные представления (динамические отношения, задаваемые оператором SQL). Тогда логика расчетов будет храниться в одном SQL-операторе, определяющем это представление. Другим вариантом может быть сохранение формул в виде хранимых процедур и функций базы данных.
Проверка ограничения. К моменту проверки ограничения кортежа должны быть проверены ограничения целостности атрибутов, входящих в этот кортеж.
Ограничение кортежа является немедленно проверяемым ограничением. Действительно, ограничение кортежа не зависит ни от каких других объектов базы данных, кроме атрибутов, входящих в состав кортежа. Поэтому никакие изменения в других объектах не могут повлиять на истинность ограничения.
Таблица 3
Транзакция A
Время
Транзакция B
Чтение |
|
--- |
--- |
|
Чтение |
--- |
|
Запись |
--- |
|
Фиксация транзакции |
Повторное чтение |
|
--- |
Фиксация транзакции |
|
--- |
Неповторяемое считывание
|
|
Транзакция A ничего не знает о существовании транзакции B, и, т.к. сама она не меняет значение в строке, то ожидает, что после повторного чтения значение будет тем же самым.
Результат. Транзакция A работает с данными, которые, с точки зрения транзакции A, самопроизвольно изменяются.
показывает текущее состояние учебного процесса.
Таблица 4
C (студент)
B (предмет)
A (Преподаватель)
Иванов |
Алгебра |
Шарипов |
Иванов |
Базы данных |
Пушников |
Петров |
Алгебра |
Пушников |
Петров |
Геометрия |
Цыганов |
Сидоров |
Геометрия |
Цыганов |
Сидоров |
Базы данных |
Пушников |
Таблица 4 Отношение "Посещать лекции"
Рассмотрим отношение . Это произведение, содержащее 3*3*3=27 кортежей, можно назвать "Студенты-Лекции-Преподаватели". Множество показывает текущее состояние учебного процесса. Очевидно, что отношение Итак, факты о ходе учебного процесса удалось отразить в виде двух отношений третьей степени (3-арных), а сами отношения изобразить в виде таблиц с тремя колонками.
Удобство использования табличной формы для задания отношения определяется в данном случае следующими факторами:
Все используемые множества конечны.
При добавлении или удалении студентов, предметов, преподавателей просто добавляются или удаляются соответствующие строки в таблице.
Нас сейчас не интересует вопрос, хороши ли полученные отношения. Заметим пока только, что, как показывают следующие замечания, не любую строку можно добавить в таблицу "Посещать лекции".
Замечание. В таблицу "Посещать лекции" нельзя добавить две одинаковые строки, т.к. таблица изображает отношение синтаксического ограничения - такое ограничение задано в определении понятия отношение (одинаковых строк не может быть ни в одной таблице, задающей отношение).
Замечание. В таблицу "Посещать лекции" нельзя добавить кортеж (Иванов, Геометрия, Пушников). Действительно, из таблицы "Читает лекции по…", представляющей отношение семантического ограничения - такое ограничение является следствием нашей трактовки данных, хранящихся в отношении (следствием понимания смысла данных).
Таблица 4
Табельный номер
Фамилия
Зарплата
1 |
Иванов |
1000 |
2 |
Петров |
2000 |
3 |
Сидоров |
3000 |
Таблица 4 Отношение "Сотрудники" При первом взгляде на таблицу, изображающую это отношение, может показаться, что в таблице имеется три потенциальных ключа - в каждой колонке таблицы содержатся уникальные данные. Однако среди сотрудников могут быть однофамильцы и сотрудники с одинаковой зарплатой. Табельный же номер по сути свой уникален для каждого сотрудника. Какие же соображения привели нас к пониманию того, что в данном отношении только один потенциальный ключ - "Табельный номер"? Именно понимание смысла данных, содержащихся в отношении.
Попробуем представить это отношение в другом виде, изменив наименования атрибутов:
Таблица 4
Табельный номер
Фамилия
Зарплата
1 |
Иванов |
1000 |
Таблица 4 Отношение A INTERSECT BЗамечание. Казалось бы, что в отличие от операции объединения, потенциальные ключи могли бы наследоваться пересечением отношений. Однако это не так. Вообще, никакие реляционные операторы не передают результатирующему отношению никаких данных о потенциальных ключах. В качестве причины этого можно было бы привести тривиальное соображение, что так получается более просто и симметрично - все операторы устроены одинаково. На самом деле причина более глубока, и заключается в том, что потенциальный ключ - семантическое понятие, отражающее различимость объектов предметной области. Наличие потенциальных ключей не выводится из структуры отношения, а явно задается для каждого отношения, исходя из его смысла. Реляционные же операторы являются формальными операциями над отношениями и выполняются одинаково, независимо от смысла данных, содержащихся в отношениях. Поэтому, реляционные операторы ничего не могут "знать" о смысле данных. Трактовка результата реляционных операций - дело пользователя.
Таблица 4
PNUM
PNAME
DNUM
VOLUME
1 |
Иванов |
1 |
100 |
1 |
Иванов |
2 |
200 |
1 |
Иванов |
3 |
300 |
2 |
Петров |
1 |
150 |
2 |
Петров |
2 |
250 |
3 |
Сидоров |
1 |
1000 |
Замечание. Соединяемые таблицы перечислены в разделе FROM оператора, условие соединения приведено в разделе WHERE. Раздел WHERE, помимо условия соединения таблиц, может также содержать и условия отбора строк.
Таблица 4
Н_СОТР
Н_ПРО
Н_ЗАДАН
1 |
1 |
1 |
1 |
2 |
1 |
2 |
1 |
2 |
3 |
1 |
3 |
3 |
2 |
2 |
Таблица 4 Отношения ЗАДАНИЯ
Таблица 4
Номер поставщика
PNUMНаименование поставщика
PNAME
1
Фирма 1
2
Фирма 2
3
Фирма 3
Таблица 4 Отношение "Поставщики"
Таблица 4
X
Y
1 |
Aa |
1 |
Bb |
2 |
Cc |
2 |
Dd |
3 |
Ee |
3 |
Ff |
Таблица 4 таблица A (Родительская)
Таблица 4
Транзакция A
Время
Транзакция B
Выборка строк, удовлетворяющих условию (Отобрано n строк) |
|
--- |
--- |
|
Вставка новой строки, удовлетворяющей условию |
--- |
|
Фиксация транзакции |
Выборка строк, удовлетворяющих условию (Отобрано n+1 строк) |
|
--- |
Фиксация транзакции |
|
--- |
Появились строки, которых раньше не было
|
|
Транзакция A ничего не знает о существовании транзакции B, и, т.к. сама она не меняет ничего в базе данных, то ожидает, что после повторного отбора будут отобраны те же самые строки.
Результат. Транзакция A в двух одинаковых выборках строк получила разные результаты.