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.