Обновлять данные из одной таблицы в другую (в базе данных)
DB гуру,
Я надеюсь, кто-то сможет установить меня в правильном направлении.
У меня две таблицы. Таблица A и таблица B. Когда система появляется, все записи из таблицы A массируются и копируются в таблицу B (согласно схеме таблицы B). Таблица A может содержать десятки тысяч строк.
Пока система работает, таблица B синхронизируется с таблицей A через уведомления об изменении БД.
Если система перезагружена или моя служба перезагружена, я хочу повторно инициализировать таблицу B. Однако я хочу сделать это с наименьшими возможными обновлениями БД. В частности, я хочу:
- добавить любые строки, которые находятся в таблице A, но не в таблице B, и
- удалите любые строки, которые не указаны в таблице A, но находятся в таблице B
- любые строки, которые являются общими для таблицы A и таблицы B, должны быть оставлены нетронутыми
Теперь я не "парень DB", поэтому мне интересно, что это обычный способ сделать это.
Ответы
Ответ 1
Используйте exists
для минимизации обработки.
Что-то в этих строках изменилось, так что соединения правильные (также убедитесь, что я не делал что-то глупое и получаю TableA
и TableB
назад от вашего описания):
insert into TableB
select
*
from
TableA a
where
not exists (select 1 from TableB b where b.ID = a.ID)
delete from
TableB b
where
not exists (select 1 from TableA a where a.ID = b.ID)
Ответ 2
Функции Informix Enterprise Replication будут делать все это для вас. ER работает, отправляя логические журналы с одного сервера на другой и перемещая их вперед по вторичному.
Вы можете настроить его как мелкозернистый, как вам нужно (т.е. всего несколько таблиц).
Вы используете термин "уведомления об изменении БД" - вы уже используете ER или это какое-то триггерное соглашение?
Если по какой-то причине ER не может работать для вашей конфигурации, я бы предложил переписать модель уведомлений для асинхронного поведения, то есть:
- записывать уведомления в таблицу на сервере "A" , которая содержит временную метку или серийное поле
- создать таблицу на сервере "B" , которая хранит временную метку/серийное значение последней обработанной записи.
- запустите процесс демона на сервере "B" , который:
- сравнивает метки времени/серий A и B.
- выбирает записи "A" между метками "A" и "B"
- обрабатывает эти записи в 'B'
- обновить временную метку "B" /серийный номер
- спящий режим для соответствующего периода времени и цикла
Итак, сервер "B" отвечает за то, чтобы его копия синхронизировалась с "A" . "A" не является неудобным, поскольку "B" недоступен.
Ответ 3
Простым способом было бы использовать историческую таблицу, в которую вы поместили бы изменения из A, которые произошли со времени последнего обновления, и используйте эту таблицу для синхронизации таблицы B вместо прямой копии с A на B. После синхронизации, вы удаляете всю историческую таблицу и начинаете заново.
Я не понимаю, как можно обновлять таблицу A, а не B, если ваша служба или компьютер не запущены. Они найдены на двух разных базах данных или сервере?
Ответ 4
Объедините данные из обеих таблиц в соответствии со столбцами comon, и это даст вам строки, которые имеют совпадение в обеих таблицах, то есть данные в и B. Затем используйте эти значения (позвоните по этому набору M) с заданными операциями, т.е. установите минус операции, чтобы получить различия.
первое требование: минус M
второе требование: B минус A
третье требование: M
У вас есть идея?
Ответ 5
Я парень Sql Server, но с Sql Server 2008 для такого рода операций доступен вызов функции MERGE
.
Используя оператор MERGE, мы можем выполнять операции вставки, обновления и удаления в одном выражении.
Итак, я googled и обнаружил, что Informix also supports the same
MERGE, но я не уверен, удаления слишком или нет, хотя вставка и обновление устраняются. Более того, этот оператор сам по себе берет на себя транзакцию