清除并填充 SQL 服务器中的表
Clear and populate tables in SQL Server
我有一个非常简单和常见的场景:我需要每天更新两个 table。它们通常结合在一起,仅供用户阅读(除了我的维护工作外没有更新发生,这需要几分钟 运行)。
我需要两个 table 中的数据版本保持同步 - 它们都需要随时具有相同版本的数据。另外,我想尽可能地限制可能的停机时间和锁定,因为 table 中的数据可以在更新期间主动查询。执行此操作的最佳方法是什么?
没有足够的信息来彻底回答这个问题,但是,我会尽力提供第一关。我建议使用更多信息更新您的答案。
假设一个 table 是只读的而另一个不是,一个事务中包含的截断和插入可能是一个可行的解决方案。
begin tran
truncate table tableA;
insert into TableA select * from TableB;
commit;
另一种方法是从两个来源获取主键值,对重要的列(差异很重要的列)进行哈希处理,然后在特定键的哈希值不匹配时更新 tables .
select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableA
except
select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableB
另一种选择是识别需要更改的记录(以多种方式,例如使用上面的哈希系统),删除相应的 PK 并将新记录插入目标 table 而不是一个完整的截断。
/* using example code above .... */
delete from tableA where exists (select 1 from TableB where pk = pk and hash <> hash);
insert into tableA select * from TableB where not exists (select 1 from tableA where pk = pk);
您可以将数据加载到不同架构中同名的 table 中,然后将它们换出。在这里加载 staging.Table1 和 staging.Table2,然后将它们与 dbo 中的版本交换。目标 table 必须为空:
begin transaction
truncate table dbo.Table1;
truncate table dbo.Table2;
alter table staging.Table1 switch to dbo.Table1;
alter table staging.Table2 switch to dbo.Table2;
commit transaction
我认为交换应该在它自己的事务中,因为它将获得模式锁。您始终可以多次重新加载暂存 tables,并在加载成功时交换。如果加载 tables 的过程需要一些时间,架构锁将干扰查询系统 tables,例如,如果您打开 SSMS 并尝试列出对象。
我有一个非常简单和常见的场景:我需要每天更新两个 table。它们通常结合在一起,仅供用户阅读(除了我的维护工作外没有更新发生,这需要几分钟 运行)。
我需要两个 table 中的数据版本保持同步 - 它们都需要随时具有相同版本的数据。另外,我想尽可能地限制可能的停机时间和锁定,因为 table 中的数据可以在更新期间主动查询。执行此操作的最佳方法是什么?
没有足够的信息来彻底回答这个问题,但是,我会尽力提供第一关。我建议使用更多信息更新您的答案。
假设一个 table 是只读的而另一个不是,一个事务中包含的截断和插入可能是一个可行的解决方案。
begin tran
truncate table tableA;
insert into TableA select * from TableB;
commit;
另一种方法是从两个来源获取主键值,对重要的列(差异很重要的列)进行哈希处理,然后在特定键的哈希值不匹配时更新 tables .
select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableA
except
select primary_key, hashbytes('md5', lower(concat(columna,columnb,columnc))) "hash"
from tableB
另一种选择是识别需要更改的记录(以多种方式,例如使用上面的哈希系统),删除相应的 PK 并将新记录插入目标 table 而不是一个完整的截断。
/* using example code above .... */
delete from tableA where exists (select 1 from TableB where pk = pk and hash <> hash);
insert into tableA select * from TableB where not exists (select 1 from tableA where pk = pk);
您可以将数据加载到不同架构中同名的 table 中,然后将它们换出。在这里加载 staging.Table1 和 staging.Table2,然后将它们与 dbo 中的版本交换。目标 table 必须为空:
begin transaction
truncate table dbo.Table1;
truncate table dbo.Table2;
alter table staging.Table1 switch to dbo.Table1;
alter table staging.Table2 switch to dbo.Table2;
commit transaction
我认为交换应该在它自己的事务中,因为它将获得模式锁。您始终可以多次重新加载暂存 tables,并在加载成功时交换。如果加载 tables 的过程需要一些时间,架构锁将干扰查询系统 tables,例如,如果您打开 SSMS 并尝试列出对象。