1

I have a perl hash that I want to save in a database field (MySQL) so that I can retrieve it for update right away.

Inversely, I want to define a datable field (MySQL) that's intended to save the perl hash.

Is this possible and what would be best practice to achieve it?

1
  • 2
    If a lot of your data are like this, consider using a NoSQL database like MongoDB. Commented Oct 15, 2015 at 13:09

3 Answers 3

3

It's not possible, because a hash is a data structure in memory. It may have pointers, buffers etc.. You therefore cannot just shove that into a tablespace.

What you can do is serialise it. Turn it into a single "thing" which you can then stash and retrieve.

You can use a variety of ways of doing this - some common ones might be:

  • Storable (core in perl, produces binary data and not particularly portable).
  • JSON - pretty common and therefore portable. Produces plain text.
  • XML - similar to JSON, but with some different usage scenarios.

Which you use depends very much on what you're trying to accomplish. A very crude example might be to use freeze/thaw from Storable and encode it to text via base64.

use strict;
use warnings;
use Storable qw ( freeze thaw );
use MIME::Base64;

my %test_hash = (
    "fish"   => "paste",
    "apples" => "pears"
);

my $frozen = encode_base64 freeze( \%test_hash );

my %new_hash =  %{ thaw (decode_base64 $frozen ) };
print Dumper $new_hash;

But this really does raise the question - why are you trying to pack a hash - which is a data object - into a database - which is built for handling data objects. You get the worst of both worlds by doing so, because your database will be effectively blind to the hash content. I would suggest that you need to rethink what you're trying to do here.

Edit: You can technically do this with Data::Dumper as well - which prints a variable to text, which you can eval. This is a bad idea, since whilst it looks like it works with trivial structures, there are some gotchas (e.g. 'parent' references). And you still have to read it back in and parse it, which is what you would have to do with JSON or XML. You you end up with the worst of all worlds tackling it this way.

Sign up to request clarification or add additional context in comments.

2 Comments

Meh, you were faster. Nice one.
A few additions though. Point out that Data::Dumper is not the right way to do this and mention Sereal.
1

It doesn't sound like a good idea, see jeffa's reply to similar thread: Store hash in mysql

I would suggest using Storable to store your data structure in a file

use Storable;
store \%hash, 'file';
my $hashref = retrieve('file');

You could try the below though:

my @keys = keys %hash;    
my @values = values %hash;

my $sth = $dbh->prepare("INSERT INTO tablename(id, value) VALUES (?,?);");

$sth->execute_array({},\@keys, \@values);

1 Comment

That is, you suggest to create a table where the column names would be the keys of the hash, and the field values would be the values of the keys? How would I present such a table on the logical/physical data model of the DB? At a given time, the DB would have 1000 of such tables! What names (dynamic) will I give to those tables? How would I delete these table when I delete one entry in another table that the sub tables are referring to?
0

If you are sure that your data can be serialized to JSON, you can use a column with MySQL's JSON data type.

"As of MySQL 5.7.8, MySQL supports a native JSON data type that enables efficient access to data in JSON (JavaScript Object Notation) documents."

1 Comment

Would have to upgrade from 5.6 to 5.7.8

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.