我认为您对增量的概念感到困惑。
您要么收到全部负载(整个数据集),要么只收到更改(“增量”)。
如果你处理满载,你可以做一个截断+插入。这样您就不必处理新旧行或删除。由于参照完整性约束等原因,这可能不可行。
如果您收到 delta,则每行通常会被放入 2 个类别中的 1 个类别中:
- 匹配键 =
UPDATE
。您可以选择忽略具有相同数据的行或覆盖。
- 没有匹配的键 =
INSERT
删除是特殊的。不存在的行无法发送给您。因此,您需要就如何处理它达成一致。在满载的情况下,可以删除接收到的数据集中不存在的所有本地行。
如果是 delta,您可以同意发送带有删除标记(标志、日期)的行。然后,您可以决定是否使用删除标记(由上面的 (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 |
+-------------+----------+----------+-------------+
-- 此时可以选择删除delta表(下次记得重新创建)
drop table contracts_delta;
- 或者您可以截断它以节省一些空间。(无论如何,您需要确保它在下一次加载时是空的)
truncate table contracts_delta;
-- 或者您可以保存实际的增量(重命名表),以防您有时需要单独的增量
alter table contracts_delta rename to contracts_delta_20110115;