Какая алгоритмическая сложность операций в B-дереве?

«Какая алгоритмическая сложность операций в B-дереве?» — вопрос из категории SQL и базы данных, который задают на 33% собеседований Data Инженер. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

Основные операции в B-дереве (поиск, вставка, удаление) имеют логарифмическую сложность O(log n), где n — общее количество ключей в дереве. Это гарантируется за счет того, что B-дерево всегда остается сбалансированным.

Детализация по операциям:

  • Поиск (Read): O(logt n), где t — минимальная степень дерева (минимальное количество детей у узла, кроме корня). На практике t велико (сотни), поэтому высота дерева мала даже для миллиардов записей.
  • Вставка (Insert): O(logt n) для поиска позиции + O(t) для возможного разделения узла. Поскольку t — константа, общая сложность остается O(log n).
  • Удаление (Delete): Аналогично O(logt n) для поиска + O(t) для возможного слияния узлов.

Почему это важно для баз данных? Индексы в реляционных СУБД (например, B+деревья в PostgreSQL, MySQL InnoDB) построены на этой концепции. Это позволяет быстро находить данные по ключу. Например, поиск одной записи в таблице с миллиардом строк требует всего ~3-4 чтений с диска (так как высота дерева обычно 3-4).

Пример поиска в псевдокоде:

def b_tree_search(node, key):
    while node is not None:
        # Линейный или бинарный поиск ключа в текущем узле
        i = find_key_index(node.keys, key)
        if i < len(node.keys) and node.keys[i] == key:
            return node, i  # Ключ найден
        if node.is_leaf:
            return None     # Ключ отсутствует
        # Переход к соответствующему дочернему узлу
        node = node.children[i]
    return None

Сложность O(log n) делает B-деревья идеальными для структур, хранящихся на диске, где количество операций ввода-вывода критически важно.