更改依赖表的排序和分布

Posted

技术标签:

【中文标题】更改依赖表的排序和分布【英文标题】:Alter sort and distribution for dependent tables 【发布时间】:2018-05-23 07:29:18 【问题描述】:

这是更改 Redshift 表中的排序和分布键的查询。

CREATE TABLE new_dummy 
  DISTKEY (id)
  SORTKEY (account_id,created_at)
  AS (SELECT * FROM dummy);

ALTER TABLE dummy RENAME TO old_dummy;
ALTER TABLE new_dummy RENAME TO dummy;
DROP TABLE old_dummy;

它会抛出以下错误:

错误:无法删除表 old_dummy,因为其他对象依赖于它 提示:使用 DROP ... CASCADE 也可以删除依赖对象。

那么是不是不能更改依赖表的键?

【问题讨论】:

【参考方案1】:

您似乎有引用原始 (dummy) 表的 VIEW。

重命名表时,VIEW 继续指向原始表,而不管它的名称是什么。因此,尝试删除表会导致错误。

您需要在删除表格之前删除视图。然后,您可以重新创建视图以指向新的 dummy 表。

所以,流程是:

创建new_dummy并加载数据 下拉视图 删除dummynew_dummy 重命名为dummy 创建视图

您可能认为他的做法很糟糕,但这实际上是一个很好的功能,因为重命名表格不会破坏任何视图。视图将自动保留在正确的表格中。

更新:

根据 Joe 在下面的评论,流程将是:

创建视图...没有架构绑定

然后,对于每次重新加载:

创建new_dummy并加载数据 删除dummynew_dummy 重命名为dummy

【讨论】:

请注意,您以后可以通过使用WITH NO SCHEMA BINDING 子句创建视图来避免此问题。 docs.aws.amazon.com/redshift/latest/dg/r_CREATE_VIEW.html 我没有任何意见。但是我用其他表定义了一些外键定义。 嗯,奇怪的是外键导致了这些问题,因为在 Redshift 中没有强制使用外键(但它们用于优化查询)。在这种情况下,重命名表将无济于事。【参考方案2】:

此答案基于您在表定义中有外键引用的事实,这与重命名和删除表的过程不兼容。

鉴于这种情况,我建议您按如下方式加载数据:

开始交易 DELETE * 来自表 使用INSERT INTO 加载数据 结束交易

这意味着您正在完全重新加载表格的内容。将其包装在事务中意味着表不会出现“空”的时间段。

但是,这会使表格有点混乱,需要VACUUM 才能删除旧数据。

或者,您可以:

TRUNCATE餐桌 使用INSERT INTO 加载数据

TRUNCATE 不需要清理,因为它会清除与表关联的所有数据(不仅仅是将其标记为删除)。但是,TRUNCATE 会立即提交事务,因此会出现表为空的间隙。

【讨论】:

以上是关于更改依赖表的排序和分布的主要内容,如果未能解决你的问题,请参考以下文章

sql 更改数据库表的排序规则

mysql 错误汇总

Redshift 数据库中维度表的排序和分布键选择

表的创建更改和删除

SQL Server修改表结构时,不允许保存更改,阻止保存要求重新创建表的更改

基数排序和更改基数