|
su.dbms- SU.DBMS ---------------------------------------------------------------------- From : Dmitry V. Liseev 2:5020/400 30 Jan 2002 22:16:49 To : Andrei N.Sobchuck Subject : Re: Проблемы persistent layers -------------------------------------------------------------------------------- a> <1012231289.212259@gatekeeper.fct.ru> a> <e8043a.hf3.ln@server1.mart.cherkassy.ua> From: "Dmitry V. Liseev" <dimik@infopro.spb.su> Andrei N.Sobchuck <andrei@mart.cherkassy.ua> wrote in message news:e8043a.hf3.ln@server1.mart.cherkassy.ua... Hi! > >> Тут товарисч за Cache вспоминал. Хотелось бы увидеть пример запроса, > >> который возвращает, набор объектов какого-то класса (любого). > > IZ> Cache в ряд ли можно назвать объектно ориентированной СУБД. > Ошибся. Hа ихнем СДюке написано "Post-Relational". > Впрочем, мой вопрос остаётся в силе. > Я нашел пример на жабе, как вытащить один конкретный объект (по ключу?), > но > не нашел, как _запросом_ вытащить несколько объектов. В КАШЕ есть разные виды запросов. 1. Если тебя интересует именно SQL, то любой запрос на встроенном SQL транслируется оптимизатором на встроенный язык (ObjectScript), а затем в некий аналог жабовского байт-кода. Если этот запрос встроен в код метода, то это происходит на этапе компилляции метода. Если этот запрос пришел по ODBC, это делается в рантайме и кешируется. Поскольку в описании объекта ты можешь указать, как именно хранить объект и по каким свойствам индексировать, то оптимизатор эту информацию имеет уже на этапе компилляции кода. Созданный оптимизатором код можно всегда посмотреть и поправить ручками. Этот код запроса, сгенерированный оптимизатором шарится по диску (не создавая в памяти экземпляров объектов, что очень быстро) и выдает тебе нужные данные: &sql(SELECT LastName INTO :LastName FROM Person WHERE FirstName='Dennis') Если объекты индексированы по полю FirstName, то никакого фуллскана не происходит. Если тебе нужно не только LastName, а весь объект, то просто находишь идентификаторы нужных объектов и создаешь в памяти их экземпляры: &sql(SELECT ID INTO :id FROM Person WHERE FirstName='Dennis') Set obj=##class(Person).%OpenId(id) Опять-же нужна индексация по полю FirstName. Если индекс выключить и перекомпиллировать этот код, то оптимизатор создаст код, который будет действительно делать фуллскан. Если нужен не один, а несколько объектов - никаких проблем. Просто создаешь курсор и в цикле поднимаешь в память найденные объекты, после чего возвращаешь их одним списком на клиента. Клиенту уже приезжает коллекция IDispatch интерфейсов на эти объекты. New id,ChildId,SQLCODE,ChildDesignsList,Child ; Получим идентификатор текущего объекта Set id=..%Id(),ChildDesignsList="" ; Запросим все дочерние объекты, которые на нас ссылаются. &sql(DECLARE ChildDesigns CURSOR FOR SELECT ID INTO :ChildId FROM Design WHERE ParentDesign=:id) &sql(OPEN ChildDesigns) ; Поднимем в память экземпляры объектов и засунем их в список. For &sql(FETCH ChildDesigns) Quit:SQLCODE'=0 Do . Set Child=##class(Design).%OpenId(ChildId) . Set ChildDesignsList=ChildDesignsList_$ListBuild(Child) &sql(CLOSE ChildDesigns) ; Вернем список Quit ChildDesignsList 2. Запросы можно писать руками на языке ObjectScript. Это делается, если требуется очень высокая производительность и нет надежды на оптимизатор. Hапример, у меня так сделана проверка прав доступа. Hа каждый объект, любого типа (если его класс унаследовать от класса SecurableObject) существующий в базе можно создать списки прав доступа на разные типы операций. Соответственно, при чтении такого объекта с диска, модификации или удалении проверяются права доступа приконнекченного юзера и генерятся соответствующие исключения. Различных классов, для которых требуется проверка прав доступа у меня достаточно много. Для ее реализации достаточно эти классы просто унаследовать от SecurableObject. Hикакого заметного падения производительности при проверках прав доступа не происходит. Разумеется, никто не собирается оптимизировать запросы, в которых есть вызовы методов. Для выполнения запроса используются не экземпляры объектов в памяти, а их хранящиеся на диске свойства. А для вызова метода объекта, необходимо сначала прочитать его с диска - это достаточно длительная операция (она загрузит в память все свойства, даже если они не используются в запросах, а свойство может являться другим встроенным объектом или вообще коллекцией). Эта оптимизация легко делается вручную - можно перекрыть метод сохранения объекта, и когда кто-то захочет сохранить экземпляр объекта на диске, то вызовется твой код, где ты можешь построить собственные индексы на любой цвет и вкус, по которым потом и будешь искать. ЗЫ: Это действительно не ООСУБД, она просто обладает дополнительными возможностями по сравнению с реляционными, потому и Post-Relational. Это просто сервер СУДБ и сервер приложений вместе с PL в одном флаконе. Ибо я не сторонник чистоты ОО-идей и предпочитаю C++ вместо ST и удобную в разработке систему вместо чистой ООСУБД. Вернее наоборот, это в первую очередь сервер приложений с достаточно эффективным языком разработки, похожим на VisualBasic (его называют ObjectScript), основанный на уже давно существующей "М-технологии". Основное отличие состоит в том, что переменные этого языка не просто скалярные или массивы, а индексированные массивы с произвольным количеством индексов. С математической точки зрения каждая переменная - дерево. Hапример два человека выглядят так: Set Person(1,"FirstName")="Alex" Set Person(2,"FirstName")="Peter" Set Person(2,"LastName")="Allan" Причем для второго человека мы храним как имя, так и фамилию. В РСУБД нельзя создать таблицу, в которой первая строка имеет одно поле, а вторая - два. Причем к первому можно добавить список имен детей: Set Person(1,"Childs",1,"Name")="John" Set Person(1,"Childs",2,"Name")="Michael" Set Person(1,"Childs",3,"Name")="Ann" В терминах РСУБД это означает появление в первой строке таблицы поля, которое также является таблицей. А уже потом - это сервер СУБД, поскольку это переменные могут быть не только локальными, но и глобальными, т.е. хранится на диске и быть доступными сразу всем процессам. Т.е. на самом низком уровне физически на диске хранятся не таблицы, а эти деревья (в оптимизированном виде). PL там реализован в виде библиотеки классов (на манер MFC) и при желании ты можешь даже не знать, каким именно образом и где хранятся твои объекты, но этим можно (и нужно) управлять. Можно и собственный PL написать. В рекламе написано про три вида доступа: реляционный, объектный и прямой. Реляционные запросы транслируются в код на ObjectScript, который ползает по этим деревьям на диске, объектный доступ через методы PL делает тоже самое, а прямой доступ - это когда ты сам ручками пишешь на ObjectScript код, работающий с глобальными переменными. _Такая_ реализация PL меня более чем устраивает _в работе_. Те сабж, которые там есть для меня представляют скорее академический интерес (как тема диссертации), чем реально мешают работать. ____________________________ С уважением, Лисеев Дмитрий. http://private.peterlink.ru/dimik/ PGP key fingerprint: 09 28 74 28 6C 39 62 29 2E CB 95 03 4F 04 33 73 --- ifmail v.2.15dev5 * Origin: Peterlink News System (2:5020/400) Вернуться к списку тем, сортированных по: возрастание даты уменьшение даты тема автор
Архивное /su.dbms/20753095cb3ed.html, оценка из 5, голосов 10
|