Обновлять данные из одной таблицы в другую (в базе данных)

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, но я не уверен, удаления слишком или нет, хотя вставка и обновление устраняются. Более того, этот оператор сам по себе берет на себя транзакцию