Going Off the Beaten DB Path (cont'd)
Assigning Multiple Values to a Single Key
Key/value pairs are all very well, but at some point you're going to want to use a larger data structure. There are several ways to assign multiple values to a single key. I'll describe one simple way, and one that is more complex. The simple way is to pack all the fields into one delimited string. If, for example, I want to load the contents of a tab-delimited text data file into a Berkeley DB file, I can do it in the following way:
tie %hash, "DB_File", "myDB";
# open a filehandle on my tab-delimited data file
open (INFILE, "data.txt");
# go through it line by line
while (<INFILE>) {
chomp;
@row_elements = split /\t/, $_;
# take the first field and make it the key
$key = pop (@row_elements);
# take the rest of the fields and join them
# into a single string delimited by :
$value = join (":", @row_elements);
# add key/value pair to the hash
$hash{$key} = $value;
}
untie %hash;
When I want to retrieve the data, I'll need to split the value on : to get at the individual fields.
A slightly more complicated, but more compact and efficient, way is to use the MLDBM Perl module (available from CPAN). MLDBM allows us to store arrays of data (or hashes, or arrays of hashes) as values in our key/value pairs. The trick is that the array (or whatever) must be stored as a reference when the file is constructed, and then dereferenced in order to access it.
use MLDBM('DB_File');
# tie with MLDBM, or throw an error if something goes wrong
tie %hash, "MLDBM", "myDB"
or die "cannot create database file: $!\n";
# assign values to @array
@array = ("value1", "value2", "value3");
# store the array as a reference, with "key1" as the key
$hash{key1} = \@array;
# dereference the array and print out the third element
print "${$hash{key1}}[2]\n\n";
untie %hash;
The above code will print out value3.
Berkeley DB isn't for everyone, but it can go a long way toward bridging the gap between developer and database administrator. Once you start controlling your data from within your applications, you may never go back.
Steve Renaker is a San Francisco-based programmer, free-lance writer, and frequent contributor to DevX.com. He can be reached at steve@renaker.com.