Реляционное отображение коллекций — альтернатива объектно-реляционному отображению?

    Данный текст рассматривает вкратце особенности объектно-реляционного отображения (Object-Relational Mapping — ORM) и вводит новое понятие реляционного отображения коллекций (Collection-Relational Mapping — CoRM), предлагая обсудить перспективы и возможности технической реализации новой концепции долговременного хранения состояния объектов

    Объектно-реляционное отображение (ORM)



    Сегодня почти общим местом при разработке больших и сложных систем стало использование объектно-реляционных отображений (Object-Relational Mapping, ORM), которые используют общность некоторых теоретических основ объектно-ориентированного и реляционного программирования для объединения этих двух, существенно разных, способов моделирования реальности.

    Объектно-ориентированное программирование опирается на концепции, плохо ложащиеся в парадигму реляционных СУБД, в основном представленных в виде систем, исполняющих запросы SQL. Такими концепциями являются иерархические структуры данных, полиморфизм, инкапсуляция и конечно же, наследование. И если наследование еще как-то получило развитие например в PostgreSQL, то например инкапсуляция, прямо противоречащая принципиальной открытости и произвольности комбинирования значений в кортежах SQL, создает на самом деле существенные (возможно, исходящие из теоретических противоречий) препятствия эффективному использованию реляционной СУБД, как долговременного хранилища состояний объектов класса.

    Тем не менее, распространенность реляционных СУБД, их относительная эффективность при исполнении запросов к большим и очень большим массивам данных, широкие возможности объединения гетерогенной вычислительной среды через реляционную СУБД и другие преимущества, связанные с использованием таких СУБД, заставляют искать компромисс между удобством проектирования системы в объектно-ориентированном стиле и ограничениями, накладываемыми на проектируемую систему использованием этих СУБД.

    Основной опорой для объединения объектной и реляционной парадигм в рамках ORM является тезис о том, что так же как реляционная таблица содержит множество элементов (строк) одной структуры, так и класс объединяет множество объектов, имеющих единую структуру и поведение. Поэтому одним из наиболее распространенных шаблонов, повсеместно используемых в реализациях ORM, является отображение класса в таблицу, при этом полями таблицы являются атрибуты (все или часть, однозначно определяющая состояние) объектов класса.


    Рисунок 1 Наиболее распространенная форма объектно-реляционного отображения. Классы отображаются на таблицы, атрибуты отображаются на поля таблиц

    Любая техническая реализация имеет свои ограничения, не стала исключением и технология реляционных СУБД, основанных на языке SQL, достаточно далеком от своего теоретического предшественника — алгебры Кодда. При этом, все технические ограничения SQL, связанные с самим наличием таблицы, как физического носителя кортежей значений, связанных между собой отношением один-к-одному, естественным образом переходят на класс, отображенный на такую таблицу с помощью ORM.


    Рисунок 2 Одна из проблем при прямом отображении классов в таблицы: отображение атрибутов, имеющих множественный характер, требует отдельных таблиц.

    Реляционное отображение коллекций



    Концепция реляционного отображения коллекций (Collection-Relational Mapping, CoRM) опирается на тот факт, что таблица, как долговременное хранилище состояний объекта, имеет вполне адекватный образ в любой развитой объектно-ориентированной среде, а именно — коллекцию (Collection).

    Хранение состояния коллекции объектов в виде таблицы SQL — далеко не новое изобретение. Так, половина пакетов, посвященных хранению данных в стандартной библиотеке python, посвящена именно этой технологии. Новизна подхода CoRM состоит в том, что разрозненные коллекции объектов объединяются хорошо определенными (well-defined) реляционными взаимоотношениями между этими коллекциями.

    (the following updated: 30-05-2013 как мне справедливо отметили, документ-ориентированные СУБД и MongoDB в частности, так же могут быть рассмотрены в качестве прототипа CoRM)
    CoRM, так же как документ-ориентированные СУБД и MongoDb в частности, не накладывает никаких ограничений на способность разных объектов одного класса хранить свое состояние в разных коллекциях, так же как и на способность коллекции одновременно содержать объекты, принадлежащие к разным классам. Основным отличием CoRM от документ-ориентированных СУБД и основанных на них инструментах, подобных ORM, является то, что в CoRM сохраняется возможность использования SQL (в слегка измененном виде) и использования реляционных отношений между объектами. Отличие же CoRM от традиционного подхода ORM состоит в том, что коллекция не привязана напрямую к классу и теоретически может содержать любой объект, при выполнении минимальных требований к этому объекту (а именно, способности к сериализации некоторым специальным образом). При этом, данные требования не включают в себя никаких ограничений на структуру объекта, использование специальных типов данных и так далее.

    Последнее обстоятельство отличает подход CoRM в том числе и от широко известной библиотеки SQLAlchemy, так же манипулирующей коллекциями и отдельно привязанными к коллекциям классами.

    Реляционные взаимоотношения между элементами коллекций определяются наличием и содержимым (возвращаемым значением) выделенных свойств (properties), атрибутов или детерминированных (deterministic) методов у входящих в коллекцию объектов. Такие выделенные свойства будут называться индексами (Index) коллекции. Таким образом, коллекция и ее индексы являются связующим звеном между парадигмой объектно-ориентированного программирования, поставляющей значения индексов, и реляционной парадигмой хранилища SQL, которое использует полученные значения индексов для установления реляционных взаимоотношений между хранимыми объектами.


    Рисунок 3 Коллекция и ее индексы являются связующим звеном между объектной и реляционной моделями данных

    Углубляясь в реляционную парадигму, можно определить понятие ключей (Key) коллекции, каждый из которых будет ссылаться на некоторое сочетание индексов этой коллекции, определяя для этого сочетания дополнительные оптимизационные и ограничительные свойства, например уникальность (составного в общем случае) значения ключа в рамках коллекции.

    Отдельные ключи коллекции могут служить внешними ключами для обращения к объектам, хранящимся в другой коллекции, в точности так же, как внешний ключ в таблице служит для установления реляционных отношений с другой таблицей. В точности таким же способом, как внешний ключ в реляционной СУБД, внешний ключ в реляционном отображении коллекций может быть использован для поддержки целостности (integrity) данных, запрещая хранение такого значения внешнего ключа, которое не соответствует ни одному из значений ключа в целевой для внешнего ключа коллекции.

    Возможность практического использования реляционных отношений между коллекциями определяется размещением связанных с ними таблиц в одной базе данных. Отражением этого факта для программиста является наличие специального объекта хранилища (Storage), который определяет специфику подключения к базе данных и общие структурные и функциональные характеристики СУБД, а также содержит точки доступа к коллекциям, таблицы для которых содержатся в этой базе данных.

    Обращаясь к коллекциям для выборки данных, в выражениях фильтрации, группировки, упорядочения — программист манипулирует не свойствами объектов, которые хранятся в коллекции, а значениями индексов, получая в результате список объектов, либо список кортежей, составленных из объектов и дополнительно подсчитанных выражений (определенных на значениях индексов коллекций). Сами объекты остаются полностью инкапсулированными внутри коллекции вплоть до тех пор, пока не будут десериализованы при получении результатов запроса.

    Инкапсуляция объекта внутри коллекции и изоляция хранимого состояния объекта от индексов, доступных (в отличие от состояния объекта) со стороны реляционного хранилища, делают бессмысленными попытки отображения выражений (фильтрации, группировки, вычислений дополнительных возвращаемых значений и упорядочения) на какие-то подобия выражений используемого объектного языка (python в нашем случае), как это происходит например в SQLAlchemy. Вместо этого, запрос выборки из коллекции может быть сформулирован на языке, максимально близком по структуре к SQL, как это например делается при использовании Google App Engine Datastore. Язык GQL, используемый при обращении к коллекциям Google Datastore, является почти оптимальным образцом (разумеется за исключением странных ограничений, накладываемых на этот язык его реализацией) языка, который мог бы быть использован для получения данных из коллекций при использовании CoRM. Имена, входящие в выражения языка, очевидно должны ссылаться на индексы и ключи, определенные на коллекциях, а не на атрибуты хранимого объекта, скрытые от реляционного хранилища.

    Выведение синтаксиса запроса к коллекции за пределы синтаксиса объектного языка позволяет проводить предварительную компиляцию и кеширование компилированных запросов целевого хранилища, оставляя возможность десериализации объекта из полученных данных, что может привести к существенной оптимизации скорости доступа к объектам, чье состояние сохранено в реляционном хранилище (здесь необходимо отметить, что вопрос оптимизации доступа к объектам в коллекции, вообще говоря, является достаточно болезненным для существующих ORM).

    Интересным дополнением является то, что инкапсуляция и выделение индексов коллекции, как отдельной сущности, помимо прочего, позволяют легко реализовать динамические индексы, значения которых не содержатся напрямую в атрибутах хранимого состояния объекта, но однозначно вычисляются из них.

    Вместо вывода



    Реляционное отображение коллекций, будучи реализованным, может стать отличной альтернативой существующим реализациям ORM, позволяя вывести из под ограничений реляционного хранилища объектную сущность приложения.

    Внимание, вопрос:

    Только зарегистрированные пользователи могут участвовать в опросе. Войдите, пожалуйста.

    Как Вы думаете, имеет ли смысл начать реализацию (open source) реляционного отображения коллекций?
    Будете ли Вы участвовать в проекте по реализации реляционного отображения коллекций?
    Поделиться публикацией

    Похожие публикации

    Комментарии 16
      0
      инкапсуляция, прямо противоречащая принципиальной открытости и произвольности комбинирования значений в кортежах SQL, создает на самом деле существенные (возможно, исходящие из теоретических противоречий) препятствия эффективному использованию реляционной СУБД, как долговременного хранилища состояний объектов класса

      Каким образом?

      Одна из проблем при прямом отображении классов в таблицы: отображение атрибутов, имеющих множественный характер, требует отдельных таблиц.

      А почему это проблема?

      таблица, как долговременное хранилище состояний объекта, имеет вполне адекватный образ в любой развитой объектно-ориентированной среде, а именно — коллекцию (Collection).

      Ага, на этом факте основано представление в любом ORM. Так что не понятно, почему вы умудряетесь на этот факт «опирать» другую парадигму.

      Рисунок 3

      … и тут мы видим нормальную такую документо-ориентированную БД. Иии?
        +1
        … и тут мы видим нормальную такую документо-ориентированную БД. Иии?

        Вот я тоже не понял, в чём суть то CoRM?

        Вот если бы кусочки кода привели для сравнения…
          0
          Так нету кода, это проект только…
          0
          инкапсуляция, прямо противоречащая принципиальной открытости и произвольности комбинирования значений в кортежах SQL, создает на самом деле существенные (возможно, исходящие из теоретических противоречий) препятствия эффективному использованию реляционной СУБД, как долговременного хранилища состояний объектов класса

          Каким образом?

          (не исчерпывающе, но в частности). Инкапсуляция заставляет существующие реализации получать весь кортеж простых атрибутов состояния объекта всякий раз при доступе к объекту (в некоторых случаях — еще и атрибуты из связанных таблиц). При обширном количестве атрибутов, это существенно увеличивает трафик данных между БД и приложением, заметно снижая общую эффективность приложения по сравнению с «чистым» SQL.

          Одна из проблем при прямом отображении классов в таблицы: отображение атрибутов, имеющих множественный характер, требует отдельных таблиц.

          А почему это проблема?

          Это оказывается проблемой, когда природа приложения такова, что данные множественного атрибута не имеют самостоятельной ценности без владеющего ими объекта. Например — документ и его строки.
          В этом случае, вторая таблица становится ненужной с той точки зрения, что по ней приложение не осуществляет никаких глобальных запросов, поэтому ее наличие в базе только утяжеляет ее, с точки зрения наличия индексов на таблице строк например.

          таблица, как долговременное хранилище состояний объекта, имеет вполне адекватный образ в любой развитой объектно-ориентированной среде, а именно — коллекцию (Collection).

          Ага, на этом факте основано представление в любом ORM. Так что не понятно, почему вы умудряетесь на этот факт «опирать» другую парадигму.

          Не совсем. «Любой» ORM почему-то склонен считать, что в программе будет ровно по одной коллекции для хранения состояния объектов каждого из классов, входящих в отображение.

          Рисунок 3


          … и тут мы видим нормальную такую документо-ориентированную БД. Иии?

          Документ-ориентированные СУБД, исходя из их общего описания, например MongoDB, опираются на «монолитное» хранение набора хранимых атрибутов, как простых, так и имеющих множественный характер, допускают хранение произвольных наборов простых и сложных атрибутов в любых коллекциях, индексируют отдельные атрибуты. Это действительно, очень похоже на CoRM в той части, которая отображена на рисунке. Вероятно, я должен был в исходном посте сослаться на них, как на один из прототипов.

          Различий, тем не менее, есть здесь несколько.
          Во-первых, в отличие от MongoDB и других документ-ориентированных СУБД, гордо относящих себя к NoSQL, CoRM не отказывается от использования некоторой разновидности SQL. Более того, полностью наследуются все преимущества использования реляционных отношений из нижележащего хранилища SQL.
          Во-вторых, в отличие от MongoDB, CoRM не пытается воспроизвести собственный движок СУБД, а опирается на существующие СУБД, что дает значительно более обширные возможности, связанные например с совместимостью в гетерогенной среде разработки.
          В-третьих, документ-ориентированные СУБД занимаются хранением состояния объекта и запросами к этому состоянию, в то время как у CoRM хранение состояния поручено нижележащему движку SQL, а сам CoRM осуществляет сокрытие деталей хранения, обеспечивая корректное преобразование хранимого состояния в объект заданного класса и обратно.
            0
            Инкапсуляция заставляет существующие реализации получать весь кортеж простых атрибутов состояния объекта всякий раз при доступе к объекту (в некоторых случаях — еще и атрибуты из связанных таблиц).

            Не заставляет. Как раз наоборот, инкапсуляция позволяет объекту получать свое состояние из БД таким образом, каким ему нужно.

            ее наличие в базе только утяжеляет ее

            Реальные цифры есть? Насколько БД «утяжеляет» лишняя таблица (по сравнению с размещением этих данных в какой-нибудь другой таблице).

            «Любой» ORM почему-то склонен считать, что в программе будет ровно по одной коллекции для хранения состояния объектов каждого из классов, входящих в отображение.

            Это утверждение неверное. Как минимум есть Entity Framework, который так не считает.

            Более того, полностью наследуются все преимущества использования реляционных отношений из нижележащего хранилища SQL.

            Я в этом не уверен.

            Во-вторых, в отличие от MongoDB, CoRM не пытается воспроизвести собственный движок СУБД, а опирается на существующие СУБД, что дает значительно более обширные возможности, связанные например с совместимостью в гетерогенной среде разработки.
            В-третьих, документ-ориентированные СУБД занимаются хранением состояния объекта и запросами к этому состоянию, в то время как у CoRM хранение состояния поручено нижележащему движку SQL, а сам CoRM осуществляет сокрытие деталей хранения, обеспечивая корректное преобразование хранимого состояния в объект заданного класса и обратно.

            Вы уверены, что это достоинства, а не недостатки? В частности, что у вас нет потерь производительности на лишнем уровне преобразований?
              0
              Инкапсуляция заставляет существующие реализации получать весь кортеж простых атрибутов состояния объекта всякий раз при доступе к объекту (в некоторых случаях — еще и атрибуты из связанных таблиц).

              Не заставляет. Как раз наоборот, инкапсуляция позволяет объекту получать свое состояние из БД таким образом, каким ему нужно.

              По крайней мере, на примере конкретно Django ORM, SQLAlchemy или Elixir — еще как заставляет. Я не говорил и не говорю о том, что это обязательно должно случаться, поэтому в частности, в исходном посте отметил, что это обстоятельство, наблюдаемое на существующих ORM, с которыми мне пришлось иметь дело (см. выше), возможно, исходит из теоретических противоречий. Данный вопрос требует отдельной серьезной проработки. Тем не менее, исходя из того, что ООП подходит к объекту в целом, как к монолитному конструкту, в то время как «запись» или «кортеж» в реляционной СУБД — это открытый и гибкий по составу набор значений, можно отметить некоторое противоречие при прямом отображении объекта и кортежа друг на друга.

              Реальные цифры есть? Насколько БД «утяжеляет» лишняя таблица (по сравнению с размещением этих данных в какой-нибудь другой таблице).

              Исходя из обычной арифметики, можно отметить, что поле ссылки на родителя и индекс на этом поле в дочерней таблице будут представлять из себя совершенно лишние сущности и «утяжелять» базу данных, при условии, что дочерняя таблица не используется ни в каких запросах, кроме запросов на получение списка дочерних элементов для родительской записи. Конкретные цифры вы можете получить самостоятельно на любом движке SQL.

              «Любой» ORM почему-то склонен считать, что в программе будет ровно по одной коллекции для хранения состояния объектов каждого из классов, входящих в отображение.

              Это утверждение неверное. Как минимум есть Entity Framework, который так не считает.

              Именно поэтому «любой» я поставил в кавычки. Впрочем, я все равно попрошу ссылку на то, какой именно фреймворк Вы имеете в виду.

              Вы уверены, что это достоинства, а не недостатки? В частности, что у вас нет потерь производительности на лишнем уровне преобразований?

              Прямое сравнение MongoDB и CoRM по этим параметрам — не совсем корректно, поскольку во-первых, они решают сходные, но не идентичные задачи, а во-вторых — MongoDB имеет место быть, в то время как CoRM только еще проектируется.
                0
                Тем не менее, исходя из того, что ООП подходит к объекту в целом, как к монолитному конструкту, в то время как «запись» или «кортеж» в реляционной СУБД — это открытый и гибкий по составу набор значений, можно отметить некоторое противоречие при прямом отображении объекта и кортежа друг на друга.

                … противоречие, которое вы разрешаете, уничтожая гибкость набора значений в СУБД, да. В то время как современные ORM (в частности, тот же EF) прекрасно позволяют выбрать из объекта только нужные поля.

                Исходя из обычной арифметики, можно отметить [...] Конкретные цифры вы можете получить самостоятельно на любом движке SQL.

                Это означает, что вы пока не столкнулись с реальными проблемами, связанными с этим оверхедом. Я их тоже, знаете ли, никогда не видел.

                Впрочем, я все равно попрошу ссылку на то, какой именно фреймворк Вы имеете в виду.

                Я, вроде бы, явно написал: Entity Framework.

                Прямое сравнение MongoDB и CoRM по этим параметрам — не совсем корректно, поскольку во-первых, они решают сходные, но не идентичные задачи

                И в чем же различие?
                  0
                  Исходя из обычной арифметики, можно отметить [...] Конкретные цифры вы можете получить самостоятельно на любом движке SQL.


                  Это означает, что вы пока не столкнулись с реальными проблемами, связанными с этим оверхедом. Я их тоже, знаете ли, никогда не видел.

                  Это означает, что мне лениво поднимать соответствующий тест и проводить формальные замеры. Я не только столкнулся с этой проблемой лоб в лоб, мне пришлось ее решать способом даже более кардинальным, чем я здесь описываю. В частности, мне вовсе пришлось отказаться от попытки как-либо использовать ORM непосредственно при первичной обработке данных, а при анализе — прикручивать сбоку наляпки разного рода. Именно поэтому в частности, я начал думать о чем-то таком, что я здесь описал.
                  В данной статье у меня не было желания подробно разбирать ORM с точки зрения производительности например. Если желаете, можете ознакомиться со статьей вот здесь, где я подробно описываю, с конкретными замерами и цифрами, как именно отдельные ORMы сами по себе, просто в силу своего применения, тормозят исполнение кода и расходуют ресурсы, а также вот здесь, где я предлагаю наляпку на Django ORM для прикручивания и кеширования параметризованных запросов, ускоряющую выполнение кода в несколько раз. Правда там нет того конкретного юзкейза, который мы обсуждаем здесь (запись-владелец и набор записей-деталей). На написание и проведение тестов, которые приведены в каждой из статей, я потратил не менее одного рабочего дня и еще немножко. Вы при желании, можете потратить примерно столько же, чтобы убедиться, прав я или не прав. Но прежде чем заявлять здесь что я неправ, неплохо бы было именно Вам провести подобные тесты.

                  Я, вроде бы, явно написал: Entity Framework.

                  Это вот этот что-ли? msdn.microsoft.com/ru-ru/library/bb399572.aspx

                  В таком случае вот здесь msdn.microsoft.com/ru-ru/data/jj591617 описаны юзкейзы различного использования маппинга:
                  — Specifying That a Class Is a Complex Type
                  — Specifying Not to Map a CLR Entity Type to a Table in the Database
                  — Mapping a CLR Entity Type to a Specific Table in the Database
                  — Mapping the Table-Per-Hierarchy (TPH) Inheritance
                  — Mapping the Table-Per-Type (TPT) Inheritance
                  — Mapping the Table-Per-Concrete Class (TPC) Inheritance
                  — Mapping CLR Properties of an Entity Type to Multiple Tables in the Database (Entity Splitting)
                  — Mapping Multiple Entity Types to One Table in the Database (Table Splitting)

                  Я что-то не вижу здесь возможности отобразить один и тот же класс так, чтобы он хранил часть объектов — в одной таблице, а часть — в другой (Entity Splitting как я понимаю, позволяет разделять один объект на два, мапируя их на разные таблицы, это не то, ну а остальные варианты только сокращают количество коллекций), а это и было одним из описанных преимуществ CoRM.

                  Таким образом, мое предыдущее утверждение о том что <<«любой» ORM почему-то склонен считать, что в программе будет ровно по одной коллекции для хранения состояния объектов каждого из классов, входящих в отображение>>, остается верным, с точностью до «ровно», которое надо разумеется, заменить на «не более чем» (последнее верно и для других ORM). Ну и конечно же, «склонен» формально не означает, что так оно и есть во всех случаях.

                  Прямое сравнение MongoDB и CoRM по этим параметрам — не совсем корректно, поскольку во-первых, они решают сходные, но не идентичные задачи

                  И в чем же различие?

                  Своей невнимательностью, Вы во второй раз заставляете меня цитировать самого себя, что (цитирование) вообще говоря, является дурным тоном:
                  Различий, тем не менее, есть здесь несколько.

                  Во-вторых, в отличие от MongoDB, CoRM не пытается воспроизвести собственный движок СУБД, а опирается на существующие СУБД…
                  В-третьих, документ-ориентированные СУБД занимаются хранением состояния объекта и запросами к этому состоянию, в то время как у CoRM хранение состояния поручено нижележащему движку SQL, а сам CoRM осуществляет сокрытие деталей хранения, обеспечивая корректное преобразование хранимого состояния в объект заданного класса и обратно.

                  В этом и состоит различие. CoRM — не движок датабазы, а лишь маппинг, а MongoDB — движок, поэтому производительность движка и производительность CoRM — разные, хотя и взаимосвязанные вещи. Кроме того, результатом работы самой MongoDB является в чистом виде структура данных, что требует навешивания сверху дополнительных слоев, реализующих поведение объекта, см здесь. Поэтому корректное сравнение должно сопоставлять производительность ORM-ов, представленных на указанной ссылке, с производительностью библиотеки CoRM на различных движках SQL, буде таковая библиотека разработана.
                    0
                    Но прежде чем заявлять здесь что я неправ, неплохо бы было именно Вам провести подобные тесты.

                    У меня с «подобными тестами» все очень просто: у меня есть система с традиционным ORM, и я не вижу в ней никаких проблем, вызванных оверхедом из-за лишних таблиц для представления сущностей внутри аггрегатов.

                    Я что-то не вижу здесь возможности отобразить один и тот же класс так, чтобы он хранил часть объектов — в одной таблице

                    Очень просто. Два датаконтекста, две конфигурации, в каждой конфигурации прописана своя таблица.

                    Таким образом, мое предыдущее утверждение о том что <<«любой» ORM почему-то склонен считать, что в программе будет ровно по одной коллекции для хранения состояния объектов каждого из классов, входящих в отображение>>, остается верным, с точностью до «ровно», которое надо разумеется, заменить на «не более чем» (последнее верно и для других ORM). Ну и конечно же, «склонен» формально не означает, что так оно и есть во всех случаях.

                    А эти утверждения вообще никак не связаны. Я могу создать в EF произвольное количестко коллекций, хранящих объекты одного класса, и это никак не будет связано с тем, в какой таблице хранятся эти объекты.

                    Поэтому корректное сравнение должно сопоставлять производительность ORM-ов, представленных на указанной ссылке, с производительностью библиотеки CoRM на различных движках SQL, буде таковая библиотека разработана.

                    Именно об этом я и говорю. Хотя бы в качестве PoC.

                    Кстати, неоднократно замечено, что при сложных бизнес-слоях не рекомендуется ставить бизнес-логику напрямую в те объекты, которые отображаются на БД, а использовать их в качестве DTO.
          0
          Интересная концепция. Хотелось бы увидеть псевдокод на любом распространенном языке — как это будет выглядеть?

          Я лично для себя принял такие правила (и реализовал их в своем велосипеде, куда без этого):
          — запись в таблице — это объект
          — вся таблица — это класс
          — набор записей — коллекция объектов

          Из этого легко вытекает, что операции с таблицей в целом производятся статическими методами класса, над конкретной записью — динамическими методами объекта, а операции над коллекцией — методами объекта-коллекции с возможными «пробросом» к методам объектов-членов коллекции.

          Ну типа так (жуткая лапша):

          $users = User::findAllByRegion('Russia');
          $user0 = $users[0];
          $user0->setNickname('Habr');
          $user1 = $users[1];
          $user1->setPassword('password');
          $users->save();
          


          Пока такой концепции хватает для большинства разумных случаев, где вообще применим ORM.
            +3
            Поздравляю вас, вы описали помесь ActiveRecord с Recordset.
              0
              Так точно, кэп )))
            0
            Хотелось бы побольше кода, как здесь.
            И сравнение по скорости запросов чистого SQL с Вашим решением тоже не помешало бы.

            PS: сам использую СУБД, нативно поддерживающую ООП (не только для Python), SQL и NoSQL, поэтому и вопросов с ORM не возникает.
              0
              сам использую СУБД, нативно поддерживающую ООП (не только для Python), SQL и NoSQL, поэтому и вопросов с ORM не возникает.

              Какую именно, если не секрет?
                0
                Какую именно, если не секрет?
                Нисколько не секрет — это СУБД Caché.

                Эх, а я думал Вы догадаетесь сами по моему профилю.
                  0
                  Я помню ее, когда-то — лет 10 назад — очень внимательно разглядывал, очень интересная концепция была, хорошо что она столь успешно развивается.

            Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.

            Самое читаемое