For sorting or adjacency queries, you want a btree index. A hash index can give you O(1) lookup with the drawback that you lose ordering completely (whereas getting a sorted selection of records with a tree is a O(1) operation). The trick here is having a hashing function which is both fast and avoids collisions (the worst case scenario is hash(x)=1 where everything hashes to the same value and you end up again with O(n) lookups).
By definition a binary tree means there are two children per node.
Binary is the one thing a b-tree is not.
This difference occurs because a B-tree can have interior nodes that aren't completely full, whereas a binary tree's interior nodes have exactly 2 children.
Seems like it would be extremely odd to have a 2-2 btree, you’d just get a significantly more complicated BST no?
I’d figure you’d want to fill a cacheline with something typical-ish, so probably at least 4 (this way if you have 4 children and 3 keys, the keys are 8 bytes and the child links are straight pointers your node is 56 bytes and you can add some metadata e.g. a bitmap).
Apparently Rust’s BTreeMap is a 6-11 btree but I don’t know how they picked the branching factor.
And..even if you did, you could re-index it.
As of 14.1, they still don't support unique constraints:
select amname, pg_indexam_has_property(oid, 'can_unique') from pg_am
amname | pg_indexam_has_property
--------+-------------------------
heap | ¤
btree | t
hash | f
gist | f
gin | f
spgist | f
brin | fEDIT: This is no longer true. Thanks latch!
Binary trees are the ideal in a world of a pure von Neumann model. In practice data structures perform better when data is grouped together and this is what the b-tree gets you. It's both more disk and cache efficient in real world workflows