Where do you "Load Balance" an ORM in a PHP MVC Application - php

The Problem: Object models built using an ORM often need to perform multiple queries to perform a single action. For example a "get" action may pull information from multiple tables, particularly when you have a nested object structure. On complicated requests these queries can add up and your database will start blocking long before it would if you were manually writing SQL.
The Question: Where do you load balance the ORM to cut down on the number of queries that need to be made, and more importantly why did you choose this approach? Do you have separate models to load data dependent on context, or do you specify which data should load in the controller? Or something else?

ORM is really there for a good reason -- to speed up your development.
If performance becomes an issue for me, I'd rather implement some caching mechanisms instead of taking a step back and hard-coding SQL.

I recommend using the Domain Model pattern, to provide an interface to data data in an OO-friendly way. As part of the implementation of persistence within your Domain Model classes, it's appropriate to use a mix of ORM and SQL.
For instance, you'll have some simple queries against a single table. Use a convenient ActiveRecord pattern for this. But as you describe, you'll also typically need some complex queries against multiple tables for more complex related data. ActiveRecord is a clumsy solution in this case, so use plain SQL. It's the best tool when you need a complex query with relational operators like JOIN or GROUP BY.
#pestaa mentions caching which is another good tool. Here's another one you can consider: Identity Map. The point is that you should learn multiple tools, and think about which one is the best in any given situation.
Trying to use only one pattern for every situation is like driving your car everywhere in first gear.

A lot of it depends on the ORM, its philosophy and features. But assuming you've got a good set of model classes between your ORM and the rest of your application, you can do the following:
Provide methods in your models that provide the right amount of depth for most cases. If your ORM doesn't allow you to specify things efficiently, consider a different ORM (if you have that luxury)
Plan and implement caching. Since we're talking in a data-centric context, this means writing/leveraging data caching in your model.
Have a plan to split reads from writes. Either in your model or ORM configuration. Especially if reads are your bottleneck, using some replication to create a gang of read-only slaves can be immensely useful. However, if you don't plan for it, you can easily design yourself into a position where it's a pain.

Related

What is the main advantage of active records in codeigniter?

In codeigniter PHP framework we can use normal SQL query and also we can use active record. Here i have understood active record syntax is less than normal SQL queries.
Can any one tell me what is the main advantage of active record in codeigniter?
Thanks in advance
The Active Record design pattern provides an easy way to handle the data (create/load, modify, update, delete) without the need to take care of the technical details.
Its main drawback is that it makes the unit testing impossible without using a database (which increases the test execution time a lot and breaks the isolation needed by the unit testing.)
Why the creators of CodeIgniter have chosen to use Active Record as their main way to implement the data persistence in the framework? I don't know.
Use it as it is or step forward and use another framework.
This is like comparing SQL with the ORM features because ACTIVE RECORD works as ORM in CI.
Here is the list of benefits of ORM:
Productivity: The data access code is usually a significant portion
of a typical application, and the time needed to write that code can
be a significant portion of the overall development schedule. When
using an ORM tool, the amount of code is unlikely to be reduced—in
fact, it might even go up—but the ORM tool generates 100% of the
data access code automatically based on the data model you define,
in mere moments.
Application design: A good ORM tool designed by very experienced
software architects will implement effective design patterns that
almost force you to use good programming practices in an
application. This can help support a clean separation of concerns
and independent development that allows parallel, simultaneous
development of application layers.
Code Reuse: If you create a class library to generate a separate DLL
for the ORM-generated data access code, you can easily reuse the data
objects in a variety of applications. This way, each of the
applications that use the class library need have no data access code
at all.
Application Maintainability: All of the code generated by the ORM is
presumably well-tested, so you usually don’t need to worry about
testing it extensively. Obviously you need to make sure that the
code does what you need, but a widely used ORM is likely to have
code banged on by many developers at all skill levels. Over the long
term, you can refactor the database schema or the model definition
without affecting how the application uses the data objects.
You can change the backend database anything as you don't need to
worry about query syntax as you are playing with OBJECTS instead of
queries.
It definitely makes your code cleaner to read, and I only not use it when I have to do some seriously complex SQL stuff, like building multitable search queries. I recommend it for its code cleanliness highly.
It helps to prevent Sql Injection.
But for some complex sql queries you can prefer your normal sql queries.

how to separate data access layer in codeigniter

