flattened table

flattened table(扁平表)

高度规范化的数据库设计通常使用星型或雪花型架构模型,包括多个大型事实表和许多较小的维度表。查询通常涉及大事实表和多个维表之间的连接。根据表的数量和加入的数据量,这些查询会产生很大的开销。

为避免此问题,某些用户创建了宽表,这些表组合了查询所需的所有事实和维度表列,这些表可以显着加快查询执行速度。但是,维护冗余的规范化和非规范化数据集有其自己的管理成本。

非规范化或扁平化的表可以最小化这些问题。扁平表可以包含通过查询其他表来获取其值的列。源表和扁平表的操作是分离的,一个中的更改不会自动传播到另一个。这最小化了非规范化表的典型开销。
扁平表使用以下列约束子句之一定义派生列:
1.DEFAULT query-expression 在以下两个事件发生时设置列值:

使用CREATE TABLE 或创建列时ALTER TABLE...ADD COLUMN。
任何表加载操作如INSERT。

2.SET USING query-expression 仅在REFRESH_COLUMNS调用函数时设置列值。
在这两种情况下,query-expression必须只返回一个行和列值,或者不返回任何值。如果查询未返回任何行,则将列值设置为NULL。

创建扁平表

扁平表通常是一个事实表,其中一个或多个列查询其他表的值,通过DEFAULT或SET USING约束。与其他列一样,您可以在创建扁平表时设置这些约束,也可以在以后通过修改表模式设置这些约束:

CREATE TABLE ...(...,列名 数据类型 {DEFAULT | SET USING} 表达式,...)
ALTER TABLE ... ADD COLUMN 列名 {DEFAULT | SET USING} 表达式
ALTER TABLE ... ALTER COLUMN column-name {SET DEFAULT | SET USING} 表达式

DEFAULT和SET USING约束可用于所有数据类型的列。
您为这些约束设置的表达式存储在系统表中COLUMNS,列COLUMN_DEFAULT和COLUMN_SET_USING中。两个约束都支持相同的表达式。

DEFAULT 并且SET USING通常支持相同的表达式。这些包括:

  • 查询
  • 同一个表中的其他列
  • 文字(常数)
  • 所有Vertica支持的操作

以下类别的功能:

  • 空处理
  • 用户定义的标量
  • 系统信息
  • 字符串
  • 数学
  • 格式

注意:如果SET USING或DEFAULT查询表达式连接具有相同名称的两列,则列名必须包括其表名。否则Vertica假定两列都引用维度表,并且谓词始终求值为true。

扁平表示例

在以下示例中,列orderFact.cust_name和orderFact.cust_gender分别定义为SET USING和DEFAULT列。两列都通过查询表custDim获取它们的值:

=> CREATE TABLE public.custDim(
     cid int PRIMARY KEY NOT NULL,
     name varchar(20),
     age int,
     gender varchar(1)
);
=> CREATE TABLE public.orderFact(
     order_id int PRIMARY KEY NOT NULL,
     cid int REFERENCES public.custDim(cid),
     cust_name varchar(20) SET USING (SELECT name FROM public.custDim WHERE (custDim.cid = orderFact.cid)),
     cust_gender varchar(1) DEFAULT (SELECT gender FROM public.custDim WHERE (custDim.cid = orderFact.cid)),
     amount numeric(12,2)
);

向两个表中插入一些数据:

=> INSERT INTO custDim VALUES(1, 'Alice', 25, 'F');
=> INSERT INTO custDim VALUES(2, 'Boz', 30, 'M');
=> INSERT INTO custDim VALUES(3, 'Eva', 32, 'F');
=>
=> INSERT INTO orderFact (order_id, cid, amount) VALUES(100, 1, 15);
=> INSERT INTO orderFact (order_id, cid, amount) VALUES(200, 1, 1000);
=> INSERT INTO orderFact (order_id, cid, amount) VALUES(300, 2, -50);
=> INSERT INTO orderFact (order_id, cid, amount) VALUES(400, 3, 100);
=> INSERT INTO orderFact (order_id, cid, amount) VALUES(500, 2, 200);
=> COMMIT;

查询两张表,得到以下信息:

=> SELECT * FROM custDim;
 cid | name  | age | gender
-----+-------+-----+--------
   1 | Alice |  25 | F
   2 | Boz   |  30 | M
   3 | Eva   |  32 | F
(3 rows)

=> SELECT * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 |           | F           |   15.00
      200 |   1 |           | F           | 1000.00
      300 |   2 |           | M           |  -50.00
      500 |   2 |           | M           |  200.00
      400 |   3 |           | F           |  100.00
(5 rows)

Vertica会自动填充DEFAULT列orderFact.cust_gender,但SET USING列orderFact.cust_name仍然存在NULL。要填充此列,必须在扁平表orderFact上调用函数REFRESH_COLUMNS。此函数调用orderFact.cust_name列的SET USING查询并从结果集中填充列:

