【问题标题】:ALTER table in vertica垂直中的 ALTER 表
【发布时间】:2014-06-24 17:27:41
【问题描述】:

我在 Vertica 中有一个带有 time_stamp:int 的表,其值为 Unix 时间戳,我想将此数据类型从 int 更改为 TIMESTAMPTZ

我试过了

ALTER TABLE exploded_names ALTER COLUMN time_stamp SET DATA TYPE TIMESTAMPTZ;

但出现以下错误

ROLLBACK 2353:无法更改列“time_stamp”的类型,因为它在投影“exploded_names_b0”的分段表达式中被引用

然后我试图放弃那个投影:

drop projection exploded_names_b0 CASCADE;
ROLLBACK 4122:投影的锚表上没有最新的超级投影爆炸了_names_b0
提示:使用 DROP TABLE ... CASCADE 删除锚表及其最后一个投影,或者创建一个替换的超级投影

我不想放下桌子。

【问题讨论】:

  • time_stamp 的当前数据类型是什么?
  • 查看我的答案的更新。

标签: sql database vertica


【解决方案1】:

您收到的错误是告诉您该列用于投影的分段表达式,因此无法更改。这是SET DATA TYPE 选项的限制。您可以创建新的超级投影并省略分段子句中的列,或者使用新列类型创建新表和投影。

由于您提到您当前的列是int 类型,它不会转换为TIMESTAMPTZ。这就是我要做的:

第 1 步 - 设置示例数据

CREATE TABLE public.exploded_names (
   id int,
   time_stamp int
);

INSERT INTO public.exploded_names (id, time_stamp) VALUES (1, 1403635837);

COMMIT;

第 2 步 - 添加新列

ALTER TABLE public.exploded_names ADD COLUMN iso_time TIMESTAMPTZ;

第 3 步 - 创建新的超级投影

我们将使用SELECT EXPORT_OBJECTS('', 'public.exploded_names');获取现有的超级投影

CREATE PROJECTION public.exploded_names /*+createtype(L)*/
(
 id,
 time_stamp,
 iso_time
)
AS
 SELECT exploded_names.id,
        exploded_names.time_stamp,
        exploded_names.iso_time
 FROM public.exploded_names
 ORDER BY exploded_names.id,
          exploded_names.time_stamp
SEGMENTED BY hash(exploded_names.id, exploded_names.time_stamp) ALL NODES KSAFE 1;

SELECT MARK_DESIGN_KSAFE(1);

我们需要删除time_stamp 列并在分段子句中添加iso_time 并更改新超投影的名称:

CREATE PROJECTION public.exploded_names_2
(
 id,
 time_stamp,
 iso_time
)
AS
 SELECT exploded_names.id,
        exploded_names.time_stamp,
        exploded_names.iso_time
 FROM public.exploded_names
 ORDER BY exploded_names.id,
          exploded_names.time_stamp
SEGMENTED BY hash(exploded_names.id, exploded_names.iso_time) ALL NODES KSAFE 1;

SELECT MARK_DESIGN_KSAFE(1);

第 4 步 - 填充新列

在这里,我们将使用转换后的 Unix 时间戳更新 iso_time 列,然后刷新新的超投影。

UPDATE public.exploded_names SET iso_time = TO_TIMESTAMP(time_stamp);

COMMIT;

SELECT REFRESH('public.exploded_names');

第 5 步 - 丢弃旧的超投影

我们需要推进古代历史标记,然后放下旧的超级投影:

SELECT MAKE_AHM_NOW();

DROP PROJECTION public.exploded_names;

第 6 步 - 验证预测

让我们确保设置正确的投影SELECT GET_PROJECTIONS('public.exploded_names');

 当前系统 K 为 1。
节点数:3。
表 public.exploded_names 有 2 个投影。

投影名称:[Segmented] [Seg Cols] [# of Buddies] [Buddy Projections] [Safe] [UptoDate] [Stats]
-------------------------------------------------- --------------------------------------------------
public.exploded_names_2_b1 [分段:是] [分段列:“public.exploded_names.id”,“public.exploded_names.iso_time”] [K:1] [public.exploded_names_2_b0] [安全:是] [UptoDate:是] [统计: 行数]
public.exploded_names_2_b0 [分段:是] [分段列:“public.exploded_names.id”,“public.exploded_names.iso_time”] [K:1] [public.exploded_names_2_b1] [安全:是] [UptoDate:是] [统计: 行数]

附带说明,如果您还没有,您应该运行 Database Designer 来获得优化的投影。

【讨论】:

  • 创建另一个投影不会使那个投影成为超级投影....正在阅读代码,如果你能/知道如何做到这一点。但我认为它是在创建表时定义的,这意味着您在这里唯一的选择是删除并重新创建。
猜你喜欢
  • 2021-09-12
  • 2016-11-11
  • 1970-01-01
  • 2011-12-28
  • 2016-03-29
  • 2011-10-30
  • 2013-10-15
  • 2015-03-01
  • 2023-03-27
相关资源
最近更新 更多