Суррогатные ключи
Зачем нужен суррогатный ключ?
В хранилище данных (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-функции и их настройка описано здесь.