How does one use the RDBMS in a performant way on top of Zend_Db_Table? (if at all…)

↘锁芯ラ 提交于 2019-12-01 13:14:54

I agree with you that Zend_Db_Table sometimes acts as a hammer in search of nail. It's not always the most natural tool for writing customized, performant queries with joins. It seems to me that Zend_Db_Table is optimal primarily for a single table without joins. But it is still possible to do optimal db querying using aspects of the Zend_Db component.

As noted by @singles, all this db access should probably be buried inside a model (for an ActiveRecord type of approach) or in a mapper (for a DataMapper approach) or in an entity manager (like Doctrine2) does.

For exmaple, your custom BlogPost model could be fed an instance of a custom BlogPostDataAccess which would be fed an instance of Zend_Db_Adapter. All your queries - including your optimized joins - would reside within the BlogPost_DataAccess class. The SELECT queries in the DataAccess class could be written using soemthing like (pseudocode):

$select = $adapter->select()
        ->join()
        ->join()
        // etc.
        ->join()
        ->where()
        ->limit()
        ->order();

See what I mean?

Update

How about a $tableMap member variable? Something like:

public static $tableMap = array(
    'posts'        => 'table_posts',
    'users'        => 'table_users',
    'categories'   => 'table_categories',
    // etc
);

Then in your queries, you could use something like:

$select = $adapter->select();
$select->from(self::$tableMap['users'], array('name', 'email'));

Maybe add methods called setTableMap($tableMap), getTableMap(), getTable($k), setTable($k), store the initial mapping data in a config file and then populate the static member during bootstrap.

Some points need clarification:

  1. Like you said - Zend_Db_Table doesn't implement "auto join", in another way could be called eager loading. If you need such a functionality, take a look at PHP-AR
  2. It's possible to implement eager loading in Zend_Db_Table on your own - I spent some time thinking about it, and I'm pretty sure, that it can be done. But I don't have time to do it :)
  3. But looking from the other side - Zend_Db_Table is a part of model of your app. You should worry how your data are fetched, you're interested in data itself. Going further - if you use fat model, thin/skinny controller attitude, you can implement join that you need inside method in quick way, which will be sufficient for most of cases.
    Example: http://pastebin.com/pNwideWf (I'm linking to paste bin, because code formating don't work properly for me in editor).

Unfortunately, using that aproach, you won't be able to save data in joined tables, and you must watch out with column names: you can't do $row->joined_table->field_from_joined_table - instead of this you can $row->joined_table_field_from_joined_table.

Summarizing - if you want performance, use fat models as mentioned before - store all logic of fetching/filtering data in model classes, in your case Zend_Db_Table.

Take a look at NotORM database layer. That might do what you need ;)

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!