SitePoint Sponsor

User Tag List

Results 1 to 13 of 13
  1. #1
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)

    Storing data in session or db?

    I had this vocab program I wrote a while back, that selected words from a database and weighted them based on a system to display incorrectly answered words more often. I kept the weight data in a separate table, and by the time I'd written out the whole program with over 1,000 words and several different users accessing the app, I had quite a bit of weight data and my queries were ending up being far too complicated for me to keep track of.

    I decided to rewrite this program, on the basis that the weights would be much simpler if stored in an array than each in its own row in a separate table. The app loads the dictionary every time it runs, adds weights, and then stores the dictionary/weight array (inside an object) serialized in $_SESSION. This works, but I'm wondering if it's the best way to do it. If I want to save user weights for the next time they log in, I would have to save that data in the database somehow. So I guess I have several options-

    1. Store data in sessons, and save to database on log out
    2. Keep data serialized in a database table, and access with every new word
    3. Store data in sessions, but rewrite session handling to store sessions in database.

    What would be most appropriate?

    thanks,

    Cory

  2. #2
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by allspiritseve View Post
    This works, but I'm wondering if it's the best way to do it.
    Probably not. Sessions aren't meant for caching data. Create a table in your database for that.

  3. #3
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Alright, I've switched to storing user data in a serialized array in the database. I'm now wondering, though, if it might be better to serialize the whole entire object inside the database, as then every time a user checks a card, the "active" card can be saved, and more easily checked since I don't have to pass the card id through the form and back... is there any reason why I shouldn't make an object persistent?

    Edit: I found this post in a different thread:

    "kyberfabrikken: Storing data in the database as serialized objects is a bad practice. Consider using an ORM library instead."

    So now my question is-- why is it a bad practice? What is an ORM library, and why exactly would it be more beneficial or be a better way of programming?

    Thanks,

    Cory
    Last edited by allspiritseve; Oct 22, 2007 at 15:24. Reason: Found more information

  4. #4
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Because when the data is serialized, you've put it in a fireproof, lead-lined box, and buried it 12 feet under the ground. The only way to access the information inside, is to unserialize all of it in PHP. This makes it impossible to use the normal procedures for operating on data in a database. In other words, you can't make a SELECT statement, with a meaningful WHERE clause on serialized data.

    It depends on the context of course; If your data is highly volatile, it may not be worth the effort to use a database. The moment data is used by more than one user, I would say that it shouldn't be serialized any more, but persisted in a database instead. (And by persisted, I mean that data are actually normalized -- not just serialized and stored in a blob)

    Incidentally, I don't think an ORM is useful in this situation, although it's hard to tell without a deeper knowledge of the application.

    ORM means Object-Relational Mapping. PHP has a number of packages, such as Propel and Doctrine.

  5. #5
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well, that's the thing with this data-- it's all user data, each object would never be used by more than one person. All of the data that I want to share, such as which card is active, does not lend itself to being logically stored in a database. It's not data I would need a part of, it really doesn't even have any use without being included with the dictionary and weight arrays. I haven't decided yet whether I even want these stored objects to be kept after a user has logged out; its really just something that is nice to have between each page request during the span of the session.

    So maybe-- I should keep the "active card" id in sessions, and go back to my original method of a new row for every user x every word in the dictionary.

    Cory

  6. #6
    SitePoint Wizard silver trophy kyberfabrikken's Avatar
    Join Date
    Jun 2004
    Location
    Copenhagen, Denmark
    Posts
    6,157
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Do you need all the data on all pages? Serializing/Unserializing is a costly process, if the size of the data is large. If you're concerned that there is a lot of data, you're not doing yourself a favour by moving from database to session -- It should rather be the other way around.

    Quote Originally Posted by allspiritseve View Post
    So maybe-- I should keep the "active card" id in sessions, and go back to my original method of a new row for every user x every word in the dictionary.
    Judging from you description so far, I would say so. You can use a storageengine=MEMORY type table for this (Assuming, you're using MySql). They are very fast, and they are automatically pruned, when the server is restarted.

  7. #7
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Well-- it definitely wouldn't be a lot of data, just an id... the whole reason I moved to sessions in the first place instead of a database was because it would be so much easier to work with an array of (card_id, weight), and simply save the array in sessions, rather than ever time loading a good hundred rows from several thousand in a table just to build the same simple array.

  8. #8
    SitePoint Member
    Join Date
    Oct 2007
    Posts
    22
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    hmmm...

    i'm not shure that i understand your poblem but one thing comes to my mind.
    maybe you should use memory table (as sugested) + store your sessions in database and make forgein key relation (on delete cascade) between session id and your data id so that system automaticly purns your data table on session garbage collection.
    (yes, memory tables purn them self on server reset, but server might be online for a very long time)

  9. #9
    SitePoint Addict
    Join Date
    Sep 2006
    Posts
    232
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I agree with kyberfabrikken, what's strange is that a lot of people are doing it, storing data in the session. Let's take this forum for example, vBulleting, I've never seen something like it. I bet they even thought about storing the user avatar in the session

    Remember that a programmer might take 1 hour to build a small and powerful caching system using the database, while a developer only 1 minute using an array. So if your boss is a marketing guru or enjoys selling stuff, be careful... what a developer builds in 1 minute, might take you an hour. Remember that your boss rewards speed because in his jargon, coding standards or best practices doesn't mean jack. If your boss is a techie, then, that's a different story

  10. #10
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Quote Originally Posted by DevPulse View Post
    i'm not sure that i understand your poblem
    Well, it's not really a problem, its a tiny little program that few people will use, but I've never had any formal programming training, and I was just curious what would be the appropriate way to handle the functionality I desired.

    As far as storing data in sessions-- I agree, I have seen that done a lot.

    Cory

  11. #11
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    Ugh... ok, I'm back to attempting to use a database to store my user data. I am using the following query:

    Code:
    SELECT cards.* FROM cards LEFT JOIN cdlinks ON (cards.card_id = cdlinks.card_id) LEFT JOIN userdata ON (cdlinks.cdlink_id = userdata.cdlink_id AND userdata.user_id = '1') WHERE cdlinks.deck_id = '1'
    However, this results in several entries for the same card.

    How can I construct a query where cards and cdlinks are joined, and then userdata is appended or replaced will null values? I just can't seem to get it right and I'm getting quite frustrated.

    Thanks,

    Cory

  12. #12
    SitePoint Addict
    Join Date
    Aug 2007
    Posts
    365
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    try change

    Code:
    cards LEFT JOIN cdlinks ON (cards.card_id = cdlinks.card_id)
    with
    Code:
    cards INNER JOIN cdlinks ON (cards.card_id = cdlinks.card_id)

  13. #13
    Spirit Coder allspiritseve's Avatar
    Join Date
    Dec 2002
    Location
    Ann Arbor, MI (USA)
    Posts
    648
    Mentioned
    0 Post(s)
    Tagged
    0 Thread(s)
    I've been messing around with the queries a bit, and I think it's because I had duplicate entries in my userdata table for the same cdlink. So it wasn't really the query that was misbehaving, but the application inserting queries instead of updating existing ones.

    Thanks for your help though,

    Cory


Bookmarks

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •