为啥像 Snowflake 和 Redshift 这样的列式数据库不能更改列顺序?

Posted

技术标签:

【中文标题】为啥像 Snowflake 和 Redshift 这样的列式数据库不能更改列顺序?【英文标题】:Why can't columnar databases like Snowflake and Redshift change the column order?为什么像 Snowflake 和 Redshift 这样的列式数据库不能更改列顺序? 【发布时间】:2020-01-09 14:17:58 【问题描述】:

我一直在使用 Redshift,现在正在测试 Snowflake。两者都是柱状数据库。我所读到的有关此类数据库的所有内容都表明它们按列而不是按行存储信息,这有助于大规模并行处理 (MPP)。

但我也看到他们无法更改列的顺序或在现有列之间添加列(不知道其他列式数据库)。添加新列的唯一方法是将其附加到末尾。如果要更改顺序,则需要使用新顺序重新创建表,删除旧的,并更改新的名称(这称为deep copy)。但这有时是不可能的,因为依赖关系甚至内存利用率。

我更惊讶的是,这可以在行数据库中完成,而不是在列数据库中。当然,它还不是功能肯定是有原因的,但我显然没有足够的信息。我认为这只是更改 information_schema 中表的序数的问题,但显然不是那么简单。

有人知道这是什么原因吗?

【问题讨论】:

Snowflake 没有使用严格的列式数据存储。 (见docs.snowflake.net/manuals/user-guide/…) 好点。它仍然不允许更改列位置。我很感兴趣 您可以在哪个基于行的数据库中更改列的顺序或在其间添加一列? “我对这可以在行数据库中完成这一事实感到更加惊讶” - 如果这可以在任何数据库中完成,我也会感到非常惊讶,无论存储是基于行还是基于列,根据我的经验,它不能。您可能已经体验过类似 SQL Server 中的可视化数据库设计器的体验,这使得您看起来可以对列重新排序,但实际上在后台使用新架构将数据选择到新表中. 改变列的顺序是没有意义的操作。列的顺序对任何事物的影响为零。并且您可以控制选择中列的顺序,您应该这样做作为选择 * 对相同列的访问速度较慢,因为雪花必须在流式传输结果之前读取所有分区元数据以了解输出列。跨度> 【参考方案1】:

通常,表中的列排序不被视为第一类属性。通过按顺序列出名称,可以按您需要的任何顺序检索列。

强调表格中的列顺序表明经常使用SELECT *。我强烈建议不要在没有明确的LIMIT 子句的列式数据库中使用SELECT *,以尽量减少影响。

如果必须更改列顺序,您可以在 Redshift 中通过按所需顺序创建一个新的空表版本,然后使用 ALTER TABLE APPEND 将数据快速移动到新表中。

https://docs.aws.amazon.com/redshift/latest/dg/r_ALTER_TABLE_APPEND.html

【讨论】:

【参考方案2】:

如果不删除并重新创建列,则无法更改列在内部存储的顺序。

您的 SQL 可以按您想要的任何顺序检索列。

按特定顺序列出列的一般要求是出于查看目的。

您可以将视图定义为所需的列顺序,并在所需的操作中使用该视图。

CREATE OR REPLACE TABLE CO_TEST(B NUMBER,A NUMBER);
INSERT INTO CO_TEST VALUES (1,2),(3,4),(5,6);
SELECT * FROM CO_TEST;
SELECT A,B FROM CO_TEST;

CREATE OR REPLACE VIEW CO_VIEW AS SELECT A,B FROM CO_TEST;
SELECT * FROM CO_VIEW;

创建视图以按所需顺序列出列不会干扰视图下方的实际表格,并且不会浪费与重新创建表格相关的资源。

【讨论】:

【参考方案3】:

在某些数据库(尤其是 Oracle)中,通过在列表末尾存储 NULLable 列来对表中的列进行排序会影响性能。与数据块中存储的使用方式有关。

【讨论】:

以上是关于为啥像 Snowflake 和 Redshift 这样的列式数据库不能更改列顺序?的主要内容,如果未能解决你的问题,请参考以下文章

解析 JSON 时出错:输入中有多个文档(Redshift 到 Snowflake SQL)

为啥 Redshift 和 S3 之间的 AWS 文件大小不同?

为啥 Snowflake 中的 FUTURE 授权默认需要 AccountAdmin?

雪花“PARTITION BY”复制选项,包括输出数据集中的分区列

为啥 Snowflake 中这两个相似的查询具有非常不同的性能?

在 Snowflake 中,为啥当你同时分配两个变量时,变量有 256 字节的限制?