MySQL Active Record

Возможно ли используя Active Record произвести к базе данных такой запрос:


SELECT * FROM `DATA` WHERE price between 500 and 3000

или использовать только DAO. И намного ли быстрее DAO по сравнению с Active Record на высоко нагруженных проектах?

Hi, sorry for the English since not be a Russian, as I translate from systran you ask about AR etc.

I thing you have to look at condition section of active record (reading record).

As I remember AR is slower.

A traslation (that I will not copy/paste) at systran that probably has errors :)

Thank you. The fact that it is necessary. :rolleyes:

AR не рекомендуется использовать на проектах высокой нагрузки. Она не для этого писалась ;)

У меня тоже вопросы по AR только другого плана




    public function actionFavourite(){

        $criteria=new CDbCriteria;


        $criteria->params['user_id'] = Yii::app()->user->id;

        $criteria->join = 'INNER JOIN `FavouriteCar` AS `fa` ON `fa`.`User_id`=:user_id AND `Car`.`id`=`fa`.`Car_id`';


        $pages=new CPagination(Car::model()->count($criteria));

        $pages->pageSize=self::PAGE_SIZE;

        $pages->applyLimit($criteria);


        $models=Car::model()->findAll($criteria);


        $this->render('list',array(

            'models'=>$models,

            'pages'=>$pages,

            'alphaVisible'=>false,

        ));

    }



В начале как самое простое решении у меня был запрос

… Car.id IN (SELECT Car_id FROM FavouriteCar WHERE …)

путем копания в доках и методом научного тыка удалось его заменить на INNER JOIN

теперь вопросы

  1. Можно ли используя AR реализовать запрос вида

SELECT Car.* FROM Car c, FavouriteCar fc WHERE fc.User_id=:user_id AND c.id=fc.Car_id.

если да то как? - я не могу разобраться

  1. чиcто теоретический вопрос - какой запрос будет быстрее с INNER JOIN или с WHERE

спасибо

Прошу прощения, а для чего АР тогда писалась ?

Конечно AR медленнее… однако! в высоко нагруженных проектах особенно когда упираются в БД используют кеш

Но в любом случае АR писалась для ускорения разработки. а уже из этого вытекают все другие моменты (ЗА и ПРОТИВ).

Все сильно зависит от выбранной вами архитектуры Вашего приложения

Но ведь кэш можно использовать через АР ?

Если нет, то тогда как только встречаешь достаточно большую нагрузку, создающую проблемы, приходится переписывать

на raw sql ?

Проблема AR в том что она вместо обычного массива данных возвращает вам коллекцию связаных обьектов с кучей избыточных данных. Поэтому для удобства AR - очень хорошая штука, часто упрощает жизнь. Но на крупных проектах с высокой нагрузкой надо все оптимизировать, и нет ничего проще чем брать именно те данные которые вам нужны через DAO, не полагаясь на AR.

Вам ничего не мешает вести разработка на AR, а в будущем перегрузив методы AR типа findAll и тп - использовать DAO. Помню на форуме кто то хвалился что так и делает

Понятно, спасибо

Хуже идеи быть не может. ActiveRecord не только упрощает разработку. В первую очередь он способствует написанию КРУПНЫХ масштабируемых(!) приложений. Очень облегчает жизнь при коммандной разработке. Да, он медленнее чем DAO, но это окупается скоростью разработки и снижением её себестоимости. К тому же, при использовании кеширования, разница между приложением целиком написанным с использованием AR против DAO по скорости будет мизерно ощущаться только при обновлении кеша. Переходите на DAO - теряете масштабируемость. Если используете mixins(Behaviors) при переписывании на DAO получаете ещё и геморрой. Если используете ещё в добавок сложные Behaviors типа EAV, то вычитаете из жизни год и переписываете, в итоге получаете вермишель.

Alexandr Dorogikh

Вариантов реализации этого на AR много. Все зависит от того, какие relations() в моделях вы себе можете позволить. При грамотно настроенных отношениях в моделях запрос любимых машин может выглядеть, как 1 из вариантов




$user=User::model()->findByPk(Yii::app()->user->id);

$favoriteCars=$user->favoriteCars;



Код в модели User:




function relations()

{

    return array(

        'favoriteCars'=>array(self::MANY_MANY,'Car','FavoriteUserCar(userID,carID)'),

    );

}



Копайте в сторону CActiveRecord::MANY_MANY.

С точки зрения SQL сервера никакой разницы. С точки зрения проектировки запроса, за второй вариант где соединение идет в условии будут долго и упорно бить… скорее всего ногами. :rolleyes:

Egorka

Использование BETWEEN в AR элементарно:




$from=500;

$to=3000;

$data=Data::model()->findAll('price BETWEEN ? AND ?',array($from,$to));



creocoder, вы не совсем правы на счет перехода с AR на DAO посредством перегрузки findAll(). Такой подход позволяет сохранить практически всю гибкость AR, но здорово экономит на памяти.

перезагрузив метод findAll вы хотите избавиться от объектов :slight_smile: а Вам толдычут что Да это круто все в массиве но это круто для блога

а для более менее крупного проекта объекты фактически единственный способ выживания.

to creocoder

А вы пробовали прежде чем говорить? С таким подходом можно смело кричать на весь мир "В жопу оптимизацию. Давай новые сервера!".

Первое правило оптимизации - максимальное упрощение. Отказ от избыточных и ненужных связей и тп. Когда столкнетесь с проектом где хитов 50-100 тысяч в сутки, и живого онлайна за 300 чел - вспомните что такое избыточные данные :)

Но с другой стороны нельзя же оптимизровать так что бы самому было противно с этим работать …

Во всем нужен компромисс.

И способов оптимизации значительно больше чем просто переписывании логики приложения в функциональный вид и RAW SQL.

верно ?

Мнений по этому поводу много, и что самое интересное люди, столкнувшиеся с большими нагрузками, имею разные мнения.

одни за RAW SQL, другие за AR.

кому верить, не понятно.

походу каждый решает для себя что ему более выгодней в его ситуации (

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

Правильно говоришь!

тайный холиварщик и провакатор :slight_smile:

to rosko

Если бы это было правдой, не было бы AR :) Или у вас DAO понимает with(), together() и relations() ? Тогда это уже не DAO, а AR. Завтра может захотеться добавить ->with(‘article.content.author.profile.country’). Что касается findAll() и его аргументов. В качестве $criteria может идти трехэтажное выражение, а с версии 1.1 CDbCriteria понимает ещё и ‘with’. Послезавтра может захотеться что-то поменять в этом criteria. Где вы увидели гибкость?

to Zolter

Вы слишком самоуверены. Уход от ActiveRecord в пользу DAO - это 2 шага назад. Что касается оптимизации, то такая оптимизация сродни похудению методом отпиливания ноги. Что касается высоконагруженных проектов, то там всегда используют кеширование, при котором разница между DAO и AR настолько мизерна, что её почти нет, при сохранении всех неоспоримых преимуществ последнего.

В чем вы увидели избыточность AR объектов? Если вы не заметили, то в последующих эеземплярах, кроме первого идут ссылки. Или вы на страницу по 10000 сущностей выдираете? Максимум 500, в противном случае смело отрывайте проектировщику сайта руки. Вообщем проблема надумана.

Эх вот не можете вы спокойно :)

Делайте как хотите, я это перерос :) Хотите поспорить и по выпендриваться у кого пиписка больше - так вам на хабр. Если по вашему мнению запросы которые строит AR - это прямо верх совершенства - то что я могу сказать? Это круто, вам легко и спокойной живется :)