It's a shame that FoundationDB went closed source when it did, since that was the key period (imo) for database exploration - the early 2010s. If it would've been more popularized then I imagine most people would be using it now.<p>The nice thing about FDB is that after 3 plus nodes, you can simply add nodes using your cloud provider of choice and it scales pretty nicely while still giving your high availability and fault tolerance.<p>It's pretty funny to me though to see this - I've been spending a few days building a simple database on top of FDB that supports indexes, secondary indexes and schema migrations backed by json-schema (very, very similar to this, totally independently!)<p>To get into a little bit, it's not super difficult if you use FDB. FDB is a very bare key value store. It's incredibly low level. You don't even get a notion of collections. You have to implement everything yourself. what it does give you, however, is a giant hash map that will guarantee that items are in sorted order.<p>so to build what I was describing it's easy:<p>a collection can be a tuple to map:<p><pre><code> (your-app, your-collection, _id, your-model-id-number) => json
</code></pre>
e.g.<p><pre><code> (hn-app, users, _id, 1) => { _id: 1, username: endisneigh }
(hn-app, users, _id, 2) => { _id: 1, username: reader }
</code></pre>
an index can be something like:<p><pre><code> (your-app, your-collection, your-field-to-index, index-value, _id, your-model-id-number) => json
</code></pre>
e.g.<p><pre><code> (hn-app, users, username, endisneigh _id, 1) => { _id: 1, username: endisneigh }
(hn-app, users, username, reader, _id, 1) => { _id: 1, username: reader}
</code></pre>
Because FDB gives you transactions, you maintain the index by populating the keys according to the pattern above on your create* and update* operations.<p>To do something like a schema migration, FDB gives you a get_range operation that you can use to find all keys that have a prefix. So what you'd do is store a value indicating that you're doing a migration into the database, iterate through the keys in a batch (so it's all a single transaction), update the value in the db saying what the last key you've migrated is, and continue until you've done all of the keys.<p>A lot of stuff is pretty trivial once you assume the underlying semantics are solved. I've seen some interesting projects involving things like using FDB as a virtual file system for SQLite, but the problem with that is FDBs primitives are actually flexible, and so there are optimizations you can make if you built it using those primitives from the beginning, as opposed to using FDB as simple a key value store without taking advantage of the transactions.<p>-------<p>On another note, one idea I've had (feel free to steal) is to reimplement IndexedDB using FoundationDB. IndexedDB is also a key value store which supports transactions, like FDB. Obviously IDB is not networked.<p>The idea is that if you can semantically map IDB with FDB, then you could use FDB as a store for IDB (scoped to the user, of course). And then any app that uses IDB for its storage (like an offline app) could use FDB as the backing without having to use a different set of data structures to actually represent the storage.