NYCPHP Meetup

NYPHP.org

[nycphp-talk] Database Abstraction / ORM

guilhermeblanco at gmail.com guilhermeblanco at gmail.com
Wed May 9 23:18:13 EDT 2012


Hi Anthony,

It's great to see PHP contributors around. =)
Comments inline.

On Mon, May 7, 2012 at 10:13 AM, Anthony Ferrara <ircmaxell at gmail.com> wrote:
> Hey Justin,
>
> Replies inline;
>
> On Mon, May 7, 2012 at 8:16 AM, Justin Demaris <justin.demaris at gmail.com> wrote:
>> Hello PHP Talkers,
>>
>> How do you guys feel about ORM systems and other database abstraction
>> layers?
>
> Personally, I do not like them.  I find that the ORM layers
> specifically violate SRP (Single Responsibility Principle) and are
> usually not worth while.  Instead, I prefer a light weight Data Mapper
> layer ( http://martinfowler.com/eaaCatalog/dataMapper.html ).  I
> usually hard-code SQL in the mapper, but you *could* use an ORM there.
>  But the key is to keep it completely separated from the business
> objects.  That way your data model is free to evolve independently
> from your business objects...
>
>> Is there any ORM system out there
>> that just does it right? Namely, I'd be looking for things like:
>>
>> 1) When I instantiate an object by it's ID multiple times, it doesn't bother
>> to hit up the database after the first time, but just keeps giving me copies
>> of the same object
>
> Well, do you really want this all of the time?  I can see cases where
> you do want to re-query the database (especially in sensitive
> areas)...

Any good ORM relies on a UnitOfWork.
Under this concept, you can tell it to "forget" about a certain object
or "know" about an object.
Based on that, both perspectives you mentioned are support.

>
>> 2) Lazy load the object values. There are a number of patterns where I've
>> seen people instantiate a bunch of objects and then only use a small subset
>> of them. It would be nice if the object only loaded the data when we try to
>> reference one of its non-ID properties.
>
> Why?  Your business objects should have all the data they need at
> creation time.  Otherwise you can wind up in the situation where
> objects representing the same state have different states.  Which is
> not a good thing...

As I mentioned in the other email, any good ORM tool should deal with
Proxies/References.
If you want to load, or only load partially, you should have this ability.
I disagree with Anthony that is bad. That's the biggest principle to
avoid (and also to cause if misused) the N+1 problem insanely referred
by beginners or ORM haters.

>
>> 3) Ability to tweak the back end to work with other database systems
>> (especially Riak, Mongo and Cassandra)
>
> Unless you're building a project that you want to distribute to
> others, I find this a bad feature.  Sure, it's nice to know you can
> switch to another storage with a config change.  But practically, how
> often do you do that?  And if you do that, you're going to want to
> tune your data model specifically towards the strengths of the target
> backend.  Otherwise you're constantly stuck with a sub-optimal
> solution, and little way out when you need to scale...

I disagree with you, unfortunately.
The time needed for certain operations using certain DB drivers may be
huge for functional testing purposes.
By tweaking your application environment, you can use sqlite:memory
for testing and mysql in prod, running the tests quicker.
I hate advertising too much, but unfortunately, PHP lacks so much of
good competitors of Doctrine. You can use ORM and ODM mappers and
almost swap one with the other and your application can still run
smoothly.

>
>> I have had really good luck in the past working with Yii and integrating
>> with Redis to use their Active Record structure, but I'm not sure of the
>> performance there. Also, I've been hearing a lot about Doctrine 2 lately and
>> the necessity of having an extra Data Mapper layer in the middle that
>> separates the classes and properties from the fields and tables that store
>> the data.
>
> That mapper layer is a good thing...  It allows both to vary
> independently of each other.  Which avoids un-needed coupling between
> the layers.
>
> As far as Doctrine 2 goes, IMHO it's the best layer out there.  I use
> it when I have projects that dictate requirements that it helps fill.
> But usually, I just use the database specific layer (MySQLi or
> MongoDB).

There's a reason why you need a mapping layer.
Depending of your domain problem, you may want for example different
strategies for inheritance. There're 3 types available, but not all of
them are implemented by D2. Class Table Inheritance, Single Table
Inheritance and Concrete Table Inheritance. You can read more about
them at PoEAA of Martin Fowler's book. Each type has pros and cons.
Also, associations may map to a composite foreign-key, you also have
locking strategies to play, etc. All these things must be taken into
account and are not trivial to be done without a mapping layer.

>
> I hope that helps,
>
> Anthony
> _______________________________________________
> New York PHP User Group Community Talk Mailing List
> http://lists.nyphp.org/mailman/listinfo/talk
>
> http://www.nyphp.org/show-participation



-- 
Guilherme Blanco
MSN: guilhermeblanco at hotmail.com
GTalk: guilhermeblanco
Toronto - ON/Canada



More information about the talk mailing list