How to use Zend_Cache Identifier?
I think I'm getting crazy, I'm trying to implement Zend_Cache to cache my database query. I know how it works and how to configure.
But I can't find a good way to set the Identifier for the cache entries. I have a method which searches for records in my database (based on an array with search values).
/**
* Find Record(s)
* Returns one record, or array with objects
*
* @param array $search Search columns => value
* @param integer $limit Limit results
* @return array One record , or array with objects
*/
public function find(array $search, $limit = null)
{
$identifier = 'NoIdea';
if (!($data = $this->_cache->load($identifier))) {
// fetch
// save to cache with $identifier..
}
But what kind of identifier can use 开发者_运维百科in this situation?
The identifier should be a unique string to represent the cache entry.
You might like to name them based on your database tables and fields, e.g. db_tablename_primarykey_1
If you have a method with several arguments, it'll be a pain to make a string containing all of them. Alternatively you can concat a function's arguments and the db_tablename to produce a string for hashing. For example:
$identifier = md5('db_tablename_find' . serialize(func_get_args()));
You may want to consider using Function frontend for Zend Cache, where you can do something like this:
$cache->call('veryExpensiveFunc', $params);
and the key would be produced automatically (could be a long-ish one, though). You may use Class frontend which would allow you to cache all methods of the class, transparently.
I'm having this same issue. I don't know if you found a solution yet but i have a temporary solution (because it's not very efficient):
Create a cache directory for each table you are going to query and cache results.
Whenever you query that table, save the result using a unique id. Here's the problem with my solution. You can't use the query as an id since it may be too long and some operating systems may reject it. So what i came up with is to store all queries in another file along with an auto-incrementing id, like this:
0->>SELECT * FROM table 1->>SELECT * FROM table WHERE foo = bar
You get the idea. So before executing the query check that file to see if the current query is there, if present, get the id and load using that id. You can store this file in the same cache directory.
- Whenever you update, insert or delete data in that table simply clean the cached records like this: $cache->clean('all'). You don't need to delete the id's file since the same queries will be run. And in case you are wondering, it will only clean cache files in that directory, hence the need for a directory for every table.
The good. You don't even have to set a lifetime (they can exist forever) or autoclean for ur cache since u clean it yourself whenever you run an update, insert or delete.
The ugly. Any test, load or save will make two (or three, when we need to save a new id for a new query) requests to the file system.
I've used this and it works fine, using Zend_Cache_Core and Zend_Cache_Backend_File. I'm not using the full framework, but I use the Zend_Cache module so if you use the whole framework you may need to create an abstract model class that will be doing the creating of directories, id files, and caching for your model child classes (which will then extend it).
I've seen here that using md5 may be a solution to having to create an id's file for every table. I'll try it out and get back to you. I don't know how this would work with Apc.
What happens when your underlying data changes? Well, all applicable cache records should be scrapped. That's a mondo can of worms!
How about offloading this data caching to your RDBMS?
For example, MySQL Query Cache handles this for you, invalidating stale cache records as appropriate.
精彩评论