Проблемы идентификации сущностей
Если этих проблем недостаточно, поговорим еще об одной проблеме, проблеме идентификации объектов и отношений. Как отмечалось выше, в объектных системах используется неявная форма идентификации, обычно основанная на расположении объекта в памяти (вездесущий указатель this). Это иногда также называют OID (Object Identifier, объектный идентификатор). Обычно это принято в системах, в которых напрямую не раскрывается расположение объектов в памяти, таких как объектные базы данных (в которых указатели в основной памяти являются довольно бессмысленными в качестве идентификаторов вне процессов базы данных). Однако в реляционной модели идентификация неявно присутствует внутри самого состояния – две строки с абсолютно одинаковым состоянием обычно считаются искажением реляционных данных, поскольку один и тот же факт, занесенный в базу данных дважды, является избыточным и непродуктивным. Для справедливости здесь следует говорить более точно; в действительности в реляционной системе допускаются кортежи-дубликаты (как отмечалось выше), но они часто запрещаются явными реляционными ограничениями, такими как ограничения PRIMARY KEY. В тех ситуациях, в которых значения-дубликаты допускаются, в реляционной системе отсутствует способ определить, какая из дублирующих строк выбирается – нет никакого неявного способа идентификации кортежей отношения, кроме как на основании его атрибутов. Это не так в случае объектных систем, в которых два объекта, обладающие абсолютно идентичными состояниями в двух разных областях памяти, в действительности являются разными объектами. (Из-за этого приходится различать операции «==» и «.equals()» в языках Java и C#.) Из этого вытекает простое следствие: если требуется согласовать в объектной и реляционной системах смысл идентификации, то в реляционной системе для обеспечения соответствия объектному идентификатору должно обеспечиваться некоторая разновидность уникального идентификатора (обычно автоинкрементный столбец целого типа).
Это приводит к некоторым серьезным проблемам по отношению к автоматическим системам ОР-отображения, поскольку смысл идентификации является абсолютно разным. Если две отдельные пользовательские сессии взаимодействуют с одним и тем же отношением в реляционном хранилище, то работает подсистема управления параллельным доступом РСУБД, которая обычно основывается на метафоре транзакционности (ACID). Если система ОР-отображения выбирает отношение из хранилища данных (по существу, формируя «представление» данных), образуется второй источник идентификации данных, одним из которых является база данных (защищенная упомянутой транзакционной схемой), а другим – объектное представление данных в основной памяти, для которого отсутствует транзакционная поддержка согласованности, кроме той, которая встроена в язык (например, мониторы в Java и .NET) или основанная на использовании библиотек (например, System.Transactions в .NET 2.0). Обе последние возможности могут игнорироваться разработчиками и действительно часто игнорируются ими. Управление изоляцией и параллельным доступом представляет собой непростую проблему, и, к сожалению, языки и платформы, обычно доступные для разработчиков, не настолько согласованы и гибки, как подсистемы управления транзакциями РСУБД.
Проблему еще более усложняет то, что во многих системах ОР-отображения имеется существенная поддержка кэширования данных (применяемого для повышения производительности и во избежание повторяющихся обращений к базе данных). Когда требуется производить реальное «выталкивание» данных в базу данных, и что означает транзакционная целостность, если приложение считает, что запись в базу данных произошла, а на самом деле этого не случилось? Эта проблема, в свою очередь, усложняется в тех случаях, когда система ОР-отображения выполняется в нескольких процессах над сервером баз данных. Обычно это происходит при использовании кластерных серверов приложений. Теперь идентификация данных производится в n+1 месте, где n – число узлов сервера приложений, а 1 – это сам сервер баз данных.Каждый узел должен каким-то образом сообщать другим узлам о своем намерении произвести обновление данных для поддержки некоторого механизма, предотвращающего одновременный доступ к данным (другим экземпляром той же сессии или некоторым экземпляром другой сессии, производящим доступ к тем же данным). На это тратится время, падает производительность. Даже в случае кэшей, работающих только на чтение, информация об обновлении хранилища данных должна каким-то образом доводиться до кэшей, поддерживаемых в узлах сервера приложений. Для этого требуются коммуникации сервера с клиентами по инициативе базы данных; в текущем поколении РСУБД поддержка таких коммуникаций не очень хорошо понятна или плохо документирована.