2011/10/26 Andrei <[email protected]>: > И как у этого велосипеда с производительностью на больших объёмах данных? > Расскажи лучше нам про велосипед из патченного CDBI :)
Но вопрос задан правильно. Универсальное решение не будет шустро работать при полноценном использовании его универсальности. >> соответственно вопросы: >> >> 1. кому-нибудь интересна подобная система, стоит класть на CPAN? Выкладывайте хотя бы на гитхаб! > 26 октября 2011 г. 18:26 пользователь Ivan Petrov <[email protected]> > написал: >> >> сделали мы тут цельный проект на DBIx::Class. С точки зрения >> попробовать последний. До этого всегда использовали DBI, который >> использовала модель в системе MVC. >> >> Впечатления плохие, однако появились мысли куда надо двигаться чтобы >> было хорошо. Я их тут изложу, а вы покритикуйте. >> >> В первую очередь зачем как бы нужен был этот DBIC. >> - конструирование SQL-запросов >> - уход от смешивания кода Perl с кодом SQL >> - выборка объектов, а не хешей из БД, которые можно расширять своими >> методами >> - упрощение кода моделей с точки зрения что в простых случаях вообще >> не делать выделенную модель >> >> Ничего не забыл? >> >> По результатам проекта (проект был довольно большой и дальше еще будет >> долго) я понял следующее: >> >> 1. даже в простых случаях DBIC на роль модели не годится. То есть в >> любом случае нужно делать выделенную модель, пусть даже там один >> resultset('Name')->find. Ибо тесты. При их написании мы применяем >> способ "подменить модель на стадии тестирования". >> >> 2. DBIC не предоставляет хорошей абстракции над БД. Все равно >> JOIN'ы, SELECT'ы торчат местами (например join_type => 'left' в has'ах >> итп). То есть оперировать хранилищем как некоей абстракцией в реальном >> случае не получается. >> >> 3. Конструктор SQL-запросов крайне страшен. Работали мы с постоянно >> включенной отладкой (выводом всех делающихся запросов в лог). С одной >> стороны есть множество вещей которые на DBIC сделать крайне непросто >> (например многие аггрегаторные вещи), с другой стороны когда >> начинается работа с более чем двумя таблицами он зачастую мутит такие >> страшные вложенные SQL-запросы что волосы дыбом становятся, а с >> третьей стороны использование фич конкретной БД становится затруднено. >> >> В итоге пришли к тому, что в сложных случаях приходится делать в БД >> view'ы только из за того что от DBIC добиться генерации нормального >> запроса очень и очень сложно или невозможно. Набор опций при выборке >> может быть больше самого SQL-запроса, если его просто написать. >> >> Ну вот и в свете того, что код работы с DBIC все равно располагается в >> моделях, конструировать эффективные SQL-запросы он все равно не умеет, >> то из плюсов его использования остаются только: >> - выборка в объекты и итераторы по ним >> - уход от смешивания Perl и SQL >> >> Соответственно размышляя над всем этим мы пришли к тому, что >> >> 1. построить качественный автогенератор SQL запросов на все случаи >> жизни (или по кр. мере на большинство) невозможно, поэтому его не >> стоит и пытаться сделать >> >> 2. из за п.1 бОльшая часть DBIC становится не нужна, а надо делать >> некоего помощника, который бы человеку просто помогал удобно работать >> с БД. >> >> то есть надо >> >> 1. написать свой итератор, работающий поверх массива или >> хеша - выборки из БД. >> 2. написать базовую обертку над одной строкой выборки (доступ в виде >> методов) >> 3. Используя 1 и 2 написать над DBI класс, который выборки блессает в >> итераторы и объекты >> 4. решить вопрос с выносом SQL-кода из перловых модулей. То есть >> обертка 3 должна уметь работать с SQL, располагающимися в файлах. >> >> >> Вынос SQL в файлы очень плохо соотносится с дефолтными плейсхолдерами >> DBI. поскольку они позиционные. >> >> Вывод: >> 5. надо реализовывать именованные плейсхолдеры >> >> ну и попутно >> 5.1 реализовать плейсхолдерные (темплейтные) выражения для типовых >> вещей, как-то >> INSERT ... VALUES (?,?,?),(?,?,?),(?,?,?),... >> >> или >> SELECT ... WHERE id IN (?,?,?) >> >> то есть подстановки массивов. >> >> Соответственно исходя из этого родился набор модулей, который в >> ближайшее время, если кому-то будет интересно, мы можем выложить на >> CPAN (там еще работы на неск. дней осталось), который все это делает: >> >> 1. по дефолту блесает строки-выборки в объект, у которого три >> предопределенных метода: new, is_changed, iterator. Плюс методы >> совпадающие с именами выбранных столбиков. >> >> 2. блесает наборы-выборки в объект позволяющий делать проходы по >> выборкам итп (совместимо с DBIC'шными ->all, while(...->next) итп >> >> 3. в п. 1 и 2 позволяет указывать свои классы для итераторов и выборок >> >> 4. позволяет вместо SQL использовать имена файлов SQL в предзаданной >> директории (по аналогии с темлейтами любого вебпроекта) >> >> 5. реализует следующий набор подстановок в SQL >> >> ?{путь} - просто подставляет переменную >> ?@{путь} - подставляет массив переменных (через запятую) >> ?%{путь}{поле,поле,...} - подставляет массив переменных (через >> запятую) из массива хешей >> >> ну и на вс случай сделали >> ?sub{перловый код} >> >> >> А так же набор условных подстановок вроде >> >> ?if[de]?{путь}{ блок который вставится }{else-блок} >> >> условия - if - истина >> ifd - определен >> ife - имеется >> >> Блоки можно вкладывать друг в друга. >> >> пути - по сути путь к переменной во входном хеше, то есть >> >> $dbh->do($sql, values => { ids => [1, 3, 5] }, abc => 'def'); >> >> путями являются >> 'values' >> 'abc' >> 'values.ids' >> >> и так далее. >> >> поддерживаются в путях и объекты >> >> path.to:method - будет вызван метод объекта, а значение им >> возвращенное будет вставлено в SQL. >> >> >> В итоге что получили: >> >> 1. SQL вынесен в отдельный каталог (отдельные каталоги) примерно так >> же как вынесены темплейты в любом вебпроекте >> 2. типичные SQL-вещи делаются просто. Сложные тоже можно делать. >> 3. Поскольку итератор по именам методов постарались сделать >> совместимым с DBIC то замена одного на другое не вызывает больших >> трудностей. >> >> ну и возьмем пример: >> >> скажем приходит от пользователя форма >> >> $filters = { region => 'Москва', street => '' }; >> >> То есть он фильтр по региону заполнил, а фильтр по улице нет >> >> запрос может выглядеть так >> >> SELECT >> * >> FROM >> tbl1 >> LEFT JOIN tbl2 ... >> >> WHERE >> something = .. >> >> ?if{filters.region}{ AND region = ?{filters.region} } >> ?if{filters.street}{ AND street = ?{filters.street} } >> >> и так далее. >> >> Получается SQL перестраивается в зависимости от того что там вводит >> пользователь. >> >> Осталось нерешенными некоторые типовые вопросы, но мы их планируем >> порешать в ближайшее время (например подставновки частей в >> like-секции) >> >> соответственно вопросы: >> >> 1. кому-нибудь интересна подобная система, стоит класть на CPAN? >> 2. может на эту тему есть что-то готовое да мы велик очередной ваяем? >> тогда ткните указкой:) >> -- >> Moscow.pm mailing list >> [email protected] | http://moscow.pm.org > > > > -- > Andrei Protasovitski > < andrei[dot]protasovitski[at]gmail[dot]com > > Diemen, Netherlands > > -- > Moscow.pm mailing list > [email protected] | http://moscow.pm.org > > -- WBR, Yury Pats skype: yuripats cellular: +375 (29) 5870723 -- Moscow.pm mailing list [email protected] | http://moscow.pm.org
