Using Berkeley DB Databases

Problem

You want a simple, fast database that doesn need a server to run.

Solution

Rubys standard dbm library lets you store a database in a set of standalone binary files. Its not a SQL database: its more like a fast disk-based hash that only stores strings.

require dbm DBM.new( andom_thoughts) do |db| db[ ape measure] = "What if there was a tape measure you could use as a yo-yo?" db[23] = "Fnord." end DBM.open( andom_thoughts) do |db| puts db[ ape measure] puts db[23] end # What if there was a tape measure you could use as a yo-yo? # Fnord. DBM.open( andom_thoughts) { |db| db[23] } # TypeError: can convert Fixnum into String Dir[ andom_thoughts.*] # => ["random_thoughts.pag", "random_thoughts.dir"]

Discussion

The venerable Berkeley DB format lets you store enormous associative datasets on disk and quickly access them by key. It dates from before programming languages had built-in hash structures, so its not as useful as it used to be. In fact, if your hash is small enough to fit in memory, its faster to simply use a Ruby hash that you serialize to disk with Marshal.

If you do need to use a DBM object, you can treat it almost exactly like a Ruby hash: it supports most of the same methods.

There are many, many implementations of the Berkeley DB, and the file formats differ widely between versions, so DBM files are not very portable. If you e creating your own databases, you should use the generic dbm library. It provides a uniform interface to all the DBM implementations, using the best library you have installed on your computer.[7]

[7] Actually, it uses the best DBM library you had installed when you installed the dbm Ruby extension.

Ruby also provides gdbm and sdbm libraries, interfaces to specific database formats, but you should only need these if you e trying to load a Berkeley DB file produced by some other program.

Theres also the SleepyCat library, a more ambitious implementation of the Berkeley DB that implements features of traditional databases like transactions and locking. Its Ruby bindings are available as a third-party download. Its still much closer to a disk-based data structure than to a relational database, and the basic interface is similar to that of dbm, though less Ruby-idiomatic:

require db db = BDB::Hash.create( andom_thoughts2.db, nil, BDB::CREATE) db[Why do we park on a driveway but] = it never rains but it pours. db.close db = BDB::Hash.open( andom_thoughts2.db, nil, ) db[Why do we park on a driveway but] # => "it never rains but it pours." db.close

The SleepyCat library provides several different hashlike data structures. If you want a hash whose keys stay sorted alphabetically, you can create a BDB::Btree instead of a BDB::Hash:

db = BDB::Btree.create(element_reviews.db, nil, BDB::CREATE) db[earth] = My personal favorite element. db[water] = An oldie but a goodie. db[air] = A good weekend element when you e bored with other elements. db[fire] = Perhaps the most overrated element. db.each { |k,v| puts k } # air # earth # fire # water db[water] # => "An oldie but a goodie." db.close

See Also

Категории