Автоматическая генерация схемы реляционной базы данных на основе объектной схемы данных Богданов Алексей Современные языки программирования Язык Индекс* ∆ 1 Java 19.711% +2.20% 2 C 15.262% -2.02% 3 C++ 8.754% -0.86% 4 C# 7.210% +2.95% 5 PHP 6.566% -3.34% 6 Python 5.737% +1.51% 7 (Visual) Basic 4.710% -1.86% 8 Objective-C 3.518% +1.55% 9 Perl 1.969% -1.85% 10 JavaScript 1.866% -0.78% * TIOBE Programming Community Index, март 2011 Объектная модель данных • Один из наиболее популярных классов ЯП – объектно-ориентированные языки со строгой типизацией • Модель данных – Аспект структуры – Аспект манипуляции – Аспект целостности • Объектная модель данных – Класс – Ассоциация, агрегация, наследование – Строгая типизация • Каждый объект имеет определенный тип • Для любой операции определяются типы входных и выходных параметров Функции СУБД • Функции, предоставляемые СУБД – Управление данными во внешней и оперативной памяти – Журнализация изменений, резервное копирование и восстановление данных – Поддержка языков БД (SQL) • Основные требования: – Надежность, устойчивость – Производительность – Многозадачность • Наиболее популярные СУБД основаны на реляционной модели данных Проблема объектнореляционного отображения Интерфейс БД • Объектная модель – во время выполнения приложения • Реляционная модель – для использования функциональности СУБД Интерфейс БД Интерфейс БД • Может быть определен в терминах объектной модели • Может быть строго типизированным Содержание доклада • Существующие подходы к решению проблемы объектно-реляционного отображения • Интерфейсы доступа к СУБД • Подход к решению проблемы объектнореляционного отображения на основе генерации схемы реляционной БД по объектной схеме данных – – – – Абстракция реляционной модели данных Строгая типизация на уровне структур данных Строгая типизация запросов к данным Производительность РСУБД Прямой доступ к СУБД, SQL • SQL-запрос – это текст SELECT * FROM Users WHERE Id = 1000 • Отсутствует строгая типизация запроса • Отсутствует строгая типизация результата Средства ОР-отображения • Необходимость задавать и поддерживать описание отображения • Пример: Hibernate LINQ2SQL • Средство ОР-отображения в .NET Framework • Основное преимущество: строго типизированные запросы. • Пример: var users = from usr in context.Users where usr.Name.Contains("A") orderby usr.Id select usr; ООСУБД • Отсутствует необходимость в ОР-отображении • Строгая типизация структур данных • Строгая типизация запросов • Недостатки: ограниченные средства доступа к данным, производительность • Пример: Db4Objects Выводы • Идеальный интерфейс: – Абстракция реляционной модели – Строго типизированные структуры данных – Строго типизированные запросы, задаваемые в терминах ЯП – Абстракция конкретной реализации хранилища • При этом остаются требования к устойчивости, производительности и другие свойства классических РСУБД (ОРСУБД) Схема хранимых данных • Выделение схемы хранимых данных • Объектная строго типизированная схема данных • Модель хранимых данных является подмножеством объектной модели [DbEntity] public class Author : DbEntity { [DbField(IsIndex = true)] public string Name { get; set; } [DbField] public string City { get; set; } } public class DbEntity { public long Id { get; set; } } Схема хранимых данных 2 • Ссылки на другие сущности схемы [DbEntity] public class Author : DbEntity { // … [DbLink(“AuthorPapers")] public IEnumerable<Paper> Papers { get; set; } } [DbEntity] public class Paper : DbEntity { // ... [DbLink(“AuthorPapers")] public Author Author { get; set; } } Интерпретация схемы по соглашению • Если задать некоторый набор соглашений, можно избавиться от атрибутов элементов схемы данных • Примеры соглашений: – Первичный ключ: Id или [ИмяКласса]Id – Все поля простых типов – хранимые поля – Соглашения для ссылок: название поля [ИмяКласса]s или [ИмяКласса]. • Microsoft Entity Framework 4.1 Интерфейс БД. Типовое решение Репозиторий Интерфейс БД. Типовое решение Единица работы • Аккумуляция изменений – Добавление объектов – Изменение объектов – Удаление объектов • Управление транзакциями – Откат транзакции Репозиторий + Единица работы = Контекст БД • Объекта «контекста БД» достаточно для выполнения любых операций над хранимыми данными public interface IDbContext { IQueryable<T> Get<T>() where T : DbEntity, new(); void Store<T>(T entity) where T : DbEntity, new(); void Delete<T>(T entity) where T : DbEntity, new(); void Commit(); void Rollback(); } Деревья запросов • IQueryable = дерево запроса + провайдер var names = from author in context.Get<Author>() where author.Name.Length > 10 orderby author.Id select author.Name; Get<Author>() where orderby select Length > 10 usr.Id usr.Name Архитектура системы Локальный сервис Удаленный сервис Приложение Схема данных Схема хранимых данных Конкретные хранилища данных Реализация хранилищ. РСУБД • Реализация хранилища – Отображение объектной схемы на схему БД – Реализация провайдера для выполнения запросов в виде деревьев выражений – Реализация других операций над данными • Использование существующих РСУБД (ОРСУБД) Отображение объектной схемы на реляционную схему • Автоматическая генерация схемы БД: – Преобразование описания объектной схемы в инструкции языка реляционных БД (SQL DDL) [DbEntity] public class Author : DbEntity { [DbField(IsIndex = true)] public string Name { get; set; } [DbField] public string City { get; set; } } CREATE TABLE Authors ( Id bigint PRIMARY KEY IDENTITY, Name varchar(50), City varchar(50) ); CREATE INDEX IX_Authors_Name ON Authors(Name); Реализация хранилища в памяти • Во время сеанса работы все данные хранятся в памяти в виде коллекций объектов • Между сеансами данные сохраняются в линейный файл (например, XML) • Реализация индексов – дополнительные структуры данных в памяти в виде хэштаблиц или деревьев • Во время выполнения – преобразование деревьев запросов для использования индексов Имитация реальной БД Приложение Слой данных IAuthorStorage AuthorStorageMock IPaperStorage AuthorStorageDB Основной код приложения СУБД Имитация БД. Преимущества • Не требуется специальной процедуры развертывания СУБД • Каждый разработчик имеют свою копию данных. • Изменение схемы БД сразу отражается в схеме данных, которая описана в коде, что не приводит к конфликтным данным. • Возможность просто восстанавливать начальные данные для использования в модульных тестах. Версионность модели • Поддержка версионности – корректная обработка ситуации, когда схема изменяется между запусками приложения • Простая схема для поддержания версионности: считать измененный класс новым классом • Реализация: идентификация по имени класса и значению хэш-функции от структуры класса • Возможность миграции данных в обновленную схему Спасибо за внимание! Алексей Богданов alxbog@gmail.com