I’m making a MMORPG game online and I have decided to make it with the beautiful framework Yii. It will be a game played by (hopefully) 10000+ players with a minimum of 200 users online at the same time (History statistics of the previous version of this game).
Now I read the following in the manual:
"Do not overuse Active Record. Although Active Record is good at modelling data in an OOP fashion, it actually degrades performance due to the fact that it needs to create one or several objects to represent each row of query result. For data intensive applications, using DAO or database APIs at lower level could be a better choice."
Somebody knows if it really matters? I just make a AR class per table and call at least 3 of these classes per request most of the time. I also read something about schema caching, does it help a lot?
Now I don’t recognize any problems, of course. But will I run into trouble when there are 200 users playing at the same time?
Schema caching makes a huge difference (search the forum, there where some discussions + benchmarks i think). Also, if you find out that AR is the bottleneck, you still can rewrite the critical queries to pure SQL using DAO (or the upcoming query builder). So, you should always have an option left…
Yes, AR is a bit performance-degradation. It is a very good solution for most of the situations but not for all of them. If you at the very beginning plan that you will have 10k+ users and 200+ users playing on-line at the same time I would strongly suggest using DAO instead of ActiveRecord!
And yes - caching would be one of first things I would consider in your situation.
When I use DAO I can’t use the benefits of a model, right? For example, does CGridView and its sorting/pagination still work?
I also liked the way how models work, I just can add functions to a MoneyModel such as MoneyModel::sendMoney($money, $user); or getMoney($user) etc. Or is it actually better to make a Money component with these functions in it and putting some DAO statements in there? (or model approach) I’m a little bit confused right now, about what the best development workflow is for me.
Also, I like to make the game perfectly in one shot, and I’m not wanting to change everything afterwards and spend months to get all changed from models to DAO.
In my projects i have lots of “DAO enhanced” AR models. That means, whenever it’s easier to do something with pure SQL, i write a method and use DAO. Nothing wrong with that. So i get the best of both worlds: I can use the convenient AR features and use custom “high-performance” SQL statements for critical parts.
Here’s an example for such a method:
public function queryIdsBetween($start,$end,$condition)
SELECT DISTINCT(p.id) FROM project p
INNER JOIN versions v ON v.project_id=p.id AND v.date BETWEEN :start AND :end
As Mike told you. It is written somewhere in the Definitive Guide (sorry, don’t have time to look for it!) ActiveRecord is useful for CRUD operations (Create, Retrieve, Update, Delete) which are 90% of all database operations among 90% of all web projects. In other words, use ActiveRecord where you need some basic operations (like management of users, goods, ships or whatever in your game) and use DAO with pure SQL where you implement game logic or in other way sensitive to performance parts of your game, for which DAO is more convenient.
Even more. Use Gii tool to do all the hard work for you of creating Models and CRUD operations and inside files created for models only introduce some specific functions that uses DAO, just like Mike showed you. His example is pure DAO/SQL function declared inside Model used in ActiveRecord manner.