За последние 24 часа нас посетил 20671 программист и 1106 роботов. Сейчас ищут 550 программистов ...

Объектный SQL

Тема в разделе "Прочие вопросы по PHP", создана пользователем Sergey89, 26 июл 2008.

  1. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Что до конкретного примера, мне лично не нравится, что скрывая реализацию SQL имена таблиц указываются явно. Хотя, наверно, это уже уровень датамапера...
     
  2. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Случалось. Конкретный пример из различия двух популярных субд - мускуля и постгреса. Справедливости ради, мускуль умеет и offset, но мало кто так пишет, хех.
    А вообще, часто вы переписываете свой код? Зачем вам все эти классы, функции... а? Ну придется мож один проект из десятка поправить - ну ничего, потрудитесь, лучше чем городить все эти ООПы ;)
     
  3. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    MiksIr
    Лол, ну если не хватает воображения сделать реплейс непосредственно в момент вызова запроса, тогда конечно ;)
    Цитата к месту - ибо поверьте мне, люди не глупее вас и подходили к проблеме комплексно, а не только с точки зрения проектирования таблиц.
     
  4. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Угу, этакий класс db обвешанный регэкспами ;)
    Да и потом, не в совместимости все дело. Это был так, самый простой пример, что в голову пришел. А посмотрите синтаксис, например, работы с массивами и хешами в постргресе... ну а потом уж скажите - так ли просто "запомнить SQL".
    К тому же, такой абстрактный класс может помогать и в других вещах. Нам, например, помогает сохранять объекты беря на себя роль фильтрации служебных полей объекта. В общем, много чего можно сделать - надо лишь желание двигаться. У Сергея оно есть, по крайней мере. А уж какая там конкретная реализация конструктора SQL будет - объектная или еще какая не так важно.
     
  5. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    MiksIr
    Да на здоровье, двигайтесь. Просто я уже, наверное, сотый вариант такого подхода вижу, словно их кто-то клонирует, а идея почему-то везде одна и та же - любыми правдами и неправдами крыть исходный синтаксис запроса, создать иллюзию абстрактности, а потом тот же самый запрос и собрать обратно (с учетом конкретного диалекта SQL, ога). Все это уже давным-давно реализовано например в MZZ и LIMB. Поработайте с этими фреймворками и поймете, что вы получили, а чего лишились. А под другим подходом я имел в виду нечто действительно новое и сулящее хоть какую-то свежесть - например, обдумать вариант, при котором у программиста вообще нет никаких запросов к СУБД, нигде. Он просто связывает сущности отношениями и обращается к тем или иным полям, даже не задумываясь, где у него хранятся данные. Вот это был бы "объектный SQL", да.
     
  6. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Это уже следующий уровень абстракции - уровень датамапера. Мы его делали взяв именно лимб как основу. Уровень конструктора SQL он совершенно не исключает. А получив такой конструктор, который принимает в себя, к примеру, массив с данными (а не строчку INSERT ... ) и фильтрует его, мы можем не заботится о том, что бы модели знали как их свойства отражаются в поля конкретной таблицы.
     
  7. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Так и делаю, без всяких ООПов и почих. Проект (если он хорошо спланирован и реализован) переписывать не нужно, поставил и забыл на годы. (исключение когда хомяк "васи пупкина" раскручивается до уровня яндекса и надо полностью переписывать его под HighLoad) это по любому дешевле чем изначально писать хомяки "васи пупкина" под HighLoad вкладывая десятки тысяч мёртвых зелёных президентов, а затем ежемесячно вкладывать столько-же на его поддержку, в надежде что когда нибудь один из них вырастет и станет вторым гуглом, точнее первым, а гугл станет вторым...
     
  8. Хех, давай посмотрим с точки зрения хайлоада на это? Как ты с этим классом БД ты будешь затачивать SQL как ты сам говорил, что это не является деградацией кода? ))

    И вообще, почему ты тогда ратуешь за натив-ПХП в шаблонах? Это тоже тот случай. Введение нового синтаксиса для сущности ради самого синтаксиса.

    Я понимаю желание привести SQL к обьектному виду. Я сам это пытался сделать. Да, т.к. я работаю с 2 СУБД одновременно, некоторые вещи у меня абстрагираваны от SQL - например методы Limit() и Prepare() — но я согласен с Dagdamor (хотя я не часто с ним согласен) — генерацию SQL из обьекта считаю идеей ущербной по сути, особенно в скриптовых языках.
     
  9. sylex

    sylex Активный пользователь

    С нами с:
    9 ноя 2008
    Сообщения:
    625
    Симпатии:
    0
    Адрес:
    Омск
    плюсов, кроме как независимость от СУБД, не вижу... а минусы уже перечислили...

    полностью согласен..

    Возможно и нужна некая абстрактная модель для удобства, но не такая жесткая как здесь ИМХО :)
     
  10. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Затачивание SQL? Ты про что? Конструктор SQL вообще никак не мешает создавать нужные запросы. Про датамапер отдельный разговор - у нас он умеет и джоны строить и объекты/выборки кешировать. Деградации тут не вижу.
    Я? Я всегда был против нативных шаблонов в виду их отвратительной читаемости.
    Как реализован конструктор - объектом ли, статикой или функцией - особо роли не играет. Если кому-то нравится объект - ради бога. Вероятно объект даже будет удобнее при наличии чего-то, что само создает SQL запросы (тот же датамапер). А скриптовый язык или нет - тут тоже вообще никакой роли не играет... или уж говорите нет объектам в принципе, присоединяйтесь в Vladson-у и вперед... нада еще обсудить, не ущербна ли идея функций в _скриптовых_ языках =)
     
  11. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    Почему ты читаешь не то что написано ?
    Я не говорю объектам нет в принципе.
     
  12. MiksIr

    MiksIr Активный пользователь

    С нами с:
    29 ноя 2006
    Сообщения:
    2.340
    Симпатии:
    44
    Читаю как написано "Так и делаю, без всяких ООПов и почих."
    Или у вас объекты без ООП-а? ;)
     
  13. Vladson

    Vladson Старожил

    С нами с:
    4 фев 2006
    Сообщения:
    4.040
    Симпатии:
    26
    Адрес:
    Estonia, Tallinn
    У меня есть цель, и есть средства, там где одни оправдывают других я использую их, когда не оправдывают то шлю нафик. А делать ООП-ы только потому что это "круто" и уж тем более придумывать свой SQL для упрощения запросов (но на разработку которого уйдёт уйма времени, и на обучение которому уйдёт ещё больше) когда старый ничем не хуже это не для меня.
     
  14. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    Поймите, что подобный код, как правило, скрыт за DAO. И запрос почти целиком генерируется автоматически, со всеми джоинами и т.п. Вам лишь остаётся задать какие-то ограничения на выборку при помощи критерии.

    Это уже, как сказали, уровень Data Mapper. Бизнес объект полностью отделяется от источника данных. И ему уже всё равно откуда берутся данные. Но даже в этом случае квери билдер очень полезен. Где-то нам надо выбрать 10 объектов, где-то 20, где-то объекты отсортировать в одном порядке, где-то в другом.

    PHP:
    1. <?php
    2. $user = new UserMapper();
    3. $ten_users_sorted_by_login = $user->createCriteria()->orderBy(SQLOrder::create('login'))->limit(10)->all();
     
  15. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Sergey89
    Даже для такого примера, сверхпримитивного и сверхудобного для демонстрации возможностей объектного подхода, запись получается гораздо длиннее аналогичного SQL-запроса...
    PHP:
    1. <?php
    2. $ten_users=db_query("SELECT * FROM users ORDER BY login LIMIT 10");
    или же подхода, реализованного в PHPC...
    PHP:
    1. <?php
    2. $ten_users=$db->getOrderedLinesRange("users","login",0,10);
     
  16. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    А что если мне нужно добавить ещё пару JOIN'ов и заполнить релевантные объекты данными?


    PHP:
    1. <?php
    2. $user = $um->findById(10);
    3. $user->getDataFromRelateTable();
    Ну это тоже в своём роде qwery builder, только с заранее урезанным функционалом.
     
  17. Dagdamor

    Dagdamor Активный пользователь

    С нами с:
    4 фев 2006
    Сообщения:
    2.095
    Симпатии:
    1
    Адрес:
    Барнаул
    Sergey89
    ...то уже для этого примера существует риск забабахать такую конструкцию в цикле, не зная о ее реализации, и получить кучу излишних запросов.
     
  18. Sergey89

    Sergey89 Активный пользователь

    С нами с:
    4 янв 2007
    Сообщения:
    4.796
    Симпатии:
    0
    А я могу сказать DataMapper'у, чтобы он сразу выбрал все нужные объекты. А риск забабахать запрос в цикле есть всегда, даже когда пишешь на сыром SQL.
     
  19. kostyl

    kostyl Guest

    О чём спор? Абстракция всегда может повлеч за собой недостатки, такие как избыточность кода, падение производительности и т. п. Но она же в свою очередь имеет и достоинства абстракции. Тут надо выбирать, что тебе нужно.
     
  20. Mr.M.I.T.

    Mr.M.I.T. Старожил

    С нами с:
    28 янв 2008
    Сообщения:
    4.586
    Симпатии:
    1
    Адрес:
    у тебя канфетка?
    с одной стороны Дагдамор во многом прав, а с другой
    PHP:
    1. <?
    2.  function SqlSearchByPostsText($q,$category=array(),$page=0){
    3.        $sql='';$sqlnumrows='';
    4.        $q=Replacer::Escape($q);
    5.        if(!empty($category)) $category=Replacer::Escape($category);
    6.        $page=Replacer::Escape($page);
    7.        $cnf=locator::LoadData('config');
    8.        $tsql="
    9.             FROM ?p_posts as P
    10.             WHERE P.posts_text LIKE('%$q%')
    11.             ";
    12.        if(is_array($category) && !empty($category))
    13.           $tsql.=" AND ".$this->SFormateIN(array("P.posts_cats_id"=>$category));
    14.        $sql="
    15.           SELECT P.*
    16.           ".$tsql."
    17.           ORDER BY {$cnf['page_global_sorter']}
    18.           LIMIT {$page},{$cnf['search_page_num']}
    19.           ";
    20.        $sqlnumrows="
    21.            SELECT COUNT(P.posts_id)
    22.            ".$tsql."
    23.       ";
    24.        return array("result"=>$this->query($sql),"numrows"=>$this->resultquery($sqlnumrows));
    25.    }
    26. ?>
     
  21. shurastik

    shurastik Активный пользователь

    С нами с:
    22 фев 2008
    Сообщения:
    285
    Симпатии:
    0
    Адрес:
    Латвия
    Отойдём от привычных СУБД :D

    К примеру есть самописная база данных [которая работает с текстовыми файлами]
    У неё есть интерфейс: select(), delete() и т.д.

    Без ОРМ придётся писать парсер SQL-запросов для получения данных.
     
  22. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    вот ОРМ, как я его понимаю: возьму самый простой пример. Например, мне в базе, в папке "Организации" надо программно создать новую организацию РАО ЕЭС, при этом, естественно приходится делать сопутствующие вещи:
    - записать в логах время создания и пользователя от имени которого она создается
    - еще до этого проверить, а есть ли у пользователя права создавать в этой папке новые объекты?
    - заполнить незаполненные поля значениями по умолчанию
    - проверить корректность заполнения полей и в случае некорректности исправить ошибки или выплюнуть исключения
    ну и еще куча всяких мелочей, которые зависят от типа создаваемого объекта и реализуются в OnCreate() и OnStore()
    для того чтобы сделать все это при помощи ОРМ нужно написать ровно 4 строчки:

    PHP:
    1. $dep= new Department();
    2. $dep->name= "РАО ЕЭС"; //имя
    3. $dep->path= Object::path2(26957); //26957- это айдишник папки "Оргинизации"
    4. $dep->store(); //тут заполнятся поля значениями по умолчанию, ссылочные поля проверятся на корректность, проверятся права на создание внутри 26957, объект сохранится и запишется вго первый лог.
    5.  
    а сколько тысяч строк мне пришлось бы писать для того же без ОРМ?

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

    PHP:
    1. $org= new Object(26957);
    2. $org->move(new Object(1)); //1- это айдишник корневой папки.
    просто же? так что те кто говорит, что ОРМ ничем не помогает, тот по- моему сильно ошибается. мне было проще один раз написать ОРМ, чем каждый раз писать эти эскуэли и тонны проверок.

    А второе преимущество ОРМ, это как уже говорили относительная независимость от СУБД и от структуры БД. Вот непридуманный случай. Сначала база работала на МуСКЛ. Потом его стало нехватать и я ушел на ПГ. Теперь самое интересное. Все что пришлось переписать- это Object::create(), Object::store(), Object::copy(), Object::move(), Object::delete() и undelete(). Все это методы одного класса и все в одном месте. вот так. Если бы я не пользовался ОРМ, а писал непосредственно СКуЛь, мне пришлось бы перепроверить все места проекта, где работа с базой. Представляете сколько на это ушло бы времени? А так что раньше там стояло create(), что теперь стоит create(), я в одном месте поменял реализацию create() и все заработало. Так что ОРМ рулит
     
  23. topas

    topas Активный пользователь

    С нами с:
    16 авг 2006
    Сообщения:
    2.258
    Симпатии:
    36
    Sergey89 +1
    onphp забавная штука, а использование критериев в своих sql-запросах - просто песня
    Я за разделение Бизнес-объектов и Sql-конструкций, т.к. это обычно совершенно разные задачи.
     
  24. alexey_baranov

    alexey_baranov Активный пользователь

    С нами с:
    3 фев 2009
    Сообщения:
    647
    Симпатии:
    0
    Адрес:
    Сургут
    а с этой объектной эскуэлиной можно делать вот так:

    PHP:
    1. $sql = "select * from table";
    2. $builder= new Builder($sql);
    3.  
    4. //тут чуть по чуть модифицирали его объектно и потом обратно в текст
    5.  
    6.  
    7. $sql= $builder->asText();
    интересует в основном постгрксовский диалект скуэля.

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