1. Транзакции Неделимой операцией в БД считается выполнение одного SQL-запроса (может быть, включающего выполнение хранимой процедуры, исполнение каскадных действий и триггеров). На самом деле можно рассматривать три режима исполнения предложений: 1. Автоподтверждение (транзакцией является каждое предложение, как описано выше). 2. Неявное начало транзакций, явное подтверждение. 3. Явное начало и подтверждение транзакций. MS SQL Server: 1. BEGIN TRANSACTION – явное начало транзакции 2. COMMIT TRANSACTION – завершение транзакции 3. ROLLBACK TRANSACTION – отмена транзакции 4. SET IMPLICIT_TRANSACTIONS ON | OFF – включение/выключение режима неявного начала транзакций Базы данных: учебный курс Примеры 1. Нужно однократно исполнить несколько предложений в рамках одной транзакции. BEGIN TRANSACTION INSERT Tab1 (Field1, Field2) VALUES ('Val1', 'Val2') INSERT Tab1 (Field1, Field2) VALUES ('Val3', 'Val4') COMMIT TRANSACTION 2. Хочется явно отмечать конец каждой транзакции, не задавая явно ее начало каждый раз. SET IMPLICIT_TRANSACTIONS ON INSERT Tab1 (Field1, Field2) VALUES ('Val1', 'Val2') INSERT Tab1 (Field1, Field2) VALUES ('Val3', 'Val4') COMMIT TRANSACTION INSERT Tab1 (Field1, Field2) VALUES ('Val5', 'Val6') INSERT Tab1 (Field1, Field2) VALUES ('Val7', 'Val8') COMMIT TRANSACTION SET IMPLICIT_TRANSACTIONS OFF Базы данных: учебный курс Вложенные транзакции BEGIN TRANSACTION {SQL-предложение 1} {SQL-предложение 2} BEGIN TRANSACTION {SQL-предложение 3} IF (условие) THEN {SQL-предложение 4} COMMIT TRANSACTION ELSE ROLLBACK TRANSACTION {SQL-предложение 5} COMMIT TRANSACTION Базы данных: учебный курс Транзакции в JDBC Управление режимом транзакций – методы интерфейса Connection Connection conn = DriverManager.getConnection(...); conn.setAutoCommit(false); for(int i = 0; i < 10; ++i) { insertData(someTable, someData); updateData(someOtherTable, someOtherData); conn.commit(); } conn.setAutoCommit(true); Базы данных: учебный курс JDBC – отмена транзакции Connection conn = DriverManager.getConnection(...); conn.setAutoCommit(false); try { for (int i = 0; i < 10; ++i) { insertData(someTable, someData); } } catch (Exception x) { conn.rollback(); } finally { conn.commit(); } conn.setAutoCommit(true); Базы данных: учебный курс Механизм «точек состояния» в JDBC Вместо вложенных транзакций в JDBC можно использовать «точки состояния». Savepoint svp1 = conn.setSavepoint("name1"); Объекты типа Savepoint обладают числовым идентификатором и могут иметь имя. String s = svp1.getSavepointName(); int id = svp1.getSavepointId(); Создадим внутри выполняемой транзакции две точки сохранения. Savepoint svp1 = conn.setSavepoint(); Savepoint svp2 = conn.setSavepoint(); Тогда можно выполнить следующие действия: conn.rollback(svp1); // откат транзакции к svp1; // svp2 "освобождается" conn.commit(); // все точки сохранения освобождаются conn.releaseSavepoint(svp2); // "освобождение" точки svp2 conn.rollback(); // отмена транзакции и освобождение всех svp Базы данных: учебный курс Уровни поддержки изолированности транзакций Запросить уровень поддержки изолированности транзакции можно так: int level = conn.getTransactionIsolation(); Connection.TRANSACTION_NONE – транзакции не поддерживаются; Connection.TRANSACTION_READ_UNCOMMITTED – транзакции поддерживаются, но при чтении данных одной транзакцией могут быть видны результаты работы незавершенной другой транзакции. Connection.TRANSACTION_READ_COMMITTED – транзакции поддерживаются и результаты работы транзакций не видны извне, пока транзакция не завершена. Connection.TRANSACTION_REPEATABLE_READ Connection.TRANSACTION_SERIALIZABLE Можно попробовать установить желаемый уровень изолированности: conn.setTransactionIsolation(Connection.TRANSACTION_SERIALIZABLE); Базы данных: учебный курс 2. Права пользователей Поддержка прав пользователей ведется только на уровне самой БД, В JDBC нет никаких средств для работы с правами пользователей. Основные понятия: 1. Право на определенное действие с определенным объектом; 2. Роль – совокупность прав; 3. Пользователь (user) – исполнитель некоторой совокупности ролей; 4. Креденциал (login + password) – право на вход в систему под именем того или иного пользователя. Примеры: 1. Право вставлять (INSERT) новые записи в определенную таблицу; право добавлять (CREATE) новые таблицы в базу данных (database). 2. Владелец БД (owner); Администратор БД (admin); Программист. 3. Иванов – программист и руководитель проектов; Петров – тестировщик. 4. sa – имя администратора БД; dbo – стандартное имя владельца. Базы данных: учебный курс Передача и отзыв прав Есть несколько SQL-предложений, позволяющих передать или отозвать определенные права пользователям или ролям. Разумеется, для того, чтобы можно было исполнить такое SQL-предложение, исполнитель должен обладать правом на передачу прав. Примеры: GRANT SELECT ON OBJECT::projects TO vasja WITH GRANT OPTION GRANT EXECUTE ON OBJECT::myproc TO programmer REVOKE EXECUTE ON OBJECT::myproc FROM programmer CASCADE REVOKE ALTER ON OBJECT::projects FROM programmer Базы данных: учебный курс 3. Нормализация данных Основная задача – облегчить поддержание целостности данных. Проблемы: • При изменении одной записи может потребоваться внести изменения и в другие, вообще говоря, независимые от нее записи. • При удалении данных может быть удалена информация, которую, вообще говоря, желательно было оставить. • При добавлении данных может потребоваться вводить неопределенные значения, необходимость которых сомнительна. Говорят, что в БД могут иметь место «аномалии изменения», «аномалии добавления» и «аномалии удаления». Дополнительные цели, преследуемые нормализацией: 1. Уменьшить объем таблиц, исключив дублирование данных. 2. Обеспечить быстрый доступ к данным, упростив их структуру. Базы данных: учебный курс Пример аномалий при изменении данных Рассмотрим таблицу участия программистов в проекте: Проект Участник Роль Процент Дата начала Руководитель P1 Вася Инженер 70 2006-10-20 Иванов P1 Петя Тестер 100 2006-10-20 Иванов P2 Сережа Инженер 70 2007-02-15 Петров P2 Вася Инженер 20 2007-02-15 Петров Аномалия изменения: При изменении «Вася» на «Василий» требуется отследить все вхождения «Васи» в атрибуте «Участник» и, возможно, «Руководитель». Аномалия добавления: При добавлении нового проекта необходимо определить хотя бы одного участника проекта или оставить некоторые поля неопределенными. Аномалия удаления: При удалении «Пети» как участника проекта «P1» исчезает информация и о самом сотруднике и о роли «Тестер». Базы данных: учебный курс Нормальные формы и разделение таблиц Процесс нормализации – это, в основном, процесс разделения таблиц на независимые таблицы без потери информации. «Без потери информации» означает, что исходную таблицу всегда можно восстановить, выполнив некоторое «соединение» (JOIN) получившихся В результате разделения меньших таблиц. Разделение таблиц приводит к: • уменьшению зависимости между элементами одной записи; • уменьшению размеров самих таблиц; • уменьшению количества дублирующей информации; • увеличению гибкости в формировании результатов запросов. Различают несколько «нормальных форм» данных, которые определяются, прежде всего, уровнем зависимости между значениями атрибутов в одной таблице (или записи). • 1НФ; 2НФ; 3НФ; НФБК – традиционные, хорошо изученные НФ; • 4НФ; 5НФ – формы, введенные для того, чтобы избежать некоторых достаточно редких аномалий; • 6НФ; 7НФ – крайне редко используемые нормальные формы. Базы данных: учебный курс Первая нормальная форма Первая нормальная форма: атрибуты атомарны и каждая таблица имеет по крайней мере один потенциальный ключ. Формально в реляционных БД данные всегда находятся в 1НФ, однако, на практике возможны следующие ситуации, когда все же требуется некоторое «приведение» к 1НФ: • в таблице имеются повторяющиеся записи (надо либо удалить дубликаты, либо правильно проидентифицировать их. Фамилия Должность Фамилия Должность Иванов Инженер Иванов Инженер Петров Инженер Петров Инженер Иванов Инженер Номер Фамилия Базы данных: учебный курс Должность 1 Иванов Инженер 2 Петров Инженер 3 Иванов Инженер Первая нормальная форма Еще одна ситуация, когда требуется приведение к 1НФ: • в таблице имеются составные атрибуты. Фамилия Телефон Фамилия Телефон Иванов 232-22-33 Иванов 232-22-33 Петров 434-52-52 556-53-27 Петров 434-52-52 Петров 556-53-27 На практике это не всегда «правильное» преобразование. В данном случае разделение атрибутов привело к дублированию данных. Базы данных: учебный курс Вторая нормальная форма Данные находятся во второй НФ, если они: • находятся в 1НФ; • никакой атрибут не находится в полной функциональной зависимости от первичного ключа. Фамилия Должность Зарплата Иванов Программист 4000 Петров Руководитель 5000 Сидоров Дворник 3000 Петров Программист 4000 Фамилия Должность Первичный ключ – Фамилия + Должность; Зависимость: Должность Зарплата Должность Зарплата Иванов Программист Программист 4000 Петров Руководитель Руководитель 5000 Сидоров Дворник Дворник 3000 Петров Программист Базы данных: учебный курс Третья нормальная форма Данные находятся в третьей НФ, если они: • находятся во 2НФ; • Всякий неключевой атрибут находится в функциональной зависимости только от первичного ключа. ID Фамилия Комната Телефон 1 Иванов 13 336-7540 2 Петров 13 336-7540 3 Сидоров 15 336-7542 Первичный ключ – ID; Зависимость: Комната Телефон ID Фамилия Комната 1 Иванов 13 13 336-7540 2 Петров 13 15 336-7542 3 Сидоров 15 Базы данных: учебный курс Комната Телефон Нормальная форма Бойса-Кодда Данные находятся в НФБК, если они: • находятся в 3НФ; • нет неключевых атрибутов, находящихся в функциональной зависимости от отдельных полей первичного ключа. ID Фамилия Проект Потенциальный ключ – ID + Проект Зависимость: ID Фамилия Роль 1 Иванов 13 Руководитель 2 Петров 13 Программист 1 Иванов 15 Программист ID Фамилия ID Проект 1 Иванов 1 13 Руководитель 2 Петров 2 13 Программист 1 15 Программист Базы данных: учебный курс Роль Заключение • • • Обычно полагают, что данные «хорошо нормализованы», если они находятся в НФБК (которую часто называют третьей НФ); Иногда требуется приведение к нормальным формам более высокого порядка (удаление более сложных зависимостей для облегчения поддержания целостности данных); Часто носле нормализации БД разбивается на большое количество таблиц с маленьким числом атрибутов. Это не всегда удобно, так как требует составления сложных запросов для извлечения данных. Если поддерживать целостность не слишком сложно (например, путем определения подходящих триггеров), то иногда имеет смысл провести денормализацию данных. Базы данных: учебный курс