Skip to content

Суррогатные ключи

Зачем нужен суррогатный ключ?

В хранилище данных (DWH) натуральные ключи (например, номер заказа или код товара) помогают связать данные с исходными системами, но их редко используют как основные ключи, потому что они могут меняться или повторяться. Вместо них применяют искусственные ключи (числа или хеши), которые всегда уникальны и неизменны. Натуральные ключи оставляют как дополнение для удобства аналитики.

Автоинкремент

Стандартный практика - генерировать автоинкрементные целочисленные ключи (SERIAL в PostgreSQL или AUTOINCREMENT в MSSQL). То есть, для каждого значения натурального ключа генерировать целочисленное значение (суррогатный ключ) путем добавления единицы (+ 1) к максимальному значению ранее сгенерированных суррогатов.

Но такой подход имеет ряд ограничений, главные из которых:

  • при обновлении таблиц требуется производить join к таблице, в которой хранится маппинг натуральных ключей и их суррогатов (idmap);
  • дополнительный шаг (генерация суррогатов) перед обновлением хабов, сателлитов и линков*

* Если генерировать суррогатные ключи непосредственно в хабе, то придется сначала обновлять все хабы, затем только все линки, а после сателлиты.

HASH

В DataVault 2.0 на замену автоинкрементным суррогатным ключам пришел hash. Он позволяет в моменте (при обновлении хабов, сателлитов или линков) определять значения суррогатного ключа путем взятия hash-значения от натурального ключа.

У такого подхода есть заметные преимущества:

  • не потребуется делать дополнительный join
  • не потребуется дополнительного шага по генерации суррогата
  • можно обновлять все хабы, сателлиты и линки в параллель
  • значения суррогатного ключа легко мигрировать с dev на prod среду

Но есть и недостатки:

  • hash значение занимает больше памяти на диске (32 или 64 байт заместо 4 или 8 байт и целых чисел)
  • из-за большего объема join-операции могут быть дольше
  • могут быть коллизии (когда у разных натуральных ключей один hash)

Расчет hash

Суррогатный hash-ключ - это hash от значения натурального ключа. Если натуральных ключей у сущности несколько, то hash от конкатенации значений натуральных ключей.

Пример расчета в PostgreSQL

SHA256(CAST(NULLIF(CONCAT(
        COALESCE(NULLIF(UPPER(TRIM(CAST(id AS VARCHAR))), ''), '^^')
    ), '^^') AS BYTEA))

HASH-функции

Используемые в Datapulse HASH-функции и их настройка описано здесь.