NYCPHP Meetup

NYPHP.org

[nycphp-talk] ORM vs SQL: the ultimate showdown

Mark Armendariz lists at enobrev.com
Sat Sep 15 15:24:30 EDT 2007


I'm a huge fan of SQL, and I've been using it for over 10 years.  its a 
solid and reliable friend.  But it seems to be far too wordy and gets 
hairy to maintain, which is why we tend to look for ways to modularize 
it within our programming languages.  When using SQL, we're just working 
with strings.  mysql_query('SELECT * FROM customers') is as painful as 
using innerHTML in javascript.  In some instances, you just have to, but 
it 'feels right' to use the DOM, and the DOM allows so much more power 
from a javascript perspective.

This might seem completely ridiculous and tear the idea to shreds if you 
must, but I've been working on a library with it's own query language 
that creates both the SQL and the PHP Objects to reference everything 
returned.  Though I've been working on it for quite some time, it's 
still too early (read: messy) to offer it to the masses (I'm 
successfully using it in 4 of my current small to medium sized projects). 

Over the past 10 years, every time I try to keep all my queries in one 
place, whether it be with SQL or with some objects representing my 
Database Tables, i end up with a bunch of functions named getCustomers, 
getCustomer($id), getCustomersInNy, getCustomersInTristate, so instead I 
made a language that allows something like:

get customers
means
SELECT * FROM customers

get customers 425
means
SELECT * FROM customers WHERE customer_id = 425

get customer last_name d, first_name d, full_address where customer_id = 1-5
means
SELECT c.first_name, c.last_name, a.address_1, a.address_2, a.city, 
a.province, co.country_title FROM customers c LEFT JOIN addresses a on 
c.customer_id = a.customer_id LEFT JOIN c.countries ON a.country_id = 
c.country_id WHERE customer_id = 1 OR customer_id = 2 OR customer_id = 3 
OR customer_id = 4 OR customer_id = 5 ORDER BY c.last_name DESC 
c.first_name DESC

and
find mark in customers, addresses, countries
means
SELECT * FROM customers c LEFT JOIN addresses a on c.customer_id = 
a.customer_id FROM customers c LEFT JOIN addresses a on c.customer_id = 
a.customer_id LEFT JOIN c.countries ON a.country_id = c.country_id WHERE 
c.first_name LIKE '%mark%' OR c.last_name LIKE '%mark%' OR c.username 
LIKE '%mark%' OR a.address_1 LIKE '%mark%' OR a.address_2 LIKE '%mark%' 
OR a.city LIKE '%mark%' OR a.province LIKE '%mark%'
OR co.country_title LIKE '%mark%'
(all the string fields in all pertaining tables)

All the joins are dynamically generated, and those generations are 
cached, so it only needs to figure out the joins once.  All the queries 
are dynamically generated as well (obviously) and cached, but if a new 
field is added, the cache is cleared and all those selects are re-cached 
with the new fields (or removed fields removed from queries)

The return can be an array of results, an iterator or an object with 
access to the selected tables and fields (with values set and more 
detailed properties for formatting and manipulation).  The returned 
array can have the data formatted as well.

I haven't done the inserts and updates language yet, but all the fields 
have types (url, email, USPhone, textile, textileComment, alpha, 
alphaWithPunctuation, Integer, DateTime etc), so all the proper 
filtering and escaping is done automatically as is.  Even though the 
language doesn't have inserts and updates, I've been using the type 
objects for proper field handling and filtering (rather than 
add-slashing everything)

Anyways, to me this seems to be the way to go.  If we're dealing with 
strings anyways, we might as well keep those strings short and sweet and 
most importantly dynamic.  It should be portable (any database or any 
model, really) and simple.

The biggest argument I tend to hear is that restricting fields in php is 
silly, but I largely disagree.  By filtering inputted data, we're 
already typing these fields, and usually incorrectly.  Strict typing and 
a dynamic language fit together well as you are allowed the choice of 
either.

Ideally I'd be able to get this into an extension at some point, but I'm 
still getting things organized.  I'm currently in the process of 
rewriting the type classes to make the more modular / portable (if 
anyone has experience in the realm of creating a type system, please 
give me a shout off-list)

Anyways, that's my take on SQL and ORM.  Both - with an easily 
manipulated and portable meta language.

Mark Armendariz



More information about the talk mailing list