Pair Networks


MTDB - Multidimensional Transparent hash DataBase

also kwon as:

MTDB - Mark Thomson's DataBase


 # Load the package
 use MTDB qw($serializer);

 # Bind the hash to the class
 $db = tie %hash, 'MTDB',
         FILE => $file,
         SAFER => 1;

 # Save to disk all changed records

 # Get all record keys
 @array = keys %hash; 

 # Check if a record exists
 exists $hash{$foo};
 $bar = $hash{$foo};
 exists $bar->{$foobar};

 # Get a field
 $bla = $hash{$key};
 $scalar = $bla->{$key2}->[0];
 $scalar = $bla->{$key2}->{$key3};

 # Assign to a field
 $bla->{$key2}->{$key3} = $value;
 #store in mainhash
 $hash{$key} = $bla;
 # save to disc


The MTDB provides a hash-table-like interface to a ASCII database.

The ASCII database stores the records into one file:

After you've tied the hash you can access this database like the MLDBM

To bind the %hash to the class MTDB you have to use the tie function:

	tie %hash, 'MTDB', param1 => $param1, ...;

The parameters are:

The File where the hash(-records) will be stored and readed from. The default value is data.db

Filemode assigned to saved files.

If this parameter is not supplied the db-files will have the default permissions.


If you set this parameter to 1 MTDB will perform basic locking. The Databasefile will be exclusive locked when syncing (writing) them.

The default value is 0, i.e. the database won't be locked.

If the DB-File not exists and this parameter is supplied, the file will be created, otherwise tie fails. If this parameter is supplied and the file exists already, nothing happens.
If you want a more safe database, turn this parameter on. The Database will only sync then you request $obj->sync(), otherthise on program-end sync() will be executed automatically.
If you specified a (at least) 8 bit key, the complete database will be stored encrypted.

The data will be saved to disk when the hash is destroyed (and garbage collected by perl), so if you need for safety to write the updated data you can call the sync method to do it.

You can also specifie an antoencryption for a specified hash-key.


 $db = tie %h, 'MTDB',
	FILE => 'data.db',
        MODE => 0644,
        CREATE => 1;

 $name = $h{'za'};
 $name2 = $h{'tt'};
 $name->{'name'}[0] = 'William T. Riker';
 $name2->{'name'}[0] = 'Thomas Riker';
 $name->{'friend'}[1] = 'Jean-Luc Picard';
 $h{'za'} = $name;
 $h{'tt'} = $name2;

 # Fetch all keys in database
 while (($key, $value) = each %$h) 
	print "$key and $value->{'name'}[0]\n";

 my $root = $h{'za'}; 
 for my $k (keys %$root) 
            print $k->[0];		# William T. Riker

 # Encryption for a spezified key in *all* hashs 
$db->setkey('personal');	 # means the first subkey
$troi = $h{'troi'};
$riker = $h{'riker'};
$troi->{'personal'}->{'foo'}='secret';	# will be stored encrypted
$troi->{'personal'}->{'bar'}->{'friend'} = 'Barcley';	# will be also stored encrypted
$troi->{'foo'}->{'personal'}->{'friend'} = 'Barcley';	# will not be stored encrypted
$riker->{'personal'}->{'foo'} = 'worf';	# will be stored encrypted 









Adding or altering substructures to a hash value is not entirely transparent in current perl. If you want to store a reference or modify an existing reference value in the MTDB, it must first be retrieved and stored in a temporary variable for further modifications. In particular, something like this will NOT work properly:

	$hash{key}{subkey}[3] = 'stuff';	# won't work

Instead, that must be written as:

	$tmp = $hash{key};			# retrieve value
	$tmp->{subkey}[3] = 'stuff';
	$hash{key} = $tmp;			# store value

This limitation exists because the perl TIEHASH interface currently has no support for multidimensional ties.

The Data::Dumper serializer uses eval(). A lot. Try the Storable serializer, which is generally the most efficient.



MTDB does well with data structures that are not too deep and not too wide. You also need to be careful about how many FETCHes your code actually ends up doing. Meaning, you should get the most mileage out of a FETCH by holding on to the highest level value for as long as you need it. Remember that every toplevel access of the tied hash, for example $hash{foo}, translates to a MTDB FETCH() call.

Too often, people end up writing something like this:

        tie %h, 'MTDB', ...;
        for my $k (keys %{$h{something}}) {
            print $h{something}{$k}[0]{foo}{bar};  # FETCH _every_ time!

when it should be written this for efficiency:

        tie %h, 'MTDB', ...;
        my $root = $h{something};                  # FETCH _once_
        for my $k (keys %$root) {
            print $k->[0]{foo}{bar};


Mark Ralf Thomson

mark-thomson at gmx dot net


You can send bug reports and suggestions for improvements on this module to me. However, I can't promise to offer any other support for this script.


MTDB was developed by Mark Ralf Thomson Copyright 2002 by Mark Ralf Thomson. All Rights reserved.

Based up on MLDBM written by Gurusamy Sarathy and Raphael Manfredi

This program is free software; you can redistribute it and/or modify it under the same terms as Perl itself.


Version 0.1 August 2002


perl(1), perltie(1), perlfunc(1), Data::Dumper(3), FreezeThaw(3), Storable(3).