在vertica中的ALTER表

时间:2014-06-24 17:27:42

标签: sql database vertica

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

我试过

ALTER TABLE exploded_names ALTER COLUMN time_stamp SET DATA TYPE TIMESTAMPTZ;

但得到了以下错误

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;
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

我不想放弃这张桌子。

1 个答案:

答案 0 :(得分: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;

第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');

 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来获得优化的预测。