B + trees order several elements with a key. In this case, the key is the counter, and the element is the name of the person. The entire B + tree does not need to be inserted into memory - only search for the current node. You can set the maximum size of the nodes (and indirectly the depth of the tree) so that the node fits in memory. (In practice, nodes are usually much smaller than memory.)
Data elements are stored in tree leaves in so-called blocks. You can either save inline elements in the index, or save pointers to external storage. If the data is of regular size, this can provide an efficient search from files. In the example question, data elements can be single names, but it would be more efficient to store name blocks, all names in a block that has the same counter. Names inside each block can also be sorted. (Names in the blocks themselves can be organized as a B-tree.)
If the number of names becomes so large that the blocks of the B + tree become excessively large, the key can be made into a compound key, for example. (count, first letter). When searching in the tree, you only need to compare the counter to find all the names with this counter. When inserting or searching for a specific name with a given count, the full key can be compared to enable filtering by the name prefix.
Alternatively, instead of a compound key, data elements can point to offsets / blocks in an external file that contains name blocks that will contain a minimal B + tree.
If btree blocks are connected to each other, range requests can be effectively implemented by looking for the beginning of the range and then following block pointers to the next block until the end of the range is reached. This will allow you to effectively implement "find all names with a score from 10 to 20".
As other answers noted, RDBMS is a pre-packaged way of storing lists that don't fit into memory, but I hope this gives an idea of the structures used to solve the problem.
source share