MongoDB is categorized as a schema-less, schema-free or a document orientated data store. Another category of NoSQL product is the key/value store. It had not dawned on me until a discussion with some of the 10gen employees that MongoDB is also a key/value store, this is just a subset of features.
How would you consider the design of a key/value store? Using the memached model, there are 4 primary attributes to consider:
- The Key to store/retrieve
- The Value for the given key
- An auto expiry of the cached data
- A key scope enabling multiple namespaces
There are three primary functions:
- Put a given Key/Value pair
- Get a given Key
- Delete a given Key
Let’s explore the options. The first is to create a new collection for each key. That way there is only one row per key,
> use keystore
> var d = new Date();
> var id = "key1";
> var kv = { key: id,val: "Hello World",expires: d}
> db.key1.save(kv);
> db.key1.find();
{ "_id" : ObjectId("4c126095c68fcaf3b0e07a2b"), "key" : "key1", "val" : "Hello World", "expires" : "Fri Jun 11 2010 12:09:51 GMT-0400 (EDT)" }
However when we start loading we run into a problem.
> db.key99999.save({key: "key99999", val: "Hello World", expires: new Date()})
too many namespaces/collections
> show collections;
Fri Jun 11 12:49:02 JS Error: uncaught exception: error: {
"$err" : "too much key data for sort() with no index. add an index or specify a smaller limit"
}
> db.stats()
{
"collections" : 13661,
"objects" : 26118,
"dataSize" : 2479352,
"storageSize" : 93138688,
"numExtents" : 13665,
"indexes" : 13053,
"indexSize" : 106930176,
"ok" : 1
}
I did read there was a limit on the number of collections at Using a Large Number of Collections
.
Also for reference, I look at the underlying data files shows the ^2 increment of data files.
$ ls -lh data/current total 2.2G -rw------- 1 rbradfor rbradfor 64M 2010-06-11 12:45 keystore.0 -rw------- 1 rbradfor rbradfor 128M 2010-06-11 12:45 keystore.1 -rw------- 1 rbradfor rbradfor 256M 2010-06-11 12:46 keystore.2 -rw------- 1 rbradfor rbradfor 512M 2010-06-11 12:48 keystore.3 -rw------- 1 rbradfor rbradfor 1.0G 2010-06-11 12:48 keystore.4 -rw------- 1 rbradfor rbradfor 16M 2010-06-11 12:48 keystore.ns
> db.dropDatabase();
{ "dropped" : "keystore.$cmd", "ok" : 1 }
In my next test I’ll repeat by adding the key as a row or document for just one collection.