ReplacingMergeTree
Движок отличается от MergeTree тем, что удаляет дубликаты с одинаковым значением ключа сортировки (ORDER BY
секция таблицы, а не PRIMARY KEY
).
Дедупликация данных происходит только во время слияния. Слияние происходит в фоновом режиме в неизвестное время, поэтому вы не можете запланировать его. Некоторые данные могут оставаться необработанными. Хотя вы можете выполнить несогласованное слияние, используя запрос OPTIMIZE
, не рассчитывайте на его использование, так как запрос OPTIMIZE
будет читать и записывать большое количество данных.
Таким образом, ReplacingMergeTree
подходит для удаления дублирующихся данных в фоновом режиме, чтобы сэкономить место, но не гарантирует отсутствие дубликатов.
Подробное руководство по ReplacingMergeTree, включая лучшие практики и способы оптимизации производительности, доступно здесь.
Создание таблицы
Для описания параметров запроса см. описание оператора.
Уникальность строк определяется секцией ORDER BY
таблицы, а не PRIMARY KEY
.
Параметры ReplacingMergeTree
ver
ver
— колонка с номером версии. Тип UInt*
, Date
, DateTime
или DateTime64
. Опциональный параметр.
При слиянии ReplacingMergeTree
оставляет только одну из всех строк с одинаковым ключом сортировки:
- Последнюю в выборке, если
ver
не установлен. Выборка представляет собой набор строк в наборе частей, участвующих в слиянии. Самая недавно созданная часть (последняя вставка) будет последней в выборке. Таким образом, после дедупликации последняя строка из самой последней вставки останется для каждого уникального ключа сортировки. - С максимальной версией, если указан
ver
. Еслиver
одинаков для нескольких строк, то для них будет применено правило "еслиver
не указано", т.е. останется последняя вставленная строка.
Пример:
is_deleted
is_deleted
— имя колонки, используемой во время слияния для определения, представляет ли данные в этой строке состояние или должно быть удалено; 1
- "удаленная" строка, 0
- "строка состояния".
Тип данных колонки — UInt8
.
is_deleted
можно включить только при использовании ver
.
Не имеет значения, какая операция выполняется с данными, версия должна увеличиваться. Если две вставленные строки имеют одинаковый номер версии, сохраняется последняя вставленная строка.
По умолчанию ClickHouse сохранит последнюю строку для ключа, даже если эта строка является строкой удаления. Это сделано для того, чтобы любые будущие строки с более низкими версиями могли быть безопасно вставлены, и строка удаления все еще применялась.
Чтобы навсегда удалить такие строки удаления, включите настройку таблицы allow_experimental_replacing_merge_with_cleanup
и либо:
-
Установите настройки таблицы
enable_replacing_merge_with_cleanup_for_min_age_to_force_merge
,min_age_to_force_merge_on_partition_only
иmin_age_to_force_merge_seconds
. Если все части в партиции старшеmin_age_to_force_merge_seconds
, ClickHouse объединит их в одну часть и удалит любые строки удаления. -
Вручную выполните
OPTIMIZE TABLE table [PARTITION partition | PARTITION ID 'partition_id'] FINAL CLEANUP
.
Пример:
Клаузулы запроса
При создании таблицы ReplacingMergeTree
требуются те же клаузулы, что и при создании таблицы MergeTree
.
Устаревший метод создания таблицы
Не используйте этот метод в новых проектах и, если возможно, переключитесь на описанный выше метод для старых проектов.
Все параметры, кроме ver
, имеют то же значение, что и в MergeTree
.
ver
- колонка с версией. Опциональный параметр. Для описания смотрите выше.
Дедупликация во время запроса и FINAL
Во время слияния ReplacingMergeTree идентифицирует дублирующиеся строки, используя значения колонок ORDER BY
(используемые для создания таблицы) как уникальный идентификатор, и сохраняет только наивысшую версию. Однако это дает только будущую корректность - не гарантирует, что строки будут дедуплицированы, и вы не должны на это полагаться. Запросы, следовательно, могут давать некорректные ответы из-за того, что строки обновления и удаления учитываются в запросах.
Чтобы получить правильные ответы, пользователям потребуется дополнить фоновое слияние дедупликацией и удалением строк во время запроса. Это можно сделать, используя оператор FINAL
. Например, рассмотрим следующий пример:
Запрос без FINAL
дает некорректное количество (точный результат будет варьироваться в зависимости от слияний):
Добавление final дает правильный результат:
Для получения дополнительной информации о FINAL
, включая способы оптимизации производительности FINAL
, мы рекомендуем прочитать наше подробное руководство по ReplacingMergeTree.