Using dbmopen – disk-resident hashes in perl

Perl supports access to simple key->value databases through the "dbmopen" and "dbmclose" commands. These provide very simple access to disk-resident persistent hashes. This style of database does not support the notion of multiple columns or keys but does provide great support for the simplest of all possible database use cases: one key mapped to a single value - exactly like a perl hash.

To open one of these and associate it with a perl hash, you use the "dbmopen" command, for example...

dbmopen %db, "file.db", 0666;

The hash named in the first parameter (%db in this case) is the perl variable you will use to access the database. The string in the second is the name of the disk file (which will be created if it doesn't exist). The third parameter is the unix-style file mode to be used when creating the file (0666 is the usual value to use).

Now you add or update records simply by accessing the hash. Like this..

$db{name} = "Tom Thumb";

And you can read records in the normal perl manner..

print $db{name};

If you want to disassociate the hash from the database, you call:

dbmclose %db;

So, to all intents and purposes you treat it exactly has you do a normal perl hash. Except that..

  • You use dbmopen and dbmclose to maintain the association between the hash and the file.
  • Large hashes don't consume large amounts of memory: they are on the disk instead.
  • The content of the hash is remembered from one invocation of the program to another.
  • The values stored in the db hash can only be strings or numbers - it is not possible to store..
    • Undefined values - these are mapped to empty strings.
    • Array or hash references - these are mapped to the string representation of the reference.

To illustrate the last two points .. consider the following script

use Data::Dumper;
dbmopen %x, "myfile.db", 0666;
$x{xx} = [1,2,3,4];
$x{yy} = undef;
print Dumper( \%x );
dbmclose %x;

It generates the following output (assuming myfile.db is empty)

$VAR1 = {
        'xx' => 'ARRAY(0x8c6ec28)',
        'yy' => '',
};

Whereas, with the "dbmopen" and "dmbclose" lines removed, it outputs..

$VAR1 = {
         'xx' => [
              1,
              2,
              3,
              4
         ],
         'yy' => undef,
};
Scroll to Top