I used to write the data access functionalities in model itself. Now I want to separate data access from business logic. I am using codeigniter as framework.
It seems that one way of doing it is use ORM, but it will have a performance penalty I guess.
are there any general best practices?
Have a look at POEAA's Data Source Architectural Patterns:
Table Data Gateway
Row Data Gateway
Active Record
Data Mapper
CodeIgniter claims to use ActiveRecord, but it doesnt. It's more like a rudimentary QueryObject. To truly separate your DAO from your Domain objects, you have to use a DataMapper. Depending on the complexity of your mapping needs you can build one yourself or use an ORM. Ironicaly, the majority of ORMs in the PHP World are based on ActiveRecord, which is pretty ill-suited for ORM. Doctrine 2 is the only I know that uses a DataMapper approach.
An ORM will always come with a performance penalty (and it can be a serious one). However, you should not rule out an ORM just because of that. Handcrafting an efficient DataMapper in a high impedance mismatch scenario can be tedious and difficult work. Again, see POEAA for a list of common Object-Relational patterns.
There seems to a DataMapper implementation for CodeIgniter with Overzealous DMZ. I have never worked with it and cannot say anything about it. It just came up after a quick google, so I thought I add it here.

Is it a good idea to use CodeIgniters Active Record library to manipulate MySQL databases or should I just use SQL?

I'm starting to get to grips with CodeIgniter and came across it's support for the Active Record pattern.
I like the fact that it generates the SQL code for you so essentially you can retrieve, update and insert data in to a database without tying your application to a specific database engine.
It makes simple queries very simple but my concern is that it makes complex queries more complex if not impossible (e.g. if need for engine specific functions).
My Questions
What is your opinion of this pattern especially regarding CodeIgniters implementation?
Are there any speed issues with wrapping the database in another layer?
Does it (logic) become messy when trying to build very complex queries?
Do the advantages out way the disadvantages?
Ok, First of all 99% of your queries will be simple select/insert/update/delete. For this active record is great. It provides simple syntax that can be easily changed. For more complex queries you should just use the query method. Thats what its for.
Second, It provides escaping & security for those queries. Face it, your application probably will have hundreds if not thousands of places where queries take place. Your bound to screw up and forget to properly escape some of them. Active record does not forget.
Third, performance in my experience is not dramatically affected. Of course it is but its probably around .00001 per query. I think that is perfectly acceptable for the added security and sanity checks it does for you.
Lastly, I think its clear that i believe the advantages are far greater than the disadvantages. Having secure queries that even your most junior developer can understand and not screw up is a great thing.
What is your opinion (sic) of this pattern especially regarding CodeIgniters implementation?
Can't say much about CI's implementation. Generally I avoid AR for anything but the simplest applications. If the table does not match 1:1 to my business objects, I don't use AR, as it will make modeling the application difficult. I also don't like the idea of coupling the persistence layer to my business objects. It's a violation of separation of concerns. Why should a Product know how to save itself? Futher reading: http://kore-nordmann.de/blog/why_active_record_sucks.html
EDIT after the comment of #kemp, I looked at the CI User Guide to see how they implemented AR:
As you can see in PoEAA an AR is an object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data. This is not what CI does though. It just provides an API to build queries. I understood that there is a Model class which extends AR and which can be used to build business objects, but that would be more like a Row Data Gateway then. Check out PHPActiveRecord for an alternate implementation.
Are there any speed issues with wrapping the database in another layer?
Whenever you abstract or wrap something into something else, you can be sure this comes with a performance impact over doing it raw. The question is, is it acceptable for your application. The only way to find out is by benchmarking. Further Reading: https://stackoverflow.com/search?q=orm+slow
EDIT In case of CI's simple query building API, I'd assume the performance impact to be neglectable. Assembling the queries will logically take some more time than just using passing a raw SQL string to the db adapter, but that should be microseconds only. And you as far as I have seen it in the User Guide, you can also cache query strings. But when in doubt, benchmark.
Does it (logic) become messy when trying to build very complex queries?
Depends on your queries. I've seen pretty messy SQL queries. Those don't get prettier when expressed through an OO interface. Depending on the API, you might find queries you won't be able to express through it. But then again, that depends on your queries.
Do the advantages out way the disadvantages?
That only you can decide. If it makes your life as a programmer easy, sure why not. If it fits your programming needs, yes. Ruby on Rails is build heavily on that (AR) concept, so it can't be all that bad (although we could argue about this, too :))

