分区表分区字段的update操作

本文介绍Oracle中分区表的默认限制及如何通过启用row movement属性来更新分区键字段,包括示例表创建、数据插入、更新操作及rowid的变化。
默认情况下,oracle的分区表对于分区字段是不允许进行update操作的,如果有对分区字段行进update,就会报错——ORA-14402: 更新分区关键字列将导致分区的更改。但是可以通过打开表的row movement属性来允许对分区字段的update操作。

例:创建分区表test_part进行实验

create table TEST_PART
(
  A1 NUMBERnot null,
  A2 DATE      not null,
  A3 VARCHAR2(6) not null,
  A4 DATE not null,
  A5 NUMBER not null,
)
partition by range (A1)
(
  partition P1 values less than (1000),
  partition P2 values less than (2000),
  partition P3 values less than (3000),
  partition P4 values less than (4000),
  partition P5 values less than (5000),
  partition P6 values less than (MAXVALUE)
);

插入如下的数据
SQL> select * from test_part;

        A1 A2          A3     A4                  A5
---------- ----------- ------ ----------- ----------
       123 2006-06-30  123456 2006-06-30         123
       456 2006-06-30  asdfgh 2006-06-30         456
         1 2006-06-30  234123 2006-06-30           1
         2 2006-06-30  234234 2006-06-30           2
      1234 2006-06-30  456789 2006-06-30        1234
      1111 2006-06-30  ewrqwe 2006-06-30        1111
      2222 2006-06-30  fdafda 2006-06-30        2222
      3333 2006-06-30  342342 2006-06-30        3333
      5678 2006-06-30  qwerty 2006-06-30        5678

9 rows selected

分区P1、P2的数据分别为:
SQL> select rowid,t.* from test_part partition(p1) t;

ROWID                      A1 A2          A3     A4                  A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLoAAGAAAtsEAAB        456 2006-06-30  asdfgh 2006-06-30         456
AAAGLoAAGAAAtsEAAC          1 2006-06-30  234123 2006-06-30           1
AAAGLoAAGAAAtsEAAD          2 2006-06-30  234234 2006-06-30           2
AAAGLoAAGAAAtsEAAE        123 2006-06-30  123456 2006-06-30         123

SQL> select rowid,t.* from test_part partition(p2) t;

ROWID                      A1 A2          A3     A4                  A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLwAAGAAA+8MAAC       1234 2006-06-30  456789 2006-06-30        1234
AAAGLwAAGAAA+8MAAD       1111 2006-06-30  ewrqwe 2006-06-30        1111

直接update提示错误
SQL> update test_part set a1=1123 where a1=123;

update test_part set a1=1123 where a1=123

ORA-14402: 更新分区关键字列将导致分区的更改

打开row movement属性
SQL> alter table test_part enable row movement;

Table altered

再次执行update操作
SQL> update test_part set a1=1123 where a1=123;

1 row updated

执行是成功的并迁移到分区P2上了,且这时候rowid也发生了变化
SQL> select rowid,t.* from test_part partition(p2) t;

ROWID                      A1 A2          A3     A4                  A5
------------------ ---------- ----------- ------ ----------- ----------
AAAGLwAAGAAA+8MAAC       1234 2006-06-30  456789 2006-06-30        1234
AAAGLwAAGAAA+8MAAD       1111 2006-06-30  ewrqwe 2006-06-30        1111
AAAGLwAAGAAA+8PAAB       1123 2006-06-30  123456 2006-06-30         123

SQL> 

enable row movement可以允许数据段的压缩、update分区字段的数据(跨分区的)

但是,也是有限制性的:对于普通表(heap-organized)行迁移后rowid会发生变化,对于索引表(index-organized)rowid虽然依然有效,但是其实际对应的物理构成是错误的。

转载于:https://www.cnblogs.com/yifan268/archive/2008/06/14/1221114.html

