在vertica中的ALTER表

roy*_*roy 3 sql database vertica

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

我试过了

ALTER TABLE exploded_names ALTER COLUMN time_stamp SET DATA TYPE TIMESTAMPTZ;
Run Code Online (Sandbox Code Playgroud)

但得到了以下错误

ROLLBACK 2353:  Cannot alter type of column "time_stamp" since it is referenced in the segmentation expression of projection "exploded_names_b0"

然后我试图放弃这个预测:

drop projection exploded_names_b0 CASCADE;
Run Code Online (Sandbox Code Playgroud)
ROLLBACK 4122:  No up-to-date super projection left on the anchor table of projection exploded_names_b0
HINT:  Use DROP TABLE ... CASCADE to drop the anchor table and its last projection, or create a replacement super projection instead

我不想放弃桌子.

Ker*_*mit 15

您收到的错误告诉您该列用于投影的分段表达式,因此无法更改.这是对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;
Run Code Online (Sandbox Code Playgroud)

第2步 - 添加新列

ALTER TABLE public.exploded_names ADD COLUMN iso_time TIMESTAMPTZ;
Run Code Online (Sandbox Code Playgroud)

第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);
Run Code Online (Sandbox Code Playgroud)

我们需要删除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);
Run Code Online (Sandbox Code Playgroud)

第4步 - 填充新列

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

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

COMMIT;

SELECT REFRESH('public.exploded_names');
Run Code Online (Sandbox Code Playgroud)

第5步 - 删除旧的超级投影

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

SELECT MAKE_AHM_NOW();

DROP PROJECTION public.exploded_names;
Run Code Online (Sandbox Code Playgroud)

第6步 - 验证投影

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

 Current system K is 1.
# of Nodes: 3.
Table public.exploded_names has 2 projections.

Projection Name: [Segmented] [Seg Cols] [# of Buddies] [Buddy Projections] [Safe] [UptoDate] [Stats]
----------------------------------------------------------------------------------------------------
public.exploded_names_2_b1 [Segmented: Yes] [Seg Cols: "public.exploded_names.id", "public.exploded_names.iso_time"] [K: 1] [public.exploded_names_2_b0] [Safe: Yes] [UptoDate: Yes] [Stats: RowCounts]
public.exploded_names_2_b0 [Segmented: Yes] [Seg Cols: "public.exploded_names.id", "public.exploded_names.iso_time"] [K: 1] [public.exploded_names_2_b1] [Safe: Yes] [UptoDate: Yes] [Stats: RowCounts]

另外,如果您还没有,则应运行Database Designer以获得优化的预测.