PHP data access design patterns to complement an ORM

I've currently got a site that depends on an Active Record pattern using the Doctrine ORM in PHP. I'm generally a fan of this approach - it's very straightforward and works well for managing for simple CRUD apps. But as this site grows, I think my need for more robust domain functionality will grow as well. I was wondering what other kinds of data design patterns work well in conjunction with an ORM.
My basic problem right now is that Doctrine seems to work best as a fancy querying language, so my models are littered with methods like:
function getBySomeClassfication($classification)
{
return Doctrine_Query::create()
->select('stuff')
->from('ModelClass')
->where('something = ?', $classification)
->execute();
}
or if I want to access a model class directly:
Doctrine::getTable('ModelClass')->findAll();
This means I end up working with Doctrine's object wrappers instead of directly on my domain objects. I feel like all this should exist at a lower level of abstraction.
I'm just not quite sure what the best approach is. I feel like the ORM is an excellent layer for querying single tables and dealing with relationships. But I'd like to have more flexibility in creating domain objects that work across multiple models/tables.
I've read up on using the Repository pattern, but still have a few hesitations:
I don't want to just create a pointless layer of abstraction that simply bubbles up the original problem.
I don't want to re-create or render useless the whole point of using an Active Record ORM.
Any thoughts or suggestions?
You need to work with the object wrappers (Data Access Objects) at some point and at some point your calls will be implementation (here Doctrine-) specific. It mainly depends on your current architecture on how many layers you want to put in between, but I would say - as less as possible. Is there any specific problem you have that Doctrine doesn't solve?
I sometimes don't see the point in having to deal with database specifics (e.g. one Domain Entity spreading over several tables) at all when using the ORM as a tool for (from scratch) Object Oriented Domain Model development.
I recently answered a more Java specific question here, but maybe it helps you, too for the architecture idea.
You might have a look at the Zend Framework ORM implementation(if you haven't already) where it is also possible to define relationships across multiple tables.
I hope that helps.

Is it overkill to put MySQL select statements in a class and CRUD statements in a child class?

I have 2 classes for accessing the database:
MovieDAO - access database using "select" statements only; the purpose is for retrieving data for displaying in the web browser.
and
MovieExtendedDAO (extends MovieDAO) - which is more complete and allows for creating/updating/deleting a movie in addition to the inherited functionality. This class is intended to be used only in the site's administrative area.
I have been told it is overkill to separate it like this.
Is this is a normal way to do things or part of a design pattern? Or is there no real benefit to doing this? My main intention was to simplify things for the public side: a kind of optimization for how much stuff needs to get loaded up and also what kind of things can happen on the public (non-admin) side. Thank you for your comments!
it's not a bad method, it's basically a row data gateway. in that sense i would think of your movieDAO as more of a finder, (same terminology fowler uses), and your movieextendeddao as a gateway (ie MovieFinder, and MovieGateway).
once you start getting more complex domain logic (ie calculating various things about movies) then you can look at some other data access patterns, but your approach seems reasonable for what you're doing.
It's not overkill. Sure, there are better ways of limiting access to your code. But what you are doing is separating retrieval of data (an array of records) from modifying data (single record, instance).
Perhaps you could give your classes different, more meaningful, names. Instead of MovieDAO you could use MovieQuery and instead of MovieExtendedDAO you could use Movie. You keep the funct. separated as you have now, but make the classes more self-explanatory.
You should consider why you are separating the classes. If it is for performance sake (not to load a bigger class for simple reads), than you are most surely optimizing prematurely. You should not make such decisions until you can tell from actual data that such a need exists (which in my opinion will never happen. Use APC or some other bytecode cache if you are worried about large classes).
Regarding permissions - this is something that should be application logic, and not be physically separating the methods into different classes. Also, aren't you extending a basic DAO that abstracts such operations? you will not be implementing separate insert/delete/update methods on each model will you? those operations don't vary much and should belong in a common parent class.
I suggest you have a look at some good open-source implementations for database abstraction in PHP, such as Zend_Db (which I highly recommend).
The main problem I see here is that you are mixing permissions ( Control ) with database access ( Model ). I goes against the Model - View - Controler architecture but no I am not saying everybody needs to use it. It is a kind of complex pattern. It may have advantages over your solution. Does a change in your permissions affect your class model? I think so.
Appart from MVC there may be other ways to control access. At the database ( by users, for example ).

Categories