Я думаю, что вы путаете с понятием дельты.
Либо вы получаете полную загрузку (весь набор данных), либо только изменения («дельта»).
Если вы имеете дело с полной загрузкой, вы можете сделать усечение + вставка. Таким образом, вам не придется иметь дело с новыми или старыми или удаляемыми строками. Это может оказаться невозможным из-за ограничений ссылочной целостности и т. Д.
Если вы получаете дельту, каждый ряд обычно делится на 1 из 2 категорий:
- Соответствующий ключ =
UPDATE
. Вы можете игнорировать строки с одинаковыми данными или перезаписать.
- Нет соответствующего ключа =
INSERT
Удаляются специальные. Строки, которые не существуют, не могут быть отправлены вам. Поэтому вам нужно договориться о том, как вы должны справиться с этим. В случае полной загрузки вы можете удалить все локальные строки, которых нет в полученном наборе данных.
В случае дельты вы можете согласиться отправить строку с маркером удаления (флаг, дата). Затем вы можете решить, сохранять ли строку маркером удаления (автоматически обрабатывается (1) выше), или вам следует DELETE
вашу строку. Я предлагаю сохранить его, потому что рано или поздно кто-то обвинит вас в пропущенных строках / плохом качестве данных, а затем вы бросите DELETE_DATE им в лицо.
Для MySQL вы можете использовать INSERT ... ON DUPLICATE KEY UPDATE для реализации функции "upsert".
Вы должны были бы предоставить более подробную информацию, если вам нужна более конкретная помощь.
Обновление:
Хорошо, вот пример. Скажем, у вас есть следующая структура таблицы:
create table contracts(
contract_id int not null
,details1 varchar(20)
,details2 varchar(20)
,delete_date date
,primary key(contract_id)
);
Всякий раз, когда вы получаете обновленные строки, вы вставляете их во временную таблицу с идентичной структурой:
create table contracts_delta(
contract_id int not null
,details1 varchar(20)
,details2 varchar(20)
,delete_date date
,primary key(contract_id)
);
Некоторые примеры данных:
mysql> select * from contracts;
+-------------+----------+----------+-------------+
| contract_id | details1 | details2 | delete_date |
+-------------+----------+----------+-------------+
| 1 | a1 | a2 | NULL |
| 2 | b1 | b2 | NULL |
| 3 | c1 | c2 | 2011-01-03 |
+-------------+----------+----------+-------------+
mysql> select * from contracts_delta;
+-------------+----------+----------+-------------+
| contract_id | details1 | details2 | delete_date |
+-------------+----------+----------+-------------+
| 2 | b1 | b2 | 2011-01-03 | <-- Row was deleted
| 3 | c1 | c2 | NULL | <-- No longer deleted
| 4 | d1 | d2 | NULL | <-- This is new row
+-------------+----------+----------+-------------+
Используя синтаксис, на который я ссылался ранее, вы можете вставить все новые строки. Всякий раз, когда строка уже есть (на дубликате), мы вместо этого решили обновить столбцы. Обратите внимание, что это обрабатывает удаленные строки автоматически, так как delete_date является обычным столбцом, как и все остальное.
insert
into contracts(
contract_id
,details1
,details2
,delete_date
)
select contract_id
,details1
,details2
,delete_date
from contracts_delta s
on duplicate key
update contracts.details1 = s.details1
,contracts.details2 = s.details2
,contracts.delete_date = s.delete_date;
После "upsert" данные в контрактах будут выглядеть так:
mysql> select * from contracts;
+-------------+----------+----------+-------------+
| contract_id | details1 | details2 | delete_date |
+-------------+----------+----------+-------------+
| 1 | a1 | a2 | NULL |
| 2 | b1 | b2 | 2011-01-03 |
| 3 | c1 | c2 | NULL |
| 4 | d1 | d2 | NULL |
+-------------+----------+----------+-------------+
- В этот момент вы можете удалить дельта-таблицу (не забудьте создать ее заново в следующий раз)
drop table contracts_delta;
- Или вы можете просто обрезать его, чтобы сэкономить место. (В любом случае вам нужно убедиться, что он пуст при следующей загрузке)
truncate table contracts_delta;
- Или вы можете сохранить фактическую дельту (переименовать таблицу), если вам когда-нибудь понадобятся отдельные дельты
alter table contracts_delta rename to contracts_delta_20110115;