views:

37

answers:

3

(I use the word var in the following because I'm not sure what it is I think it's a global variable for the class)

I want to cache values that are gotten from a table in a database, to save repeated queries. What I've done is create a singleton class which has a function to check a var within the class if a key exist, if it does then just return the value from the var, if it doesn't then query the database and load it into the var and return it.

Or would a better way of doing it be using a global variable (does a global variable have the same value no matter from which file accesses it?) and not using a class at all.

Or don't bother caching and just query the database every time the value is needed.

Should I post the source of what I've come up with?

+5  A: 

Check out memcached. Its purpose is to do exactly what you just described. It takes a database query and stores the results in memory which has much faster I/O. When the same query is run you check to see if the value is stored in memory and only hit the database if its not. The value of memcached over your current solution is that its persistent across connections.

Justin Lucas
memcached, in addition to persisting across connections, can also be accessed by multiple servers, unlike a cache in a singleton/globals/APC. When you have multiple servers, not being able to share caches rapidly becomes very expensive as you store duplicate cached values on each server.
Frank Farmer
sorry, what do you mean persistant across connections?
Jonathan
When you use a variable (global or not) you can only use it for that one request. So when that user loads the next page, refreshes, or another user loads the page that variable will no long be available in that next "connection". Memcache is persistent across connections because the data will still be available through any page loads, refreshes or other users and even across servers as Frank Farmer pointed out.
Justin Lucas
But surely because it's a singleton class this would not happen as there is only ever one instance.
Jonathan
If you use a singleton class for Memcached the data is not actually stored within the class. The data is stored in the server's memory. The class is simply an abstraction layer for memcached which is essentially a key/value database. The class just gives you access to open/close connections and get/set data the same way a mysql abstraction class works.
Justin Lucas
A: 

It very depends on your queries - how expensive and heavy are they for the database? If it's pretty simple and light queries - I would say caching is not needed (unless you would have really high amounts of them - thousands or millions in short time). For simple repetitive queries your DB probably will also use some kind of query cache - this will also speed things up.

Caching expensive queries would make more sense. Then you can use memcache as suggested, you may also look to APC cache as well.

Laimoncijus
the table is 3 fields: id key and value. They are just simple settings like number of links to show on a page etc. Also there is a site title which would be needed every time someone navigates to a new page.
Jonathan
+1  A: 

If it's just links you could store them in your session meaning they're only created the first time you browse to a page with that on it. If you are able to get all the links up front and store them in the session you can do..

session_start();
setupLinks();

// Getting a link by Link ID
if( ($aLink = getLink(562)) !== null) {
    echo "The Link Title is: {$aLink['value']}<br>";
} else {
    echo "The Link Title is unknown<br>";
}

// Getting a link by Key
if( ($aLink = getLink('my_link_key')) !== null) {
    echo "The Link Title is: {$aLink['value']}<br>";
} else {
    echo "The Link Title is unknown<br>";
}

function setupLinks() {

    // Only do this once, so if the links exist do nothing
    if(!isset($_SESSION['aLinks'])) {
        return null;
    }

    storeLinks(getAllLinks()); // your own custom function
}

function storeLinks($aLinks) {
    foreach($aLinks as $aLink) {
         $_SESSION['aLinks'][$aLink['id']] = array(
              'key'   => $aLink['key'],
              'value' => $aLink['value']
         );
    }
}

function getLink($iLinkID) {
    return isset($_SESSION['aLinks'][$iLinkID]) ? $_SESSION['aLinks'][$iLinkID] : null;
}

function getLinkByKey($sLinkKey) {
    foreach($_SESSION['aLinks'] as $aLink) {
        if($sLinkKey == $aLink['key']) { return $aLink; }
    }
    return null;
}
Paul Dragoonis