=> SELECT REFRESH_COLUMNS('orderFact', 'cust_name', 'REBUILD');
 
      REFRESH_COLUMNS
---------------------------
refresh_columns completed
(1 row)

=> COMMIT;
COMMIT
=> SELECT * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |   15.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Boz       | M           |  -50.00
      500 |   2 | Boz       | M           |  200.00
      400 |   3 | Eva       | F           |  100.00
(5 rows)
关于REFRESH_COLUMNS函数

刷新使用SET USING约束定义的表列。与REFRESH_COLUMNS操作关联的所有刷新操作都属于同一事务。REFRESH_COLUMNS 必须刷新指定的所有表和列, 否则,整个操作将回滚。

语法:
REFRESH_COLUMNS ( 'tables', '[columns]' [, '[refresh‑mode]' ] )

对于参数tables,可以指定一个或多个表,当指定多个表时,刷新模式必须指定为REBUILD。
对于参数columns,可以指定一个或多个列,或者某个表的所有列。

SELECT REFRESH_COLUMNS ('t1, t2', 't1.a, t2.b', 'REBUILD');
SELECT REFRESH_COLUMNS ('t1, t2', 't1.*, t2.b', 'REBUILD');

若为’ '(空字符串),则表示刷新指定表中的所有SET USING/ DEFAULT USING列。
对于参数refresh‑mode:

  • UPDATE:将原始行标记为已删除,并将其替换为新行。要保存这些更新,您必须发出COMMIT声明。
  • REBUILD:替换指定列中的所有数据。重建操作是自动提交的。

如果设置为空字符串或省略,REFRESH_COLUMNS则以UPDATE模式执行。如果指定多个表,则必须显式指定REBUILD模式。

UPDATE模式与REBUILD模式的比较

通常,当SET USING列数据的更改行数相对较少时,使用UPDATE是一个更好的选择。
当SET USING 列数据有大量是是陈旧的,必须进行更新,使用REBUILD通常是更好的做法。建议在设置任何新的SET USING列时,调用REFRESH_COLUMNS函数并使用REBUILD模式。例如,在通过ALTER TABLE…ADD COLUMN添加列后进行刷新。

REBUILD模式的一些限制

如果你调用REFRESH_COLUMNS 并指定刷新模式REBUILD去刷新一个SET USING列,如果该列满足任何下列条件,则返回一个错误:

  • 指定为表分区键。
  • 包含在实时聚合projections或带有表达式的projections中。
  • 包含在projections的排序顺序或分段中。
  • 包含在projections中,并且projections省略了列SET USING表达式中引用的锚表列。
  • 包含在projections的GROUPED条款中。
SET USING 与 DEFAULT 的对比

扁平表中的具有SET USING和DEFAULT约束的列可以查询其他表。在这两种情况下,查询表中的更改都不会自动传播到扁平表。这两个约束条件有以下不同:

DEFAULT

只有在通过加载操作(如INSERT和COPY)将新行添加到扁平表时,Vertica才会对新行执行DEFAULT查询。 此后,原始数据源的更改(如delete和update)对扁平表没有影响(此时,对于default列,要手动调用update…set…default…,可见下文中的例子)。

SET USING

只有在调用函数REFRESH_COLUMNS时,Vertica才会执行SET USING查询。
加载操作将SET USING中的列设置为NULL,加载后,必须调用REFRESH_COLUMNS以从查询的表中填充这些列。 这在两个方面很有用:您可以将更新扁平表的开销推迟到方便的任何时间,以及您可以重复查询源表以获取新数据。

一个例外:当您使用ALTER TABLE … ALTER COLUMN将SET USING应用于现有列,或修改现有的SET USING表达式时。 在这种情况下,DDL操作使用UPDATE模式自动调用列上的REFRESH_COLUMNS。 刷新操作完成后,DDL操作会自动提交更新并返回。 如果刷新操作失败,Vertica将回滚整个DDL操作。 如果刷新操作涉及大数据集,则执行时间可能很长。

提示:删除列并添加新列可能更有效。 当您向表中添加SET USING列时,ALTER TABLE …ADD COLUMN不会调用REFRESH_COLUMNS。

SET USING对于引用来自多个维度表的数据的大型扁平表特别有用。 通常,只有一小部分SET USING列可能会发生变化,而对扁平表的查询并不总是需要最新的数据。 在这种情况下,您可以定期刷新表格内容,或仅在非高峰时段刷新表格内容。 这些策略中的一个或两个可以最小化维护成本,并在查询大型数据集时提升性能。

实例比较default与set using

用前面例子中的表,现在两张表的内容为:

  => SELECT * FROM custDim;
     cid | name  | age | gender
    -----+-------+-----+--------
       1 | Alice |  25 | F
       2 | Boz   |  30 | M
       3 | Eva   |  32 | F
    (3 rows)
=> SELECT * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |   15.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Boz       | M           |  -50.00
      500 |   2 | Boz       | M           |  200.00
      400 |   3 | Eva       | F           |  100.00
