Sometimes databases use hash tables for indexing. This is a natural match for a key-value store. In particular, the following KV stores offer hash table-based indexing: -Berkeley DB [1] -Tokyo Cabinet (and its successor, Kyoto Cabinet) [2] -Bitcask (used in Riak) [3] In many benchmarks, the hash-based systems perform better than tree-based ones. The real advantage of trees, as Berkeley DB manual says: > Btrees are be…
Why databases use ordered indexes but programming uses hash tables
91–100 of 205 posts
Re: Why databases use ordered indexes but programming uses hash tables
#92One major issue with disk based hash tables is rehashing. Actually, in-memory hash tables have the same problem, but most people don't notice it. Imagine your database suddenly duplicating itself because you inserted one row and suddenly overloaded a bucket. Some hash tables that are designed to minimize the potential for DDOS attacks and improve the amortization of work use gradual rehashing (Go's hash table does th…
Re: Why databases use ordered indexes but programming uses hash tables
#93Earlier quoted context omitted.
std::unordered_map was only added in C++11, which explains why it's not used in legacy code. Habit, inertia and a desire to keep codebases internally consistent explains why it's less common now.
Also std::unordered_map suffers from a design flaw that forces a poor implementation.
Re: Why databases use ordered indexes but programming uses hash tables
#94Earlier quoted context omitted.
Didn't the article address 1) with this?: > Another difference is that hash tables only provide average constant time accesses. Bad behaviour can be caused by hash collisions, either unintentional or malicious, but a bigger issue is rehashing. Occasionally, when the table is growing, your normally fast O(1) insert involves a slow O(n) scan to move to a bigger table. The impact of this can be reduced by using multi-le…
"Occasionally, when the table is growing, your normally fast O(1) insert involves a slow O(n) scan to move to a bigger table." This my impression and it seems like it implies that the "hash table has O(1) access" is bullshit taken as a general formulation. The situation is essentially, hash tables can have "O(1) access" time at a certain size and if tuned for that size. BUT that seems an abuse of big-O notation, whic…
At the level of abstraction that comexity analysis is usually done, you can. For example, a lookup in an array (a[X]) has O(1) worse-case complexity no matter how large the array is.
Of course, this relies on a few abstractions - that random memory access has uniform cost; and that basic numeric operations have uniform cost regardless of the size of the operands. Of course, in real computers, both of these assumptions are wrong (adding terabyte-size numbers is not as fast as adding byte-sized numbers, large amounts of memory can't usually be stored on random-access hardware etc.), but that does not necessarily impact the usefulness of complexity analysis.
For hash-tables in particular, the worse-case complexity for key lookup depends on some guarantees from the hash algorithm. If you had a magical hash that is unique for any key in your domain, than lookup would be O(1) for a hash table of n elements, as n approaches infinity. Since that is not a good abstraction, we need to model the table using hash functions that can create collisions, and the worse case becomes that O(n) elements collide and get put into the same bucket, giving worse-case complexity of O(n). Adding elements to the hash table is a different operation, same as for the array.
Re: Why databases use ordered indexes but programming uses hash tables
#95Earlier quoted context omitted.
Another question: doesn't the O(1) property of hashtables require that there's no collisions? Because of the birthday paradox, you'll need an insanely large hashtable to avoid collisions, and if you don't (or get unlucky), the performance approaches O(n) as the hashtable gets fuller. If you think about it, a hashtable isn't really that different from a b-tree with a very large value for "b".
Collisions are expected (fill factors are typically typically 2/3 to 3/4). You make every bucket in the table a linked list. And check each value in the list against that for which you are searching.
Re: Why databases use ordered indexes but programming uses hash tables
#96Earlier quoted context omitted.
You should reach for the best tool for the job instead of giving job-specific reasons for your general choice. Without going into detail explaining how your bullets either don't apply to most uses, prematurely code for a future case that may not exist, dismiss performance, reference other languages as if language implementation is not a factor in the choice, etc... suffice to say they both have their place and in gen…
An ordered map is much better as a default simply because it can do everything that an unordered map can. Choosing to use an unordered map instead is a premature optimization that is nearly always unnecessary.
Re: Why databases use ordered indexes but programming uses hash tables
#97Earlier quoted context omitted.
Your both points (very valid) could perhaps be wrapped up as: Indexes have lower computational complexity for certain tasks (in particular range queries & sort), but higher constants than typical hashing. Thus indexes make more sense with two-tiered memory; to cache in RAM metadata about data kept in block storage. How that could be put to good use with the L1 cache being much faster than RAM is anyone's guess[1]. --…
Rust's default (edit: ordered) map structure is a memory Btree, fwiw.
Re: Why databases use ordered indexes but programming uses hash tables
#98Earlier quoted context omitted.
Also std::unordered_map suffers from a design flaw that forces a poor implementation.
Would you be willing to expand on that? I couldn't find any obvious well-known issues with a quick search.
[0] : https://www.reddit.com/r/programming/comments/5pwgtn/hash_ma...
[1] : https://stackoverflow.com/questions/42588264/why-is-stdunord...
Re: Why databases use ordered indexes but programming uses hash tables
#99Earlier quoted context omitted.
Also std::unordered_map suffers from a design flaw that forces a poor implementation.
Would you be willing to expand on that? I couldn't find any obvious well-known issues with a quick search.
Re: Why databases use ordered indexes but programming uses hash tables
#100Earlier quoted context omitted.
Didn't the article address 1) with this?: > Another difference is that hash tables only provide average constant time accesses. Bad behaviour can be caused by hash collisions, either unintentional or malicious, but a bigger issue is rehashing. Occasionally, when the table is growing, your normally fast O(1) insert involves a slow O(n) scan to move to a bigger table. The impact of this can be reduced by using multi-le…
Growing hash tables only takes amortized O(1); you just do two operations per logical operation, which is still O(1). One search term is "incremental resizing." https://en.wikipedia.org/wiki/Hash_table#Dynamic_resizing
But I'm not sure incremental resizing can get to actual O(1). Is the malloc() call for the new memory O(1)? And then after malloc() wouldn't the memory have to be initialized somehow (maybe just 0-initialized)?