绑定完请刷新页面
取消
刷新

分享好友

×
取消 复制
Oracle虚拟列分区测试
2021-10-19 14:59:17

虚拟列分区是基于其他列进行虚拟计算的结果做分区,这个虚拟列不会实际存储值,是通过其他列计算而来,虚拟列丰富了Oracle分区键的选择。

CREATE TABLE t (
d1 NUMBER,
d2 NUMBER,
d3 NUMBER,
d4 NUMBER,
d5 NUMBER,
d6 NUMBER,
d7 NUMBER,
-- d8 NUMBER,
n1 NUMBER,
n2 AS (CASE n1 WHEN 1 THEN 1 WHEN 2 THEN 2 ELSE 0 END) VIRTUAL
)
PARTITION BY LIST (n2) (
PARTITION zero VALUES (0),
PARTITION one VALUES (1),
PARTITION two VALUES (2)
)
ENABLE ROW MOVEMENT;


SQL> desc t;
Name Null? Type
----------------------------------------- -------- ----------------------------
D1 NUMBER
D2 NUMBER
D3 NUMBER
D4 NUMBER
D5 NUMBER
D6 NUMBER
D7 NUMBER
N1 NUMBER
N2 NUMBER

字段N2是虚拟字段,是通过字段N1的值计算而来,N1的值只有三个1,2,0,对应N1的值为1,2,其他。

下面插入数据
SQL> insert into t (n1) values(0);

1 row created.

SQL> insert into t (n1) values(1);

1 row created.

SQL> insert into t (n1) values(2);

1 row created.

SQL> insert into t (n1) values(3);

1 row created.

SQL> commit;

Commit complete.
查看分区分布
SQL>select table_name,partition_name,PARTITION_POSITION,TABLESPACE_NAME from user_tab_partitions where table_NAME='T'

TABLE_NAME PARTITION_ PARTITION_POSITION TABLESPACE_NAME
---------- ---------- ------------------ --------------------
T ZERO 1 USERS
T ONE 2 USERS
T TWO 3 USERS


数据查询结果
SQL> select * from t;

D1 D2 D3 D4 D5 D6 D7 N1 N2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
0 0
3 0
1 1
2 2
数据在分区中的分布
SQL> select * from t partition(zero);

D1 D2 D3 D4 D5 D6 D7 N1 N2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
0 0
3 0

SQL> select * from t partition(one);

D1 D2 D3 D4 D5 D6 D7 N1 N2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
1 1

SQL> select * from t partition(two);

D1 D2 D3 D4 D5 D6 D7 N1 N2
---------- ---------- ---------- ---------- ---------- ---------- ---------- ---------- ----------
2 2

经过查询验证数据确实按照虚拟列的值存储,并且虚拟列确实通过计算而来。

下面通过查询rowid来确定N2的值来自不同的行。
SQL> select rowid,n1,n2 from t partition(zero);

ROWID N1 N2
------------------ ---------- ----------
AAASPBAAHAAAAF8AAA 0 0
AAASPBAAHAAAAF8AAB 3 0

SQL> select rowid,n1 from t partition(zero);

ROWID N1
------------------ ----------
AAASPBAAHAAAAF8AAA 0
AAASPBAAHAAAAF8AAB 3

虚拟列可以像正常列一样做查询使用,但是不支持更新,虚拟列是通过其他列经过函数计算推导而来,这个
计算顺序无法页不必可逆。
SQL> SELECT rowid, n1, n2 FROM t WHERE n2 = 0;

ROWID N1 N2
------------------ ---------- ----------
AAASPBAAHAAAAF8AAA 0 0
AAASPBAAHAAAAF8AAB 3 0


SQL> update t set n2=0 where n2=1;
update t set n2=0 where n2=1
*
ERROR at line 1:
ORA-54017: UPDATE operation disallowed on virtual columns

支持删除
SQL> delete from t where n2=0;

2 rows deleted.

SQL> SELECT rowid, n1, n2 FROM t WHERE n2 = 0;

no rows selected


在实际生产中,我们确实有这样的需求,比如用户插入数据字段为date类型,但是由于数据量大需要每天做分区,所以此时就需要从日期字段中提取day的值,将数据放入分区表。Oracle虚拟列分区的功能确实增加了分区灵活度,更好的满足多样的业务需求。

分享好友

分享这个小栈给你的朋友们,一起进步吧。

Oracle运维新鲜事-技术与管理各占半边天
创建时间:2020-08-04 11:34:57
本技术栈旨在分享技术心得,运维趣事,故障处理经验,调优案例,故障处理涉及集群,DG,OGG,大家生产中遇到的问题基本都会囊括了,我会发布生产库遇到的故障,希望在交流中互助互益,共同提高,也希望大家讨论,如果您有生产中遇到的集群问题,也可以在这里提出来,一起讨论,现实中也帮助不少同学解决了生产库的故障。
展开
订阅须知

• 所有用户可根据关注领域订阅专区或所有专区

• 付费订阅:虚拟交易,一经交易不退款;若特殊情况,可3日内客服咨询

• 专区发布评论属默认订阅所评论专区(除付费小栈外)

栈主、嘉宾

查看更多
  • Abraham林老师
    栈主
  • 小雨滴
    嘉宾
  • hawkliu
    嘉宾
  • u_97a59a25246404
    嘉宾

小栈成员

查看更多
  • 栈栈
  • dapan
  • 小菜鸟___
  • hwayw
戳我,来吐槽~