【问题标题】:Partitioning a Table Referenced by a Foreign Key对外键引用的表进行分区
【发布时间】:2020-02-27 11:43:02
【问题描述】:

每月对大约 20 个表进行分区。它们都有一个日期列,作为分区键。到目前为止一切都很好,但是许多分区表被一个或多个外键引用。这使我无法进行切换+删除分区。因为 SQL Server 给出了错误:

Msg 50000,级别 16,状态 1,过程 HandleError,第 26 行 [批处理开始行 0]

表不能被外键约束引用。

一种可能性是在切换前删除约束并在切换后重新创建它们,正如您在屏幕截图中看到的那样,有很多 FK。另一种选择是在删除最旧的分区之前对每个受影响的表执行删除语句。但这需要时间,因为我们正在谈论数百万条记录/分区。

在 Oracle 中,这似乎没有问题。一旦 Oracle 发现不再有从 FK 到 PK 的引用,就可以删除分区。在 SQL Server 中没有。为了确定,我试了一下。

有没有人知道如何以优雅的方式解决这个问题?

【问题讨论】:

  • 不,恐怕您将不得不遵循删除并重新创建 FK 的方法...多次遇到此问题,但没有找到解决此问题的方法
  • 离题 - 属于dba

标签: sql-server foreign-keys primary-key partitioning


【解决方案1】:

您可以使用nockeck constraint 命令修改您的 FK 以不检查现有数据。然后分区切换将起作用。请参阅下面的示例。

CREATE PARTITION FUNCTION part_fun_test(int)
AS RANGE RIGHT FOR VALUES(10, 20, 30)
GO
CREATE PARTITION SCHEME part_schem AS PARTITION part_fun_test
ALL TO ([primary])
GO
CREATE TABLE Main_t(
id INT IDENTITY PRIMARY KEY CLUSTERED,
name VARCHAR(50)
) ON part_schem(id)
GO

CREATE TABLE Main_t_ref(
ID INT IDENTITY, 
MainID INT CONSTRAINT FK_t FOREIGN KEY REFERENCES dbo.Main_t(id)
)
GO 
CREATE TABLE Second_t(
id INT IDENTITY PRIMARY KEY CLUSTERED,
name VARCHAR(50)
)

INSERT INTO dbo.Main_t
        ( name )
DEFAULT VALUES
GO 30 

ALTER TABLE dbo.Main_t SWITCH PARTITION 1 TO dbo.Second_t --error
GO
ALTER TABLE dbo.Main_t_ref NOCHECK CONSTRAINT FK_t
GO
ALTER TABLE dbo.Main_t SWITCH PARTITION 1 TO dbo.Second_t --no error
GO

【讨论】:

  • 要扩展上述解决方案,请注意这会使您的外键处于不受信任的状态。运行 ALTER TABLE WITH CHECK CHECK CONSTRAINT 可以解决这个问题,但这可能需要一些时间并导致 FK 阻塞引用更大的表。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多