I have a C++ key/value table that looks like this:
class kvBucket {
...
map<string, kvBucket*> buckets;
map<string, string> keyPairs;
...
}
class kvTree {
...
kvBucket base;
...
}
I’d like to convert this from an in-memory structure to one that’s implemented in a database (sqlite3). I’m not sure how to represent the schema due to buckets being nested. Here’s example data:
bucket | key | value
------ --- -----
a v 1
a/b w 2
a/b x 3
a/b/c y 4
d z 5
In the C++ structure, I have member functions that do things like retrieving a list of buckets under another bucket, or retrieving a list of key/value pairs under a bucket path, etc. I’ll need to do the same with the database. Is there an efficient way to design the schema to do this?
There’s no efficient way to represent a hierarchical relationship in a relational store. Key-value stores (you may have heard of them, they’re all the rage these days) are better at it but generally don’t provide SQL layers. Getting all the buckets under a certain path is going to require more than one query if you want to be able to move the buckets about (if you don’t want to move the buckets ever, you could use the scheme you’ve got there and do a substring search on the bucket name for things like
"a/*").That said, you can do it even without having each bucket store its own full path: you need a self-to-self many-many relationship mapping from
buckettobucket. You need two tables, one for the buckets and one just for the mapping. In the mapping table you have two columns,parent_bucketandchild_bucket. In thebuckettable you have three,bucket_id,key, andvalue.