whohasit has asked for the wisdom of the Perl Monks concerning the following question:

We have some persistent mysql storage happening with simple hashes (comma-separated lists ["key,value"]).

The application reads them in using:

%hash=split(',', $val)
where $val is the returned SQL column value.

Updating the hash (rare) does the reverse using:

$val=join(',',(keys(%hash)))
Can somebody recommend a better, more effecient (and safer) way to do this?

Bill

20050707 Edit by ysth: change pre tags to p & code

Edit: g0n - changed title from "Effecient hash storage?"

Replies are listed 'Best First'.
Re: Efficient hash storage?
by friedo (Prior) on Jul 08, 2005 at 06:03 UTC
    Storable will take up less space in the DB (and it supports nested structures and just about everything else you throw at it.) Its output is not human-readable, though. It is probably not as fast as split for a simple hash, but you should Benchmark to find out what works best.

    YAML is fairly space-efficient and easily readable and editable by a human, though it does require lots of whitespace, which may not be appropriate for your database design.

    Data::Dumper will spit your structures out in native Perl code, which is can be retrieved from the database and evaled. It is a security risk, depending on who has access to your database. Once you're evaling stuff, you can put any code in there.

      Thanks for your fast response.

      So, I was concerned about Data::Dumper for the reason you outline above.. (and I've never used 'eval' for roughly the same reason that I don't own a TV or a Playstation).

      Are you suggesting YAML is the faster solution (faster than split)?

      I recognize that there are different tools for different jobs but is there any consensus on a simple, portable method for effecient storage ("freeze/thaw") of session hashes that remain mostly read-only?

      Thanks again,

        Define 'mostly' read-only.

        From the sounds of things for what you're doing, you're basically making a configuration file of some sort, so you might want to look through CPAN for 'config'

        I'm currently using a mix of different styles -- XML, unix-esque (key=value), and tab deliminated tables, even within the same project.

        Every situation has slightly different needs, and each method serves a different set of needs. (eg, I'm using XML on stuff that has a heirarchical relationship, with a potential for null or multiple values for some attributes (of which the attributes may be added to later), and may be used in completely other programs, not necessarily written in perl; key=value pairs for items that are a flat list, and don't have multiple values; tab delim tables for records with a fixed number of non-null attributes)

Re: Efficient hash storage?
by rev_1318 (Chaplain) on Jul 08, 2005 at 13:26 UTC
    Updating the hash (rare) does the reverse using:
    $val=join(',',(keys(%hash)))

    No it doesn't. Your original $var contains key-value pairs, whereas the code for the reverse you show contains values only. To get the reverse, you need something like:

    $val = join(',', %hash);

    Paul

Re: Efficient hash storage?
by revdiablo (Prior) on Jul 08, 2005 at 16:25 UTC
    We have some persistent mysql storage happening with simple hashes (comma-separated lists ["key,value"])

    This is a huge code smell. You should not have to delimit or otherwise worry about the storage of your data. That's what the database is for. A better approach might be to have two separate columns in the table instead of just one. You could name them key and value. Then you wouldn't have to worry about efficiently storing the pair -- the database engine would worry about it for you.