(5 rows)

操作1,修改表custDim

=> UPDATE custDim SET name='Roz', gender='F' WHERE cid=2;
 OUTPUT
--------
      1
(1 row)

=> COMMIT;
COMMIT

操作2,查看两张表中的内容,发现表orderFact,无论是default约束的列还是set using约束的列,都没有刷新。

=> 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 * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |   15.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Boz       | M           |  -50.00
      500 |   2 | Boz       | M           |  200.00
      400 |   3 | Eva       | F           |  100.00
(5 rows)

操作3,向表orderFact中插入一条数据,发现orderFact中的default列自动更新。

=> INSERT INTO orderFact(order_id, cid, amount)  VALUES(500, 3, 750);
 OUTPUT
--------
      1
(1 row)

=> COMMIT;
COMMIT
=> SELECT * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |   15.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Boz       | M           |  -50.00
      500 |   2 | Boz       | M           |  200.00
      400 |   3 | Eva       | F           |  100.00
      500 |   3 |           | F           |  750.00
(6 rows)

操作4,使用REFRESH_COLUMNS对表orderFact进行刷新。

=> SELECT REFRESH_COLUMNS ('orderFact','');
      REFRESH_COLUMNS 
---------------------------
 refresh_columns completed
(1 row)

=> COMMIT;
COMMIT
=> SELECT * from orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |  150.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Roz       | M           |  -50.00
      500 |   2 | Roz       | M           |  200.00
      400 |   3 | Eva       | F           |  100.00
      500 |   3 | Eva       | F           |  750.00
(6 rows)

发现REFRESH_COLUMNS仅影响列cust_name中的值。 列cust_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 * FROM orderFact ORDER BY cid;
 order_id | cid | cust_name | cust_gender | amount
----------+-----+-----------+-------------+---------
      100 |   1 | Alice     | F           |   15.00
      200 |   1 | Alice     | F           | 1000.00
      300 |   2 | Roz       | F           |  -50.00
      500 |   2 | Roz       | F           |  200.00
      400 |   3 | Eva       | F           |  100.00
      500 |   3 | Eva       | F           |  750.00
(6 rows)
修改SET USING和DEFAULT列
删除SET USING和DEFAULT约束
ALTER TABLE table-name ALTER COLUMN column-name DROP {SET USING | DEFAULT};
修改SET USING和DEFAULT表达式

您可以通过调用更改现有SET USING或DEFAULT列的查询表达式ALTER TABLE...ALTER COLUMN。修改SET USING列表达式时,Vertica会自动调用REFRESH_COLUMNS使用UPDATE模式,并重新填充该列。如果必须刷新大量行,则以下方法可能更可取:

1.删除列ALTER TABLE…DROP COLUMN。
2.调用ALTER TABLE…ADD COLUMN添加具有所需SET USING表达式的新表达式。

这种方法有两个好处:

  • 避免立即调用REFRESH_COLUMNS,并推迟原本发生的开销。
  • 允许您在调用时REFRESH_COLUMNS指定模式REBUILD ,这在许多情况下会更有效地重新填充列。
删除由SET USING或DEFAULT查询的列

Vertica强制执行扁平表与其查询的表之间的依赖关系。 除非删除操作(如DROP TABLE)时使用CASCADE关键字,否则尝试删除查询的列或其表将返回错误。 Vertica通过从扁平表中删除SET USING或DEFAULT约束来实现CASCADE。 表列及其数据不受影响。

参考:
vertica官方文档9.1.x—>Analyzing Data—>Flattened Tables
链接如下:
https://www.vertica.com/docs/9.1.x/HTML/index.htm#Authoring/AnalyzingData/FlattenedTables/FlattenedTables.htm%3FTocPath%3DAnalyzing%2520Data%7CFlattened%2520Tables%7C_____0

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
.flattened-pom.xml是一个文件,它在项目打包过程中由IDEA自动生成。它的作用是提供一个扁平化的pom.xml文件,供项目打包时读取依赖信息。 这个文件通常位于项目目录下,可以通过修改或删除它来解决一些问题。例如,当项目升级后,.flattened-pom.xml文件中的版本号可能会过时或错误,这时可以手动修改该文件中的版本号,以保持正确的依赖关系。或者,如果不需要该文件,也可以直接删除它。 如果你想查看一个具体的.flattened-pom.xml文件示例,你可以参考以下链接:<span class="em">1</span><span class="em">2</span><span class="em">3</span> #### 引用[.reference_title] - *1* *3* [idea 打包引入版本不对问题](https://blog.csdn.net/hcc_new_one_object/article/details/130984295)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] - *2* [【SpringBoot】Maven 版本管理与 flatten-maven-plugin 插件的使用及分析](https://blog.csdn.net/weixin_42201180/article/details/127204351)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v93^chatsearchT3_2"}}] [.reference_item style="max-width: 50%"] [ .reference_list ]

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值