Я последний SQL-запрос писал, наверное, года два назад :) Так что - вполне уложить можно.
А когда дело до SQL доходит, то, представь себе, я тоже не ручками контактенацией строк запросы писал. А через тот же свой mysql-драйвер, на котором ORM работает. И который вопросы инъекций тоже все на себя сам берёт.
Последний раз SQL-запрос с ручной контактенацией, дай бог, я лет 5 назад писал. И то под Java :D
Ну например, есть тарифы и группы клиентов. Некоторые (не все) тарифы можно назначить некоторым группам клиентов. И нужно сделать админку для этого.
Я сделал так: таблица тарифов, групп клиентов и еще одна таблица, где только два столбца (primary key из id группы клиента и тарифа) и строки только для тех сочетаний, какой группе что назначено. Для админки я строю таблицу: по горизонтали тарифы, по вертикали группы клиентов, на пересечении - чекбоксы. Соответсвенно и запрос будет: тарифы cross join группы клиентов left join применимость.
>Ну например, есть тарифы и группы клиентов. Некоторые (не все) тарифы можно назначить некоторым группам клиентов. И нужно сделать админку для этого.
Каждая сущность - отдельный объект. Простые связи (1xM) делаются чаще в рамках одного из объектов, множественные или унифицированные - отдельными таблицами, для этого есть специальная сущность связей. У меня много подобных связок :)
Для админки я строю таблицу: по горизонтали тарифы, по вертикали группы клиентов, на пересечении - чекбоксы. Соответсвенно и запрос будет: тарифы cross join группы клиентов left join применимость.
Админка не требует высокой производительности, так что я обычно вообще тупо в коде в циклах все нужные данные вытаскиваю и скармливаю их шаблону. 0,5 сек. вместо 0,05 в случае админки погоды не сделают :) Зато получается универсальный вариант, не привязанный не только к бэкенду, но и даже к структуре объектов. Лишь бы методы проверочные совпадали.
Ну, я так и думал. ORM хорошо справляется с задачами «взял из базы по ид - положил в базу по ид». А если надо чуть посложнее, то начинается: либо в цикле долбить базу запросами, либо писать что-то в стиле
и не дай б-же запутаться в скобках или пожелать использовать функции sql.
>Админка не требует высокой производительности, так что я обычно вообще тупо в коде в циклах все нужные данные вытаскиваю и скармливаю их шаблону. 0,5 сек. вместо 0,05 в случае админки погоды не сделают :)
Бугага. Тебе, видимо, не приходилось переписывать админку на plain sql, потому что клиент накидал чуть больше данных, чем в демо-версии, и написанный по всем правилам ORM скрипт перестал пролазить в 30-секундный временнОй лимит. Админка тупо не могла загрузиться то конца (да и хостер начал грозить карами). Я тогда из него выжал 130-кратное ускорение.
>Тебе, видимо, не приходилось переписывать админку на plain sql, потому что клиент накидал чуть больше данных, чем в демо-версии, и написанный по всем правилам ORM скрипт перестал пролазить в 30-секундный временнОй лимит
Нет, не приходилось. Дже с миллионами записей и гиговыми базами админки обычно укладываются в десятые доли секунды :) 30 секунд — это сотни гигов, что ли? Нет, с такими объёмами я не работал, слава Богу :)
Какие сотни гигов? Там вся база уложилась бы в мегабайт. Я подробности плохо помню за давностью, но там было что-то вроде 3-хуровневной вложенности объектов с отношением «один ко многим» и на каждом уровне оно автоматом разворачивалось в цикл для каждого объекта. И доразворачивалось до того, что одних запросов было около 1500 плюс обработка всего этого.
И по 30 секунд в админке?? Что-то тут не так. Мегабайтную базу можно, вообще, целиком загрузить за несколько секунд :)
но там было что-то вроде 3-хуровневной вложенности объектов с отношением «один ко многим»
Боюсь, что это, скорее всего, ошибка в дизайне. Типа, один «вложенный» объект — один запрос. Я обычно в таком случае собираю все нужные ID объектов и делаю один запрос на загрузку массивов.
При чём фреймворк организован так, что можно сперва вообще тупо использовать «ленивую» загрузку связанных объектов (по запросу на объект). Если не хватает производительности — добавляется буквально по 1-2 строчки для предзагрузке этих объектов одним запросом. Скажем, у нас есть массив сообщений форума, $posts. Там есть свойство/метод user_id, возвращающий ID юзера. Загрузка полноценного объекта user — это отдельный запрос. Типа,
{foreach from=$this->posts() item="p"}
<p>Сообщение {$p->title()} написал {$p->user()->title()}</p>
{/foreach}
Тут каждый вызов user() сгенерирует SQL-запрос. Когда дело доходит до оптимизации, мы в контроллере пишем:
function pre_show()
{
bors_objects_preload($this->posts(), 'user_id', 'forum_user', 'user');
// Массив, ID субэлемента, имя класса, куда записывать результат
// user() == bors_load('forum_user', $user_id) для каждого $post
}
и у нас одним запросом загрузятся все объекты юзера в массив постов.
Обычно для 99.9% задач такого уровня оптимизации уже хватает даже для основных страниц с высокой загрузкой. Ну а если не хватает (скажем, страница генерится 0,5 сек., а запросов от пользователей по 100 в секунду), то там уже можно и статическое кеширование включить :)
вы здесь упоролись чтоле?! я вам задал прямой вопрос. началось про ОRM Крона и анонимуса который его донимает. кстати Крон посоветуй что нить для развития скила в php и работай с бд, и что кроме вики почитать про орм.
>кстати Крон посоветуй что нить для развития скила
У меня основной источник всех знаний по PHP — это php.net :) В какой-то степени ещё отдельные статьи, результаты того или иного гугления. Систематически PHP никогда не изучал. С БД аналогично. Ну а когда впервые услышал про ORM и MVC (довольно поздно, надо сказать, и в Java), то уже их использовал на практике, не зная, что они так называются ;)