<think>我们正在使用Vertica数据库,需要获取表的分区字段信息。根据引用[2]中的内容,可以通过查询系统表`tables`来获取分区表的信息,其中`partition_expression`列就表示分区表达式(即分区字段的计算方式)。但是,我们可能更关心的是分区字段本身,而分区表达式可能是一个表达式(如`YEAR(create_time)`),也可能直接是一个字段名。不过,在Vertica中,分区字段并不是直接存储为一个字段名,而是通过分区表达式定义的。因此,我们可以通过查询`tables`表的`partition_expression`列来获取分区信息。根据引用[2]提供的查询:```sqlselecttable_schema,owner_name,table_name,partition_expressionfromtableswherepartition_expression<>'';```这个查询会返回所有分区表分区表达式。如果表不是分区表,则`partition_expression`为空,所以通过条件`partition_expression<>''`可以过滤出分区表。但是,用户的问题是如何获取某个特定表的分区字段(或分区表达式)。我们可以修改上述查询,指定表名和模式(schema)。例如,如果我们要查询模式`schema_name`下表`table_name`的分区表达式,可以这样:```sqlSELECTpartition_expressionFROMv_catalog.tablesWHEREtable_schema='schema_name'ANDtable_name='table_name'ANDpartition_expression<>'';```注意:系统表`tables`位于`v_catalog`模式下,所以完整的表名是`v_catalog.tables`(在引用[2]中直接用了`tables`,可能是因为在搜索路径中已经包含了`v_catalog`,但为了明确,建议使用`v_catalog.tables`)。另外,如果表是分区表,那么`partition_expression`列就会显示分区表达式。这个表达式可能是字段名,也可能是更复杂的表达式。例如,如果分区是按一个字段直接分区,比如`dt`,那么表达式就是`dt`。如果是按月份分区,可能是`DATE_TRUNC('month',create_time)`。所以,这个查询的结果就是分区表达式。如果用户想知道分区字段,可能需要从表达式中解析出字段名(如果表达式是一个字段的话)。但通常情况下,我们直接使用分区表达式来理解分区方式。因此,回答用户的问题:在Vertica中,可以通过查询系统表`v_catalog.tables`的`partition_expression`列来获取表的分区表达式。下面给出完整的SQL示例:```sqlSELECTtable_schema,table_name,partition_expressionFROMv_catalog.tablesWHEREtable_name='your_table_name'--替换为你的表名ANDtable_schema='your_schema_name'--替换为你的模式名,如果不指定模式,则可能匹配多个同名的表(在不同模式下)ANDpartition_expression<>'';```如果不知道表所在的模式,或者想查询所有模式中该表名的分区表达式,可以省略模式条件,但要注意可能会有多个同名的表在不同的模式下。另外,如果表不是分区表,则不会返回任何行。§§相关问题§§1.如何创建Vertica分区表?2.Vertica中的分区和分片有什么区别?3.如何修改Vertica表的分区表达式?4.Vertica分区表如何进行数据删除?</think>### Vertica 获取表的分区字段方法 在 Vertica 中获取表的分区字段信息,可通过查询系统表 `v_catalog.tables` 实现。以下是详细步骤: #### 方法一:查询所有分区表信息 ```sql SELECT table_schema AS 模式名, table_name AS 表名, partition_expression AS 分区表达式 FROM v_catalog.tables WHERE partition_expression <> ''; ``` **说明**: 1. `partition_expression` 字段直接显示分区定义(如 `YEAR(create_date)`) 2. 条件 `partition_expression <> ''` 过滤非分区表 3. 结果包含所有分区表清单[^2] #### 方法二:查询特定表的分区字段 ```sql SELECT partition_expression AS 分区字段表达式 FROM v_catalog.tables WHERE table_schema = 'your_schema' -- 替换为实际模式名 AND table_name = 'your_table' -- 替换为实际表名 AND partition_expression <> ''; ``` #### 示例输出: | 模式名 | 表名 | 分区表达式 | |----------|------------|-------------------| | sales | fact_order | YEAR(order_date) | | inventory| stock | MONTH(update_dt) | **关键点**: 1. 分区信息存储在系统视图 `v_catalog.tables` 中 2. 实际分区字段可能被函数包装(如 `YEAR(dt)`) 3. 未返回结果表示该表未分区或表名错误 > ⚠️ 注意:Vertica 的分区是逻辑划分,实际存储仍按 `ROS` 容器组织。获取分区信息后,可通过 `EXPLAIN` 验证查询是否利用分区剪枝优化[^1]。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值