DEFAULT 与 SET USING
修整表中的列可以查询具有 DEFAULT 和 SET USING 约束的其他表。在这两种情况下,查询表中的更改都不会自动传播到修整表。这两个约束的区别如下:
DEFAULT 列
Vertica 通常在将新行添加到修整表时通过 INSERT 和 COPY 等加载操作,或者当您使用指定 DEFAULT 表达式的新列创建或更改表时,对新行执行 DEFAULT 查询。在所有情况下,现有行中的值(包括具有 DEFAULT 表达式的其他列)保持不变。
要刷新列的默认值,您必须在该列上显式调用 UPDATE,如下所示:
=> UPDATE table-name SET column-name=DEFAULT;
SET USING 列
仅当您调用函数 REFRESH_COLUMNS 时,Vertica 才会执行 SET USING 查询。加载操作将新行中的 SET USING 列设置为 NULL。加载后,您必须调用 REFRESH_COLUMNS 从查询表中填充这些列。这在两个方面很有用:您可以将更新修整表的开销推迟到任何方便的时间;您可以重复查询源表以获取新数据。
SET USING 对于引用多个维度表中的数据的大型修整表特别有用。通常,只有一小部分 SET USING 列会发生更改,并且对修整表的查询并不总是需要最新数据。在这种情况下,您可以定期或仅在非高峰时段刷新表的内容。这些策略中的一种或两种可以最大限度地减少开销,并在查询大型数据集时提高性能。
您可以通过在以下两种模式之一中调用 REFRESH _COLUMNS 来控制刷新操作的范围:
-
UPDATE :将原始行标记为已删除并用新行替换它们。为了保存这些更新,您必须发出 COMMIT 语句。
-
REBUILD:替换指定列中的所有数据。重建操作是自动提交的。
如果对修整表进行了分区,则可以通过指定一个或多个分区键来减少在 REBUILD 模式下调用 REFRESH_COLUMNS 的开销。这样做会将重建操作限制到指定的分区。有关详细信息,请参阅基于分区的 REBUILD 操作。
示例
以下 UPDATE 语句更新 custDim
表:
=> UPDATE custDim SET name='Roz', gender='F' WHERE cid=2;
OUTPUT
--------
1
(1 row)
=> COMMIT;
COMMIT
更改不会传播到修整表 orderFact
(其中分别包含 SET USING 和 DEFAULT 列 cust_name
和 cust_gender
):
=> SELECT * FROM custDim ORDER BY cid;
cid | name | age | gender
-----+-------+-----+--------
1 | Alice | 25 | F
2 | Roz | 30 | F
3 | Eva | 32 | F
(3 rows)
=> SELECT order_id, order_date::date, cid, cust_name, cust_gender, amount FROM orderFact ORDER BY cid;
order_id | order_date | cid | cust_name | cust_gender | amount
----------+------------+-----+-----------+-------------+---------
100 | 2018-12-31 | 1 | Alice | F | 15.00
200 | 2018-12-31 | 1 | Alice | F | 1000.00
300 | 2018-12-31 | 2 | Boz | M | -50.00
500 | 2018-12-31 | 2 | Boz | M | 200.00
400 | 2018-12-31 | 3 | Eva | F | 100.00
(5 rows)
以下 INSERT 语句调用 cust_gender
列的 DEFAULT 查询并将该列设置为 F
。加载操作不会调用 cust_name
列的 SET USING 查询,因此 cust_name
设置为 null:
=> INSERT INTO orderFact(order_id, cid, amount) VALUES(500, 3, 750);
OUTPUT
--------
1
(1 row)
=> COMMIT;
COMMIT
=> SELECT order_id, order_date::date, cid, cust_name, cust_gender, amount FROM orderFact ORDER BY cid;
order_id | order_date | cid | cust_name | cust_gender | amount
----------+------------+-----+-----------+-------------+---------
100 | 2018-12-31 | 1 | Alice | F | 15.00
200 | 2018-12-31 | 1 | Alice | F | 1000.00
300 | 2018-12-31 | 2 | Boz | M | -50.00
500 | 2018-12-31 | 2 | Boz | M | 200.00
400 | 2018-12-31 | 3 | Eva | F | 100.00
500 | 2018-12-31 | 3 | | F | 750.00
(6 rows)
要更新 cust_name
中的值,请通过调用 REFRESH_COLUMNS 来调用其 SET USING 查询。REFRESH_COLUMNS 执行 cust_name
的 SET USING 查询:它查询表 custDim
中的 name
列并使用以下值更新 cust_name
:
-
将新行中的
cust_name
设置为Eva
。 -
返回
cid=2
的更新值,并将Boz
更改为Roz
。
=> SELECT REFRESH_COLUMNS ('orderFact','');
REFRESH_COLUMNS
---------------------------
refresh_columns completed
(1 row)
=> COMMIT;
COMMIT
=> SELECT order_id, order_date::date, cid, cust_name, cust_gender, amount FROM orderFact ORDER BY cid;
order_id | order_date | cid | cust_name | cust_gender | amount
----------+------------+-----+-----------+-------------+---------
100 | 2018-12-31 | 1 | Alice | F | 15.00
200 | 2018-12-31 | 1 | Alice | F | 1000.00
300 | 2018-12-31 | 2 | Roz | M | -50.00
500 | 2018-12-31 | 2 | Roz | M | 200.00
400 | 2018-12-31 | 3 | Eva | F | 100.00
500 | 2018-12-31 | 3 | Eva | F | 750.00
(6 rows)
REFRESH_COLUMNS 仅影响列 cust_name
中的值。gender
列中的值未更改,因此 cid=2
(Roz
) 的行设置仍设置为 M
。要使用 custDim.gender
中的默认值重新填充 orderFact.cust_gender
,请在 orderFact
上调用 UPDATE:
=> UPDATE orderFact SET cust_gender=DEFAULT WHERE cust_name='Roz';
OUTPUT
--------
2
(1 row)
=> COMMIT;
COMMIT
=> SELECT order_id, order_date::date, cid, cust_name, cust_gender, amount FROM orderFact ORDER BY cid;
order_id | order_date | cid | cust_name | cust_gender | amount
----------+------------+-----+-----------+-------------+---------
100 | 2018-12-31 | 1 | Alice | F | 15.00
200 | 2018-12-31 | 1 | Alice | F | 1000.00
300 | 2018-12-31 | 2 | Roz | F | -50.00
500 | 2018-12-31 | 2 | Roz | F | 200.00
400 | 2018-12-31 | 3 | Eva | F | 100.00
500 | 2018-12-31 | 3 | Eva | F | 750.00
(6 rows)