Thanks for all of the thoughts in this thread so far, they have been very helpful.
As I’ve been reasoning through this more based on all of the discussion here, I’m starting to come to the conclusion that an efficient and scalable data structure, which allows relational modeling, will be possible by composing together multiple basic data structures customized somewhat for the IC (the customization mostly dealing with scaling across canisters).
It really seems that with a combination of tree/map structures, like b-trees and b±trees, we can get the basic functionality that we want. For example, these two data structures are what SQLite is built out of, under the hood (if my sources aren’t wrong). SQLite uses b±trees to store the tables, and b-trees for indexes.
Given the orthogonal persistence of the IC, a lot of the underlying complexity of getting a database to function properly in a web/network app context will just melt away. That is exciting.
I’m thinking of starting using simple Rust data structures that already exist, such as a BTreeMap. With some binary search functionality, either built-in or custom-made, I think I can get a good prototype to work well within one canister. If that can work, I think we’ll be well on our way to a scalable solution.
As long as the data structures are built to compose together well, I’m thinking we should be able to create Big versions of these data structures, and they should work remarkably similar to the non-Big versions that only work within a single canister.
So if we can get a BTreeMap and a B+TreeMap and a binary search to work well within one canister, then if we build a BigBTreeMap and a BigB+TreeMap, with a BigBinarySearch, then we might be able to simply swap out the data structures in the single canister version and viola get a multi-canister version.
Thoughts?