这里达梦数据库学习系列的第四篇;今天主要来学习一下达梦数据库中的表相关知识。
SQL> set long 999
SQL> set pagesize 100
SQL> set lineshow off
SQL> select dbms_metadata.get_ddl('TABLE','ENMOTECH','BENCHMARKSQL') from dual;
DBMS_METADATA.GET_DDL('TABLE','ENMOTECH','BENCHMARKSQL')
------------------------------------------------------------------------------------------------------------------
CREATE TABLE "BENCHMARKSQL"."ENMOTECH"
(
"NAME" VARCHAR2(20),
"ID" NUMBER) STORAGE(ON "ENMOTECH", CLUSTERBTR) ;
used time: 5.966(ms). Execute id is 11.
从表结构来看,似乎跟Oracle 普通表差别很大,主要在于stroage 字句中有一个clusterbtr关键字。 这说明是一个普通表。关于创建的表
是普通表还是堆表,通过list_Table参数来进行控制,默认参数是0,表示普通表。这里我修改成1,即堆表。
SQL> select PARA_NAME,PARA_VALUE,FILE_VALUE,DESCRIPTION from v$dm_ini where PARA_NAME like '%LIST%';
PARA_NAME PARA_VALUE FILE_VALUE DESCRIPTION
------------------------ ---------- ---------- -----------------------------------------------------
IN_LIST_AS_JOIN_KEY 0 0 Whether to use in-list expression as join key
LISTEN_IP NULL NULL IP address on which the database server will listen
ENABLE_IN_VALUE_LIST_OPT 6 6 Flag of optimization methods for in-list expression
LIST_TABLE 1 1 Whether to convert tables to LIST tables when created
used time: 7.691(ms). Execute id is 7.
SQL>
我们再来创建一个测试表看看情况:
SQL> create table BENCHMARKSQL.enmotech2 as select * from BENCHMARKSQL.enmotech;
executed successfully
used time: 30.429(ms). Execute id is 5.
SQL> set lineshow off
SQL> set long 999
SQL> set pagesize 100
SQL> select dbms_metadata.get_ddl('TABLE','ENMOTECH2','BENCHMARKSQL') from dual;
DBMS_METADATA.GET_DDL('TABLE','ENMOTECH2','BENCHMARKSQL')
-----------------------------------------------------------------------------------------------------------------
CREATE TABLE "BENCHMARKSQL"."ENMOTECH2"
(
"NAME" VARCHAR2(20),
"ID" NUMBER) STORAGE(ON "ENMOTECH", NOBRANCH) ;
used time: 94.894(ms). Execute id is 6.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH a;
ROWID NAME ID
-------------------- ----- ----
1 roger 9999
used time: 1.620(ms). Execute id is 9.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH2 a;
ROWID NAME ID
-------------------- ----- ----
1099511638529 roger 9999
used time: 1.058(ms). Execute id is 8.
SQL> create table BENCHMARKSQL.enmotech2 as select * from BENCHMARKSQL.enmotech;
executed successfully
used time: 30.429(ms). Execute id is 5.
SQL> set lineshow off
SQL> set long 999
SQL> set pagesize 100
SQL> select dbms_metadata.get_ddl('TABLE','ENMOTECH2','BENCHMARKSQL') from dual;
DBMS_METADATA.GET_DDL('TABLE','ENMOTECH2','BENCHMARKSQL')
-----------------------------------------------------------------------------------------------------------------
CREATE TABLE "BENCHMARKSQL"."ENMOTECH2"
(
"NAME" VARCHAR2(20),
"ID" NUMBER) STORAGE(ON "ENMOTECH", NOBRANCH) ;
used time: 94.894(ms). Execute id is 6.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH a;
ROWID NAME ID
-------------------- ----- ----
1 roger 9999
used time: 1.620(ms). Execute id is 9.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH2 a;
ROWID NAME ID
-------------------- ----- ----
1099511638529 roger 9999
used time: 1.058(ms). Execute id is 8.
获取对象定义,还可以使用达梦提供的包来进行:
SQL> SP_TABLEDEF('BENCHMARKSQL','ENMOTECH2');
COLUMN_VALUE
-----------------------------------------------------------------------------------------------------------------
CREATE TABLE "BENCHMARKSQL"."ENMOTECH2" ( "NAME" VARCHAR2(20), "ID" NUMBER) STORAGE(ON "ENMOTECH", NOBRANCH) ;
used time: 1.784(ms). Execute id is 30.
我们可以看到,对于堆表而言,这里storage 子句中是NOBRANCH关键字。 通过查询达梦官方手册发现,堆表的情况下,有如下几种情况:
BRANCH、NOBRANCH 是堆表创建关键字,堆表为“扁平 B 树表”。这两个参数用 来指定堆表并发分支 BRANCH 和非并发分支 NOBRANCH 的数目。<BRANCH 数>取 值范围为 1~64,<NOBRANCH 数>取值范围为 1~64。
-
NOBRANCH:指定创建的表为堆表,并发分支个数为 0,非并发分支个数为 1;
-
BRANCH(<BRANCH 数>, <NOBRANCH 数>):指定创建的表为堆表,并发分支个数为<BRANCH 数>,非并发个数为<NOBRANCH 数>;
-
BRANCH <BRANCH 数>:指定创建的表为堆表,并发分支个数为<BRANCH数>,非并发分支个数为 0。
而普通clusterbtr属性,则为非堆表,即普通 B树表。
这里我们多准备一点数据进行观察:
SQL> insert BENCHMARKSQL.ENMOTECH2 select * from BENCHMARKSQL.ENMOTECH2;
affect rows 1
used time: 1.455(ms). Execute id is 10.
SQL> /
affect rows 2
used time: 0.788(ms). Execute id is 11.
SQL> /
affect rows 4
used time: 0.448(ms). Execute id is 12.
SQL> commit;
executed successfully
used time: 1.698(ms). Execute id is 13.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH2 a;
ROWID NAME ID
-------------------- ----- ----
1099511638529 roger 9999
1099511638530 roger 9999
1099511638531 roger 9999
1099511638532 roger 9999
1099511638533 roger 9999
1099511638534 roger 9999
1099511638535 roger 9999
1099511638536 roger 9999
8 rows got
used time: 0.377(ms). Execute id is 14.
SQL>
SQL> update BENCHMARKSQL.ENMOTECH2 set name='www.enmotech.com' where rowid=1099511638532;
affect rows 1
used time: 1.561(ms). Execute id is 16.
SQL> commit;
executed successfully
used time: 1.624(ms). Execute id is 17.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH2 a;
ROWID NAME ID
-------------------- ---------------- ----
1099511638529 roger 9999
1099511638530 roger 9999
1099511638531 roger 9999
1099511638532 www.enmotech.com 9999
1099511638533 roger 9999
1099511638534 roger 9999
1099511638535 roger 9999
1099511638536 roger 9999
8 rows got
used time: 0.513(ms). Execute id is 18.
SQL> insert BENCHMARKSQL.ENMOTECH select * from BENCHMARKSQL.ENMOTECH;
affect rows 1
used time: 0.903(ms). Execute id is 20.
SQL> /
affect rows 2
used time: 0.954(ms). Execute id is 21.
SQL> /
affect rows 4
used time: 0.631(ms). Execute id is 22.
SQL> commit;
executed successfully
used time: 1.205(ms). Execute id is 23.
SQL> update BENCHMARKSQL.ENMOTECH set name='enmotech.com' where rowid=5;
affect rows 1
used time: 1.386(ms). Execute id is 25.
SQL> commit;
executed successfully
used time: 1.854(ms). Execute id is 26.
SQL> select a.rowid,a.* from BENCHMARKSQL.ENMOTECH a;
ROWID NAME ID
-------------------- ------------ ----
1 roger 9999
2 roger 9999
3 roger 9999
4 roger 9999
5 enmotech.com 9999
6 roger 9999
7 roger 9999
8 roger 9999
8 rows got
used time: 0.238(ms). Execute id is 27.
SQL>
从测试来看,无论是普通表还是堆表,都存在ROWID的概念,我之前的理解有些不对。只不过达梦数据库中的ROWID结构看上去非常简单,似乎就是一个递增序列。
我们继续来探索一下达梦数据库的表相关参数属性;dm虽然没有Oracle pctfree,pctused等相关参数,不过也提供类似功能等参数;如FILLFACTOR。
FILLFACTOR参数是DM数据库提供的一个与性能有关的数据页级存储参数,它指定一个数据页初始化后插入数据时最大可以使用空间的百分比(100),该值在创建表/索引时可以指定。设置FILLFACTOR参数的值,是为了指定数据页中的可用空间百分比(FILLFACTOR)和可扩展空间百分比(100-FILLFACTOR)。
SQL> CREATE TABLE test0826
2 (id number,name varchar2(20))
3 STORAGE
4 ( INITIAL 1, MINEXTENTS 1,
5 NEXT 1, ON enmotech, FILLFACTOR 1);
executed successfully
used time: 10.266(ms). Execute id is 31.
SQL> drop table test0826;
executed successfully
used time: 33.268(ms). Execute id is 32.
SQL> CREATE TABLE test0826
2 (id number,name varchar2(20))
3 STORAGE
4 ( INITIAL 1, MINEXTENTS 1,
5 NEXT 1, ON enmotech, FILLFACTOR 0.1);
CREATE TABLE test0826
(id number,name varchar2(20))
STORAGE
( INITIAL 1, MINEXTENTS 1,
NEXT 1, ON enmotech, FILLFACTOR 0.1);
NEXT 1, ON enmotech, FILLFACTOR 0.1);
*
line 5, column 57, nearby [0.1] has error[-2007]:
Syntax error.
used time: 0.517(ms). Execute id is 0.
虽然FILLFACTOR参数取值范围从0到100;实际上0和100是没任何区别的。表示完全填充。该参数跟Oracle 功能类似oracle pctused和pctfree。从功能上来看,既要满足insert还要满足update,那么该参数不能过小;否则数据页分裂可能会比较严重。
接下来我们看看达梦数据库中对于分区表的支持情况。 查询官方手册,提供DM8种支持如下5种分区类型:
范围分区、哈希分区、列表分区、组合分区、间隔分区
看上去跟Oracle类似,Oracle也支持range,list,hash分区;同时支持3种分区类型的组合分区,其中组合有多种。
1、范围分区
SQL> CREATE TABLE test_range_part
2 (
3 id INT PRIMARY KEY,
4 name varchar(20),
5 insertime date
6 )
7 PARTITION BY RANGE(insertime)
8 (
9 PARTITION p1 VALUES LESS THAN ('2019-1-1'),
10 PARTITION p2 VALUES LESS THAN ('2020-1-1'),
11 PARTITION p3 VALUES LESS THAN ('2021-1-1'),
12 PARTITION p4 VALUES LESS THAN ('2022-1-1'),
13 PARTITION pmax VALUES LESS THAN (MAXVALUE))
14 STORAGE (NOBRANCH,FILLFACTOR 85);
executed successfully
used time: 27.070(ms). Execute id is 50.
SQL> insert into test_range_part values(10,'aaaa','2018-08-08');
affect rows 1
used time: 1.847(ms). Execute id is 51.
SQL> insert into test_range_part values(11,'bbbb','2019-08-08');
affect rows 1
used time: 1.339(ms). Execute id is 52.
SQL> insert into test_range_part values(12,'bbbb','2020-08-08');
affect rows 1
used time: 1.186(ms). Execute id is 53.
SQL> insert into test_range_part values(13,'bbbb','2021-08-08');
affect rows 1
used time: 0.753(ms). Execute id is 54.
SQL> insert into test_range_part values(14,'bbbb','2022-08-08');
affect rows 1
used time: 0.867(ms). Execute id is 55.
SQL> insert into test_range_part values(15,'bbbb','2019-08-08');
affect rows 1
used time: 0.697(ms). Execute id is 56.
SQL> insert into test_range_part values(99,'bbbb','9999-12-31');
affect rows 1
used time: 1.912(ms). Execute id is 58.
SQL> commit;
executed successfully
used time: 2.802(ms). Execute id is 57.
SQL> DBMS_STATS.GATHER_TABLE_STATS('SYSDBA','TEST_RANGE_PART',null,100,TRUE,'FOR ALL COLUMNS SIZE AUTO');
DMSQL executed successfully
used time: 155.799(ms). Execute id is 61.
SQL> select TABLE_OWNER,TABLE_NAME,PARTITION_NAME,HIGH_VALUE,PCT_FREE,PCT_USED,INI_TRANS,NUM_ROWS,BLOCKS,EMPTY_BLOCKS
2 from dba_Tab_partitions where table_name='TEST_RANGE_PART';
TABLE_OWNER TABLE_NAME PARTITION_NAME HIGH_VALUE PCT_FREE PCT_USED INI_TRANS NUM_ROWS BLOCKS EMPTY_BLOCKS
----------- --------------- -------------- ---------------- -------- -------- --------- -------- ------ ------------
SYSDBA TEST_RANGE_PART PMAX MAXVALUE NULL NULL NULL NULL NULL NULL
SYSDBA TEST_RANGE_PART P1 DATE'2019-01-01' NULL NULL NULL NULL NULL NULL
SYSDBA TEST_RANGE_PART P2 DATE'2020-01-01' NULL NULL NULL NULL NULL NULL
SYSDBA TEST_RANGE_PART P3 DATE'2021-01-01' NULL NULL NULL NULL NULL NULL
SYSDBA TEST_RANGE_PART P4 DATE'2022-01-01' NULL NULL NULL NULL NULL NULL
used time: 134.162(ms). Execute id is 62.
SQL> select * from TEST_RANGE_PART partition(P1);
ID NAME INSERTIME
----------- ---- ----------------------------------------------------------------------------------------------------
10 aaaa 2018-08-08
used time: 0.945(ms). Execute id is 63.
从操作上来看,跟Oracle别无两样;不过这里看上去兼容Oracle的dbms_stats 包,用来收集统计信息,似乎并没有起到应用的作用。
我们接续看下针对分区的访问的执行计划是如何的。
SQL> explain select * from TEST_RANGE_PART partition(P1);
1 #NSET2: [0, 1, 72]
2 #PRJT2: [0, 1, 72]; exp_num(4), is_atom(FALSE)
3 #CSCN2: [0, 1, 72]; INDEX33555514_33555512(TEST_RANGE_PART_P1 as TEST_RANGE_PART)
used time: 0.974(ms). Execute id is 0.
SQL> explain select * from TEST_RANGE_PART where id=14;
1 #NSET2: [0, 1, 72]
2 #PRJT2: [0, 1, 72]; exp_num(4), is_atom(FALSE)
3 #PARALLEL: [0, 1, 72]; scan_type(FULL), key_num(0, 0, 0), simple(0)
4 #BLKUP2: [0, 1, 72]; INDEX33555513(TEST_RANGE_PART)
5 #SSEK2: [0, 1, 72]; scan_type(ASC), INDEX33555513(TEST_RANGE_PART), scan_range[14,14]
used time: 1.257(ms). Execute id is 0.
SQL> explain select * from TEST_RANGE_PART where insertime < '2019-01-01';
1 #NSET2: [0, 1, 72]
2 #PRJT2: [0, 1, 72]; exp_num(4), is_atom(FALSE)
3 #PARALLEL: [0, 1, 72]; scan_type(L), key_num(0, 0, 1), simple(0)
4 #SLCT2: [0, 1, 72]; [TEST_RANGE_PART.INSERTIME < var1]
5 #CSCN2: [0, 6, 72]; INDEX33555512(TEST_RANGE_PART)
used time: 1.225(ms). Execute id is 0.
SQL>
SQL> select owner,index_name,UNIQUENESS,tablespace_name,BLEVEL,LEAF_BLOCKS,NUM_ROWS,STATUS,PARTITIONED
2 from dba_indexes where table_name='TEST_RANGE_PART';
OWNER INDEX_NAME UNIQUENESS TABLESPACE_NAME BLEVEL LEAF_BLOCKS NUM_ROWS STATUS PARTITIONED
------ ------------- ---------- --------------- ------ ----------- -------- ------ -----------
SYSDBA INDEX33555512 NONUNIQUE MAIN NULL NULL NULL VALID YES
SYSDBA INDEX33555513 UNIQUE MAIN NULL NULL 7 VALID YES
used time: 57.256(ms). Execute id is 66.
SQL> select INDEX_OWNER,INDEX_NAME,TABLE_NAME,COLUMN_NAME,COLUMN_POSITION from dba_ind_columns where TABLE_NAME='TEST_RANGE_PART';
INDEX_OWNER INDEX_NAME TABLE_NAME COLUMN_NAME COLUMN_POSITION
----------- ------------- --------------- ----------- ---------------
SYSDBA INDEX33555513 TEST_RANGE_PART ID 1
used time: 12.846(ms). Execute id is 68.
测试到这里让我有点疑惑了。 ID列我定义了主键,创建索引是理所当然的;对于分区键insertime也自动创建了非唯一性索引;而且也是分区索引。
当时该索引在dba_ind_columns 中却有查询不到。这是为什么 ?
对于list分区和hash分区,这里不进行测试了。再测一下组合分区。
list-range:
SQL> CREATE TABLE test_list_range(
2 id INT,
3 name varchar2(20),
4 insertime DATETIME,
5 owner varchar2(10)
6 )
7 PARTITION BY LIST(owner)
8 SUBPARTITION BY RANGE(insertime) SUBPARTITION TEMPLATE(
9 SUBPARTITION P11 VALUES LESS THAN ('2019-04-01'),
10 SUBPARTITION P12 VALUES LESS THAN ('2020-07-01'),
11 SUBPARTITION P13 VALUES LESS THAN ('2021-10-01'),
12 SUBPARTITION P14 VALUES EQU OR LESS THAN (MAXVALUE))
13 (
14 PARTITION P1 VALUES ('roger', 'rogerli')
15 (
16 SUBPARTITION P11_1 VALUES LESS THAN ('2020-10-01'),
17 SUBPARTITION P11_2 VALUES EQU OR LESS THAN (MAXVALUE)
18 ),
19 PARTITION P2 VALUES ('lxy', 'lbs', 'tingkun'),
20 PARTITION P3 VALUES (DEFAULT)
21 );
executed successfully
used time: 30.912(ms). Execute id is 70.
SQL>
list-list:
SQL> CREATE TABLE test_list_list(
2 id INT,
3 name varchar2(20),
4 insertime DATETIME,
5 owner varchar2(10)
6 )
7 PARTITION BY LIST(id)
8 SUBPARTITION BY LIST(owner) SUBPARTITION TEMPLATE
9 (
10 SUBPARTITION Q1 VALUES('roger'),
11 SUBPARTITION Q2 VALUES('rogerli')
12 )
13 (
14 PARTITION P1 VALUES (7),
15 PARTITION P2 VALUES (8),
16 PARTITION P3 VALUES (9));
warning: List partition not include default,partition may be not located
executed successfully
used time: 26.923(ms). Execute id is 71.
SQL>
list-hash:
SQL> CREATE TABLE test_list_hash(
2 id INT,
3 name varchar2(20),
4 insertime DATETIME,
5 owner varchar2(10)
6 )
7 PARTITION BY LIST(owner)
8 SUBPARTITION BY HASH (id)
9 SUBPARTITION TEMPLATE (SUBPARTITION sp1 , SUBPARTITION sp2,SUBPARTITION sp3 )
10 (
11 PARTITION P1 VALUES ('roger', 'rogerli'),
12 PARTITION P2 VALUES ('lxy', 'lbs', 'tingkun'),
13 PARTITION P3 VALUES (DEFAULT)
14 );
executed successfully
used time: 22.568(ms). Execute id is 74.
4) range-list
SQL> CREATE TABLE test_range_list(
2 id INT,
3 name varchar2(20),
4 insertime DATETIME,
5 owner varchar2(10)
6 )
7 PARTITION BY range(insertime)
8 SUBPARTITION BY LIST(owner) SUBPARTITION TEMPLATE
9 (SUBPARTITION L1 VALUES('roger'),
10 SUBPARTITION L2 VALUES('rogerli'))
11 (
12 PARTITION p1 VALUES LESS THAN ('2019-1-1'),
13 PARTITION p2 VALUES LESS THAN ('2020-1-1'),
14 PARTITION p3 VALUES LESS THAN ('2021-1-1'),
15 PARTITION p4 VALUES LESS THAN ('2022-1-1'),
16 PARTITION pmax VALUES LESS THAN (MAXVALUE)
17 );
warning: List partition not include default,partition may be not located
executed successfully
used time: 20.612(ms). Execute id is 72.
5) range-range
SQL> CREATE TABLE test_range_range(
2 id INT,
3 name varchar2(20),
4 insertime DATETIME,
5 owner varchar2(10)
6 )
7 PARTITION BY range(insertime)
8 SUBPARTITION BY range(id) SUBPARTITION TEMPLATE
9 (SUBPARTITION L1 VALUES LESS THAN(10),
10 SUBPARTITION L2 VALUES LESS than(20))
11 (
12 PARTITION p1 VALUES LESS THAN ('2019-1-1'),
13 PARTITION p2 VALUES LESS THAN ('2020-1-1'),
14 PARTITION p3 VALUES LESS THAN ('2021-1-1'),
15 PARTITION p4 VALUES LESS THAN ('2022-1-1'),
16 PARTITION pmax VALUES LESS THAN (MAXVALUE)
17 );
warning: Range partition not include maxvalue,partition may be not located
executed successfully
used time: 31.730(ms). Execute id is 73.
SQL>
6) range-hash
SQL> CREATE TABLE test_range_hash
2 (
3 id INT PRIMARY KEY,
4 name varchar(20),
5 insertime date,
6 seq int
7 )
8 PARTITION BY RANGE (insertime)
9 SUBPARTITION BY HASH (seq)
10 SUBPARTITION TEMPLATE (SUBPARTITION p1 , SUBPARTITION p2 )
11 (
12 PARTITION p1 VALUES LESS THAN ('2019-1-1'),
13 PARTITION p2 VALUES LESS THAN ('2020-1-1'),
14 PARTITION p3 VALUES LESS THAN ('2021-1-1'),
15 PARTITION p4 VALUES LESS THAN ('2022-1-1'),
16 PARTITION pmax VALUES LESS THAN (MAXVALUE))
17 STORAGE (NOBRANCH,FILLFACTOR 85);
executed successfully
used time: 38.596(ms). Execute id is 69.
hash的3种组合分区这里不再测试了;另外达梦不仅仅支持2级组合分区;还支持最多8层的多级分区,这一点比较赞。
不过分区真要做到4 5层,那管理估计也是一件头大的事儿。看文档说dm还支持间隔分区,类似Oracle 11g 的interval 分区,这个蛮有意思,测试一下看看。
SQL> CREATE table test_interval
2 (
3 id INT,
4 name varchar2(20),
5 insertime DATETIME,
6 owner varchar2(10)
7 )
8 PARTITION BY RANGE(insertime)
9 INTERVAL(NUMTOYMINTERVAL(1, 'year'))
10 (PARTITION P_BEFORE_2020
11 VALUES LESS THAN (TO_DATE ('2020-01-01', 'yyyy-mm-dd')))
12 STORAGE (FILLFACTOR 85, BRANCH(32,32));
executed successfully
used time: 16.724(ms). Execute id is 75.
SQL> insert into test_interval values(1,'roger','2019-09-09','enmotech');
affect rows 1
used time: 1.910(ms). Execute id is 76.
SQL> insert into test_interval values(1,'roger','2021-09-09','enmotech');
affect rows 1
used time: 23.831(ms). Execute id is 77.
SQL> insert into test_interval values(1,'roger','2020-09-09','enmotech');
affect rows 1
used time: 18.193(ms). Execute id is 78.
SQL> commit;
executed successfully
used time: 5.049(ms). Execute id is 79.
SQL> SELECT table_name,partition_name, high_value FROM dba_tab_partitions where table_name like '%INTERVAl%' order by 3;
no rows
used time: 15.588(ms). Execute id is 107.
SQL> SELECT table_name,partition_name, high_value,INTERVAL FROM dba_tab_partitions where table_name like '%INTERVAl%' order by 3;
SELECT table_name,partition_name, high_value,INTERVAL FROM dba_tab_partitions where table_name like '%INTERVAl%' order by 3;
SELECT table_name,partition_name, high_value,INTERVAL FROM dba_tab_partitions where table_name like '%INTERVAl%' order by 3;
*
line 1, column 106, nearby [FROM] has error[-2007]:
Syntax error.
used time: 0.327(ms). Execute id is 0.
居然查不到? 而且同样的SQL,不久多了查询一个interval列吗?居然报错。 这里来看应该是Bug 无疑了。。。。
最后简单总结一下:
1、默认情况下表为普通表;需要修改list_table参数为1,创建后的table则默认为堆表;或者在创建表时指定相关stroage选项。
2、dm有类似Oracle pctfree/pctused的参数即FILLFACTOR,该参数取值范围为【0,100】,只能是整数,参数越小,数据页可用空间就越少;
3、支持常规所有的分区表如range,list,hash;同时支持3种随意组合的9种组合分区;
4、支持interval 间隔分区;从文档来看,粒度可以非常细,支持月,天等。
5、无论是普通表还是堆表都存在rowid,至于rowid的格式化,这里没有研究,没有太多资料。看上去像是一个递增序列。
附录:另外看文档关于分区表也一些限制,如下内容拷贝至官方手册:
DM水平分区表有如下限制条件:
分区列类型必须是数值型、字符型或日期型,不支持BLOB、CLOB、IMAGE、TEXT、LONGVARCHAR、BIT、BINARY、VARBINARY、LONGVARBINARY、时间间隔类型和用户自定义类型为分区列;
范围分区和哈希分区的分区键可以多个,最多不超过16列;LIST分区的分区键必须唯一;
水平分区表指定主键和唯一约束时,分区键必须都包含在主键和唯一约束中;
水平分区表不支持临时表;
不能在水平分区表上建立自引用约束;
普通环境中,水平分区表的各级分区数的总和上限是65535;MPP环境下,水平分区表的各级分区总数上限取决于INI参数MAX_EP_SITES,上限为2^( 16 – log2MAX_EP_SITES)。比如:当MAX_EP_SITES为默认值64时,分区总数上限为1024;
不允许对分区子表执行任何DDL操作;
哈希分区支持重命名、删除约束、设置触发器是否启用的修改操作;
范围分区支持分区合并、拆分、增加、删除、交换、重命名、删除约束、设置触发器是否生效操作;
LIST分区支持分区合并、拆分、增加、删除、交换、重命名、删除约束、设置触发器是否生效操作;
LIST分区范围值不能为NULL;
LIST分区子表范围值个数与数据页大小和相关系统表列长度相关,存在以下限制:
4K页,单个子表最多支持120个范围值;
8K页,单个子表最多支持254个范围值;
16K\32K页,单个子表最多支持270个范围值;
对范围分区增加分区值必须是递增的,即只能在最后一个分区后添加分区。LIST分区增加分区值不能存在于其他已存在分区;
当分区数仅剩一个时,不允许删除分区;
仅能对相邻的范围分区进行合并,合并后的分区名可为高分区名或新分区名;
拆分分区的分区值必须在原分区范围中,并且分区名不能跟已有分区名相同;
与分区进行分区交换的普通表,必须与分区表拥有相同的列及索引,但交换分区并不会对数据进行校验,即交换后的数据并不能保证数据完整性,如CHECK约束;分区表与普通表创建的索引顺序要求一致;
不能对水平分区表建立全局聚集索引、局部唯一函数索引或全文索引;
不能对分区子表单独建立索引;
在未指定ENABLE ROW MOVEMENT的分区表上执行更新分区键,不允许更新后数据发生跨分区的移动,即不能有行迁移;
不能在分区语句的STORAGE子句中指定BRANCH选项;
不允许引用水平分区子表作为外键约束;
多级分区表最多支持八层;
多级分区表支持下列修改表操作:新增分区、新增列、删除列、删除表级约束、修改表名、设置与删除列的默认值、设置列NULL属性、设置列可见性、设置行迁移属性、启用超长记录、with delta、新增子分区、删除子分区、修改二级分区模板信息;
水平分区表支持的列修改操作除了多级分区表支持的操作外,还支持:设置触发器生效/失效、修改除分区列以外的列名、修改列属性、增加表级主键约束、删除分区、SPLIT/MERGE分区和交换分区;
水平分区表中包含大字段、自定义字段列,则定义时指定 ENABLE ROW MOVEMENT参数无效,即不允许更新后数据发生跨分区的移动;
间隔分区表的限制说明:
仅支持一级范围分区创建间隔分区;
只能有一个分区列,且分区列类型为日期或数值;
对间隔分区进行SPLIT,只能在间隔范围内进行操作;
被SPLIT/MERGE的分区,其左侧分区不再进行自动创建;
不相邻的间隔的分区,不能MERGE;
表定义不能包含MAXVALUE分区;
不允许新增分区;
不能删除起始间隔分区;
间隔分区表定义语句显示到起始间隔分区为止;
自动生成的间隔分区,均不包含边界值;
间隔表达式只能为常量或日期间隔函数。日期间隔函数为:NUMTOYMINTERVAL、 NUMTODSINTERVAL;数值常量可以为整型、DEC类型;
MPP下不支持间隔分区表。