В реляционной модели данные представлены в табличной форме, в то время как в объектно-ориентированных языках данные хранятся в виде графов объектов, что порождает целый ряд трудностей, когда дело доходит до преобразования объектов в табличную форму и наоборот: разные представление связей между зависимыми данными, отсутствие наследования в реляционном мире, несовпадение способов проверки идентичности и тд. (читай The Object-Relational Impedance Mismatch). Даже если программист решит вопрос преобразования, то перед ним возникнет проблема поддержки данных в базе и в оперативной памяти приложения в согласованном состоянии.
Во избежание вышеперечисленных и прочих проблем были разработаны технологии объектно-реляционного отображения (Object-Relational Mapping, ORM), реализующих в себе десятки шаблонов по преобразованию данных, отслеживанию изменений в объектах, реализации ленивой загрузки, кешированию, генерированию SQL запросов и тд. Программист получает возможность значительно быстрее разработать слой доступа к данным, как и возможность абстрагироваться от СУБД и работать только с объектами в оперативной памяти как с единственным хранилищем данных. Однако максимально полное абстрагирование может быть достигнуто только при работе над небольшими и слабонагруженными приложениями. В сложных проектах ORM является дополнением к SQL знаниям разработчика, а не их полной заменой.
В .NET к основным технологиям ORM относятся Entity Framework и HNibernate. Активное использование ORM при работе с огромными наборами данных может негативно отразиться на производительности разрабатываемого приложения. В таких случаях программисты могут использовать ORM для основной части системы, но для критически важных участков перейти на вызовы хранимых процедур и ручное написание SQL запросов. Другим возможным вариантом оптимизации может служить разделение приложения на 2 отдельных модуля. Первый модуль предназначен для записи данных в базу, в котором продолжает работать ORM. Второй — для чтения данных из базы, в котором работают микро ORM (Dapper или ORMLite), либо класcы ADO.NET (SqlConnection, SqlCommand и тд). Если к приложению изначально предъявляются максимально высокие требования к быстродействию со стороны чтения и записи, то в отдельных случаях использование классических ORM избегают вовсе.
Вопросы
- Как смоделировать отношение многие-ко-многим в объектной модели?
- Какая разница между подходами Code First и Database First в Entity Framework?
- Как решить проблему N+1 в Entity Framework?
- Какая разница между интерфейсами IEnumerable и IQueryable?
- Какое предназначение у шаблона Unit Of Work?
- Какую проблему решает шаблон Repository?
- В чем отличие между шаблонами Query Object и Specification?
- В чем заключаются недостатки шаблона Active Record?
- В чем идея алгоритма Hi/Lo?
Книги
- Архитектура корпоративных программных приложений — Мартин Фаулер, Дейвид Райс, Мэттью Фоммел, Эдвард Хайет, Роберт Ми, Рэнди Стаффорд
- Programming Entity Framework: Code First — Julia Lerman, Rowan Miller