Я хотел бы получить некоторые идеи по следующей проблеме.
Система
В ориентированной на клиента системе Customer_id
представляет собой выровненный по правому краю 9-значный код с 7 ведущимипространства.Допустимая запись: '000000399
'.
Существует главная таблица CUSTOMERS
и почти 80 таблиц подробностей.Основная таблица CUSTOMERS
имеет несколько записей для каждого Customer_id
и использует столбцы Start_date
, End_date
для истории записей.Конечная дата изначально равна '9999
' и обновляется до Start_date
новой записи всякий раз, когда вставляется новая запись для существующего Customer_id
.
Ниже приведен пример.Первая запись для Customer_id '000000399
' будет выглядеть так:
+ -------------------- + --------------------- + --------------------- + |Cust_id |Start_date |Конечная дата |+ -------------------- + --------------------- + --------------------- + |'000000399' |'20100225210300000' |'9999' |+ -------------------- + --------------------- + --------------------- +
Предположим, что новая запись вставлена в 2010-03-03 12:37:33,000
Новая запись должна иметь конечную дату 9999 и конечную дату предыдущей записи.должно быть обновлено с новой Start_date.Записи этого Customer_id должны быть:
+ -------------------- + --------------------- + --------------------- + |Cust_id |Start_date |Конечная дата |+ -------------------- + --------------------- + --------------------- + |'000000399' |'20100225210300000' |'20100303123733000' ||'000000399' |'20100303123733000' |'9999' |+ -------------------- + --------------------- + --------------------- +
Этот шаблон используется в основной и подробной таблицах, в которых используются столбцы Start_date и End_date.
ПроблемаВ какой-то момент Customer_ids
начал вставляться в неправильных форматах.Вы можете найти следующие форматы для одного и того же Клиента.
' 000000399'
'000000399 '
' 000000399 '
Проблема в том, что эти Customer_ids
рассматриваются как разные Клиенты в системе, поэтому они поддерживают свои собственные цепочки Start_date
и * 1037.*.В итоге мы имеем следующие записи для клиента (отсортированные по Start_date
).
+---------+-------------+-------------------+-------------------+-------------------+
| Cust_id | New_Cust_id | Start_date | End_date | New_End_date |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20100225210300000 | 20100303123733000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20100303123733000 | 20110127001826000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20110127001826000 | 20110129001706000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20110129001706000 | 20120309001920000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120309001920000 | 20120406001926000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120406001926000 | 20120524001910000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120524001910000 | 20130129180350000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20130129180350000 | 20131212153024000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20131212153024000 | 20150424184238000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20150424184238000 | 20160222184547000 | 20151103095530339 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | 399 | 20151103095530339 | 20180714105242000 | 20160222184547000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20160222184547000 | 20180911143426000 | 20180714105242000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | 399 | 20180714105242000 | 9999 | 20180911143426000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20180911143426000 | 9999 | |
+---------+-------------+-------------------+-------------------+-------------------+
Задача
Перед нами стоит задача очистки данных, чтобы не было отклонений Customer_idsи что текущие данные сохраняют свою целостность и согласованность.В приведенном выше примере решение состоит в том, чтобы ввести записи с ошибкой Customer_ids
в правильном положении (Start_date/End_date
) и в правильном формате Customer_id
.Давайте добавим несколько новых столбцов для столбцов, которые необходимо обновить.
+---------+-------------+-------------------+-------------------+-------------------+
| Cust_id | New_Cust_id | Start_date | End_date | New_End_date |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20100225210300000 | 20100303123733000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20100303123733000 | 20110127001826000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20110127001826000 | 20110129001706000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20110129001706000 | 20120309001920000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120309001920000 | 20120406001926000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120406001926000 | 20120524001910000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20120524001910000 | 20130129180350000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20130129180350000 | 20131212153024000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20131212153024000 | 20150424184238000 | |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20150424184238000 | 20160222184547000 | 20151103095530339 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | 399 | 20151103095530339 | 20180714105242000 | 20160222184547000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20160222184547000 | 20180911143426000 | 20180714105242000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | 399 | 20180714105242000 | 9999 | 20180911143426000 |
+---------+-------------+-------------------+-------------------+-------------------+
| 399 | | 20180911143426000 | 9999 | |
+---------+-------------+-------------------+-------------------+-------------------+
Изображение имеет значение для тысячи слов, так оно и должно выглядеть: записей, вставленных между
Проще говоря, когда следующая запись имеет другой формат Customer_id, дата окончания предыдущей записи должна быть обновлена до значения вставленной даты начала.Конечно, ошибочный Customer_id также должен быть обновлен до правильного формата (выровнен по правому краю).
Таким образом, конечное состояние предыдущих данных должно выглядеть следующим образом: записи обновляются по мере необходимости Обновленные данные показываютв зеленом цвете.
Решение
Я ищу способ очистки данных.У меня есть некоторые начальные мысли, но я хотел бы услышать некоторые предложения.База данных минимально проиндексирована, большинство таблиц являются кучами, ссылочных ключей нет.Некоторые числа: - 32M записей клиентов - 4M уникальных Customer_ids
- 150K ошибочных записей (неправильный формат Customer_id) - 80 таблиц с ошибочными записями - 132M записей - самая большая таблица
Ограничения - Минимальное время простоя - Новые записипоступление в базу данных (надеюсь, в правильном формате)
В настоящее время я работаю над написанием процедуры, которая будет выполнять следующее:
- Выберите каждый отдельный
Customer_id
из CUSTOMERS
таблица с ошибочными записями. начать новую транзакцию
а.Создайте временную таблицу со всеми соответствующими записями из таблицы CUSTOMERS
для этого Customer_id
(во всех форматах)
- i.Сортируйте эти записи во временной таблице согласно Start_date
- ii.Обновляйте конечную дату, когда это необходимо
- iii.Обновите ошибочный Customer_id
- iv.Обновите измененные записи в таблице
CUSTOMERS
- удалив все связанные записи и вставив обновленные записи из временной таблицы, или обновив существующие связанные записи
b.Перейдите к следующей (подробной) таблице и создайте новую временную таблицу i.Повторите шаги i-iv
- Подтвердите транзакцию, когда записи для текущего
Customer_id
обновлены во всех 80 таблицах подробностей. - Переходите к следующему
Customer_id
и повторите шаги1-3 - Молитесь, чтобы все работало по плану…
Пожалуйста, поделитесь своими мыслями.
PS.Извините за длинный пост:)