CREATE TABLE SUBPARTITION

功能描述

创建二级分区表。分区表是把逻辑上的一张表根据某种方案分成几张物理块进行存储,这张逻辑上的表称之为分区表,物理块称之为分区。分区表是一张逻辑表,不存储数据,数据实际是存储在分区上的。对于二级分区表,顶层节点表和一级分区都是逻辑表,不存储数据,只有二级分区(叶子节点)存储数据。

二级分区表的分区方案是由两个一级分区的分区方案组合而来的,一级分区的分区方案详见章节CREATE TABLE PARTITION。

常见的二级分区表组合方案有Range-Range分区、Range-List分区、Range-Hash分区、List-Range分区、List-List分区、List-Hash分区、Hash-Range分区、Hash-List分区、Hash-Hash分区等。目前二级分区仅支持行存表。

注意事项

  • 二级分区表有两个分区键,每个分区键只能支持1列。
  • 唯一约束和主键约束的约束键包含所有分区键将为约束创建LOCAL索引,否则创建GLOBAL索引。
  • 二级分区表的二级分区(叶子节点)个数不能超过1048575个,一级分区无限制,但一级分区下面至少有一个二级分区。
  • 二级分区表只支持行存,不支持列存、段页式、hashbucket。
  • 不支持Upsert、Merge into。
  • 指定分区查询时,如select * from tablename partition/subpartition (partitionname),关键字partition和subpartition注意不要写错。如果写错,查询不会报错,这时查询会变为对表起别名进行查询。
  • 不支持对二级分区 subpartition for (values)查询。如select * from tablename subpartition for (values)。
  • 不支持密态数据库、账本数据库和行级访问控制。

语法格式

  1. CREATE TABLE [ IF NOT EXISTS ] subpartition_table_name
  2. (
  3. { column_name data_type [ COLLATE collation ] [ column_constraint [ ... ] ]
  4. | table_constraint
  5. | LIKE source_table [ like_option [...] ] }[, ... ]
  6. )
  7. [ WITH ( {storage_parameter = value} [, ... ] ) ]
  8. [ COMPRESS | NOCOMPRESS ]
  9. [ TABLESPACE tablespace_name ]
  10. PARTITION BY {RANGE | LIST | HASH} (partition_key) SUBPARTITION BY {RANGE | LIST | HASH} (subpartition_key)
  11. (
  12. PARTITION partition_name1 [ VALUES LESS THAN (val1) | VALUES (val1[, …]) ] [ TABLESPACE tablespace ]
  13. (
  14. { SUBPARTITION subpartition_name1 [ VALUES LESS THAN (val1_1) | VALUES (val1_1[, …])] [ TABLESPACE tablespace ] } [, ...]
  15. )[, ...]
  16. )[ { ENABLE | DISABLE } ROW MOVEMENT ];
  • 列约束column_constraint:

    1. [ CONSTRAINT constraint_name ]
    2. { NOT NULL |
    3. NULL |
    4. CHECK ( expression ) |
    5. DEFAULT default_e xpr |
    6. GENERATED ALWAYS AS ( generation_expr ) STORED |
    7. UNIQUE index_parameters |
    8. PRIMARY KEY index_parameters |
    9. REFERENCES reftable [ ( refcolumn ) ] [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ]
    10. [ ON DELETE action ] [ ON UPDATE action ] }
    11. [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
  • 表约束table_constraint:

    1. [ CONSTRAINT constraint_name ]
    2. { CHECK ( expression ) |
    3. UNIQUE ( column_name [, ... ] ) index_parameters |
    4. PRIMARY KEY ( column_name [, ... ] ) index_parameters |
    5. FOREIGN KEY ( column_name [, ... ] ) REFERENCES reftable [ ( refcolumn [, ... ] ) ]
    6. [ MATCH FULL | MATCH PARTIAL | MATCH SIMPLE ] [ ON DELETE action ] [ ON UPDATE action ] }
    7. [ DEFERRABLE | NOT DEFERRABLE | INITIALLY DEFERRED | INITIALLY IMMEDIATE ]
  • like选项like_option:

    1. { INCLUDING | EXCLUDING } { DEFAULTS | GENERATED | CONSTRAINTS | INDEXES | STORAGE | COMMENTS | RELOPTIONS| ALL }
  • 索引存储参数index_parameters:

    1. [ WITH ( {storage_parameter = value} [, ... ] ) ]
    2. [ USING INDEX TABLESPACE tablespace_name ]

参数说明

  • IF NOT EXISTS

    如果已经存在相同名称的表,不会抛出一个错误,而会发出一个通知,告知表关系已存在。

  • subpartition_table_name

    二级分区表的名称。

    取值范围:字符串,要符合标识符的命名规范。

  • column_name

    新表中要创建的字段名。

    取值范围:字符串,要符合标识符的命名规范。

  • data_type

    字段的数据类型。

  • COLLATE collation

    COLLATE子句指定列的排序规则(该列必须是可排列的数据类型)。如果没有指定,则使用默认的排序规则。排序规则可以使用“select * from pg_collation;”命令从pg_collation系统表中查询,默认的排序规则为查询结果中以default开始的行。

  • CONSTRAINT constraint_name

    列约束或表约束的名称。可选的约束子句用于声明约束,新行或者更新的行必须满足这些约束才能成功插入或更新。

    定义约束有两种方法:

    • 列约束:作为一个列定义的一部分,仅影响该列。
    • 表约束:不和某个列绑在一起,可以作用于多个列。
  • LIKE source_table [ like_option … ]

    二级分区表暂不支持该功能。

  • WITH ( storage_parameter [= value] [, … ] )

    这个子句为表或索引指定一个可选的存储参数。参数的详细描述如下所示:

    • FILLFACTOR

      一个表的填充因子(fillfactor)是一个介于10和100之间的百分数。100(完全填充)是默认值。如果指定了较小的填充因子,INSERT操作仅按照填充因子指定的百分率填充表页。每个页上的剩余空间将用于在该页上更新行,这就使得UPDATE有机会在同一页上放置同一条记录的新版本,这比把新版本放置在其他页上更有效。对于一个从不更新的表将填充因子设为100是最佳选择,但是对于频繁更新的表,选择较小的填充因子则更加合适。该参数对于列存表没有意义。

      取值范围:10~100

    • ORIENTATION

      决定了表的数据的存储方式。

      取值范围:

      • COLUMN:表的数据将以列式存储。
      • ROW(缺省值):表的数据将以行式存储。

        CREATE TABLE SUBPARTITION - 图1 须知: orientation不支持修改。

    • COMPRESSION

      • 列存表的有效值为LOW/MIDDLE/HIGH/YES/NO,压缩级别依次升高,默认值为LOW。
      • 行存表不支持压缩。
    • MAX_BATCHROW

      指定了在数据加载过程中一个存储单元可以容纳记录的最大数目。该参数只对列存表有效。

      取值范围:10000~60000,默认60000。

    • PARTIAL_CLUSTER_ROWS

      指定了在数据加载过程中进行将局部聚簇存储的记录数目。该参数只对列存表有效。

      取值范围:大于等于MAX_BATCHROW,建议取值为MAX_BATCHROW的整数倍数。

    • DELTAROW_THRESHOLD

      预留参数。该参数只对列存表有效。

      取值范围:0~9999

  • COMPRESS / NOCOMPRESS

    创建一个新表时,需要在创建表语句中指定关键字COMPRESS,这样,当对该表进行批量插入时就会触发压缩特性。该特性会在页范围内扫描所有元组数据,生成字典、压缩元组数据并进行存储。指定关键字NOCOMPRESS则不对表进行压缩。行存表不支持压缩。

    缺省值为NOCOMPRESS,即不对元组数据进行压缩。

  • TABLESPACE tablespace_name

    指定新表将要在tablespace_name表空间内创建。如果没有声明,将使用默认表空间。

  • PARTITION BY {RANGE | LIST | HASH} (partition_key)

    • 对于partition_key,分区策略的分区键仅支持1列。
    • 分区键支持的数据类型和一级分区表约束保持一致。
  • SUBPARTITION BY {RANGE | LIST | HASH} (subpartition_key)

    • 对于subpartition_key,分区策略的分区键仅支持1列。
    • 分区键支持的数据类型和一级分区表约束保持一致。
  • { ENABLE | DISABLE } ROW MOVEMENT

    行迁移开关。

    如果进行UPDATE操作时,更新了元组在分区键上的值,造成了该元组所在分区发生变化,就会根据该开关给出报错信息,或者进行元组在分区间的转移。

    取值范围:

    • ENABLE(缺省值):行迁移开关打开。
    • DISABLE:行迁移开关关闭。
  • NOT NULL

    字段值不允许为NULL。ENABLE用于语法兼容,可省略。

  • NULL

    字段值允许NULL ,这是缺省。

    这个子句只是为和非标准SQL数据库兼容。不建议使用。

  • CHECK (condition) [ NO INHERIT ]

    CHECK约束声明一个布尔表达式,每次要插入的新行或者要更新的行的新值必须使表达式结果为真或未知才能成功,否则会抛出一个异常并且不会修改数据库。

    声明为字段约束的检查约束应该只引用该字段的数值,而在表约束里出现的表达式可以引用多个字段。

    用NO INHERIT标记的约束将不会传递到子表中去。

    ENABLE用于语法兼容,可省略。

  • DEFAULT default_expr

    DEFAULT子句给字段指定缺省值。该数值可以是任何不含变量的表达式(不允许使用子查询和对本表中的其他字段的交叉引用)。缺省表达式的数据类型必须和字段类型匹配。

    缺省表达式将被用于任何未声明该字段数值的插入操作。如果没有指定缺省值则缺省值为NULL 。

  • GENERATED ALWAYS AS ( generation_expr ) STORED

    该子句将字段创建为生成列,生成列的值在写入(插入或更新)数据时由generation_expr计算得到,STORED表示像普通列一样存储生成列的值。

    CREATE TABLE SUBPARTITION - 图2 说明:

    • 生成表达式不能以任何方式引用当前行以外的其他数据。生成表达式不能引用其他生成列,不能引用系统列。生成表达式不能返回结果集,不能使用子查询,不能使用聚集函数,不能使用窗口函数。生成表达式调用的函数只能是不可变(IMMUTABLE)函数。

    • 不能为生成列指定默认值。

    • 生成列不能作为分区键的一部分。

    • 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。

    • 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。

    • 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。

    • 生成列的权限控制和普通列一样。

    • 不能为生成列指定默认值。

    • 生成列不能作为分区键的一部分。

    • 生成列不能和ON UPDATE约束字句的CASCADE,SET NULL,SET DEFAULT动作同时指定。生成列不能和ON DELETE约束字句的SET NULL,SET DEFAULT动作同时指定。

    • 修改和删除生成列的方法和普通列相同。删除生成列依赖的普通列,生成列被自动删除。不能改变生成列所依赖的列的类型。

    • 生成列不能被直接写入。在INSERT或UPDATE命令中, 不能为生成列指定值, 但是可以指定关键字DEFAULT。

    • 生成列的权限控制和普通列一样。

    • 列存表、内存表MOT不支持生成列。外表中仅postgres_fdw支持生成列。

  • UNIQUE index_parameters

    UNIQUE ( column_name [, … ] ) index_parameters

    UNIQUE约束表示表里的一个字段或多个字段的组合必须在全表范围内唯一。

    对于唯一约束,NULL被认为是互不相等的。

  • PRIMARY KEY index_parameters

    PRIMARY KEY ( column_name [, … ] ) index_parameters

    主键约束声明表中的一个或者多个字段只能包含唯一的非NULL值。

    一个表只能声明一个主键。

  • DEFERRABLE | NOT DEFERRABLE

    这两个关键字设置该约束是否可推迟。一个不可推迟的约束将在每条命令之后马上检查。可推迟约束可以推迟到事务结尾使用SET CONSTRAINTS命令检查。缺省是NOT DEFERRABLE。目前,UNIQUE约束、主键约束、外键约束可以接受这个子句。所有其他约束类型都是不可推迟的。

  • INITIALLY IMMEDIATE | INITIALLY DEFERRED

    如果约束是可推迟的,则这个子句声明检查约束的缺省时间。

    • 如果约束是INITIALLY IMMEDIATE(缺省),则在每条语句执行之后就立即检查它;
    • 如果约束是INITIALLY DEFERRED ,则只有在事务结尾才检查它。

    约束检查的时间可以用SET CONSTRAINTS命令修改。

  • USING INDEX TABLESPACE tablespace_name

    为UNIQUE或PRIMARY KEY约束相关的索引声明一个表空间。如果没有提供这个子句,这个索引将在default_tablespace中创建,如果default_tablespace为空,将使用数据库的缺省表空间。

示例

  • 示例1:创建各种组合类型的二级分区表

    1. CREATE TABLE list_list
    2. (
    3. month_code VARCHAR2 ( 30 ) NOT NULL ,
    4. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    5. user_no VARCHAR2 ( 30 ) NOT NULL ,
    6. sales_amt int
    7. )
    8. PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code)
    9. (
    10. PARTITION p_201901 VALUES ( '201902' )
    11. (
    12. SUBPARTITION p_201901_a VALUES ( '1' ),
    13. SUBPARTITION p_201901_b VALUES ( '2' )
    14. ),
    15. PARTITION p_201902 VALUES ( '201903' )
    16. (
    17. SUBPARTITION p_201902_a VALUES ( '1' ),
    18. SUBPARTITION p_201902_b VALUES ( '2' )
    19. )
    20. );
    21. insert into list_list values('201902', '1', '1', 1);
    22. insert into list_list values('201902', '2', '1', 1);
    23. insert into list_list values('201902', '1', '1', 1);
    24. insert into list_list values('201903', '2', '1', 1);
    25. insert into list_list values('201903', '1', '1', 1);
    26. insert into list_list values('201903', '2', '1', 1);
    27. select * from list_list;
    28. month_code | dept_code | user_no | sales_amt
    29. ------------+-----------+---------+-----------
    30. 201903 | 2 | 1 | 1
    31. 201903 | 2 | 1 | 1
    32. 201903 | 1 | 1 | 1
    33. 201902 | 2 | 1 | 1
    34. 201902 | 1 | 1 | 1
    35. 201902 | 1 | 1 | 1
    36. (6 rows)
    37. drop table list_list;
    38. CREATE TABLE list_hash
    39. (
    40. month_code VARCHAR2 ( 30 ) NOT NULL ,
    41. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    42. user_no VARCHAR2 ( 30 ) NOT NULL ,
    43. sales_amt int
    44. )
    45. PARTITION BY LIST (month_code) SUBPARTITION BY HASH (dept_code)
    46. (
    47. PARTITION p_201901 VALUES ( '201902' )
    48. (
    49. SUBPARTITION p_201901_a,
    50. SUBPARTITION p_201901_b
    51. ),
    52. PARTITION p_201902 VALUES ( '201903' )
    53. (
    54. SUBPARTITION p_201902_a,
    55. SUBPARTITION p_201902_b
    56. )
    57. );
    58. insert into list_hash values('201902', '1', '1', 1);
    59. insert into list_hash values('201902', '2', '1', 1);
    60. insert into list_hash values('201902', '3', '1', 1);
    61. insert into list_hash values('201903', '4', '1', 1);
    62. insert into list_hash values('201903', '5', '1', 1);
    63. insert into list_hash values('201903', '6', '1', 1);
    64. select * from list_hash;
    65. month_code | dept_code | user_no | sales_amt
    66. ------------+-----------+---------+-----------
    67. 201903 | 4 | 1 | 1
    68. 201903 | 5 | 1 | 1
    69. 201903 | 6 | 1 | 1
    70. 201902 | 2 | 1 | 1
    71. 201902 | 3 | 1 | 1
    72. 201902 | 1 | 1 | 1
    73. (6 rows)
    74. drop table list_hash;
    75. CREATE TABLE list_range
    76. (
    77. month_code VARCHAR2 ( 30 ) NOT NULL ,
    78. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    79. user_no VARCHAR2 ( 30 ) NOT NULL ,
    80. sales_amt int
    81. )
    82. PARTITION BY LIST (month_code) SUBPARTITION BY RANGE (dept_code)
    83. (
    84. PARTITION p_201901 VALUES ( '201902' )
    85. (
    86. SUBPARTITION p_201901_a values less than ('4'),
    87. SUBPARTITION p_201901_b values less than ('6')
    88. ),
    89. PARTITION p_201902 VALUES ( '201903' )
    90. (
    91. SUBPARTITION p_201902_a values less than ('3'),
    92. SUBPARTITION p_201902_b values less than ('6')
    93. )
    94. );
    95. insert into list_range values('201902', '1', '1', 1);
    96. insert into list_range values('201902', '2', '1', 1);
    97. insert into list_range values('201902', '3', '1', 1);
    98. insert into list_range values('201903', '4', '1', 1);
    99. insert into list_range values('201903', '5', '1', 1);
    100. insert into list_range values('201903', '6', '1', 1);
    101. ERROR: inserted partition key does not map to any table partition
    102. select * from list_range;
    103. month_code | dept_code | user_no | sales_amt
    104. ------------+-----------+---------+-----------
    105. 201903 | 4 | 1 | 1
    106. 201903 | 5 | 1 | 1
    107. 201902 | 1 | 1 | 1
    108. 201902 | 2 | 1 | 1
    109. 201902 | 3 | 1 | 1
    110. (5 rows)
    111. drop table list_range;
    112. CREATE TABLE range_list
    113. (
    114. month_code VARCHAR2 ( 30 ) NOT NULL ,
    115. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    116. user_no VARCHAR2 ( 30 ) NOT NULL ,
    117. sales_amt int
    118. )
    119. PARTITION BY RANGE (month_code) SUBPARTITION BY LIST (dept_code)
    120. (
    121. PARTITION p_201901 VALUES LESS THAN( '201903' )
    122. (
    123. SUBPARTITION p_201901_a values ('1'),
    124. SUBPARTITION p_201901_b values ('2')
    125. ),
    126. PARTITION p_201902 VALUES LESS THAN( '201904' )
    127. (
    128. SUBPARTITION p_201902_a values ('1'),
    129. SUBPARTITION p_201902_b values ('2')
    130. )
    131. );
    132. insert into range_list values('201902', '1', '1', 1);
    133. insert into range_list values('201902', '2', '1', 1);
    134. insert into range_list values('201902', '1', '1', 1);
    135. insert into range_list values('201903', '2', '1', 1);
    136. insert into range_list values('201903', '1', '1', 1);
    137. insert into range_list values('201903', '2', '1', 1);
    138. select * from range_list;
    139. month_code | dept_code | user_no | sales_amt
    140. ------------+-----------+---------+-----------
    141. 201902 | 2 | 1 | 1
    142. 201902 | 1 | 1 | 1
    143. 201902 | 1 | 1 | 1
    144. 201903 | 2 | 1 | 1
    145. 201903 | 2 | 1 | 1
    146. 201903 | 1 | 1 | 1
    147. (6 rows)
    148. drop table range_list;
    149. CREATE TABLE range_hash
    150. (
    151. month_code VARCHAR2 ( 30 ) NOT NULL ,
    152. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    153. user_no VARCHAR2 ( 30 ) NOT NULL ,
    154. sales_amt int
    155. )
    156. PARTITION BY RANGE (month_code) SUBPARTITION BY HASH (dept_code)
    157. (
    158. PARTITION p_201901 VALUES LESS THAN( '201903' )
    159. (
    160. SUBPARTITION p_201901_a,
    161. SUBPARTITION p_201901_b
    162. ),
    163. PARTITION p_201902 VALUES LESS THAN( '201904' )
    164. (
    165. SUBPARTITION p_201902_a,
    166. SUBPARTITION p_201902_b
    167. )
    168. );
    169. insert into range_hash values('201902', '1', '1', 1);
    170. insert into range_hash values('201902', '2', '1', 1);
    171. insert into range_hash values('201902', '1', '1', 1);
    172. insert into range_hash values('201903', '2', '1', 1);
    173. insert into range_hash values('201903', '1', '1', 1);
    174. insert into range_hash values('201903', '2', '1', 1);
    175. select * from range_hash;
    176. month_code | dept_code | user_no | sales_amt
    177. ------------+-----------+---------+-----------
    178. 201902 | 2 | 1 | 1
    179. 201902 | 1 | 1 | 1
    180. 201902 | 1 | 1 | 1
    181. 201903 | 2 | 1 | 1
    182. 201903 | 2 | 1 | 1
    183. 201903 | 1 | 1 | 1
    184. (6 rows)
    185. drop table range_hash;
    186. CREATE TABLE range_range
    187. (
    188. month_code VARCHAR2 ( 30 ) NOT NULL ,
    189. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    190. user_no VARCHAR2 ( 30 ) NOT NULL ,
    191. sales_amt int
    192. )
    193. PARTITION BY RANGE (month_code) SUBPARTITION BY RANGE (dept_code)
    194. (
    195. PARTITION p_201901 VALUES LESS THAN( '201903' )
    196. (
    197. SUBPARTITION p_201901_a VALUES LESS THAN( '2' ),
    198. SUBPARTITION p_201901_b VALUES LESS THAN( '3' )
    199. ),
    200. PARTITION p_201902 VALUES LESS THAN( '201904' )
    201. (
    202. SUBPARTITION p_201902_a VALUES LESS THAN( '2' ),
    203. SUBPARTITION p_201902_b VALUES LESS THAN( '3' )
    204. )
    205. );
    206. insert into range_range values('201902', '1', '1', 1);
    207. insert into range_range values('201902', '2', '1', 1);
    208. insert into range_range values('201902', '1', '1', 1);
    209. insert into range_range values('201903', '2', '1', 1);
    210. insert into range_range values('201903', '1', '1', 1);
    211. insert into range_range values('201903', '2', '1', 1);
    212. select * from range_range;
    213. month_code | dept_code | user_no | sales_amt
    214. ------------+-----------+---------+-----------
    215. 201902 | 1 | 1 | 1
    216. 201902 | 1 | 1 | 1
    217. 201902 | 2 | 1 | 1
    218. 201903 | 1 | 1 | 1
    219. 201903 | 2 | 1 | 1
    220. 201903 | 2 | 1 | 1
    221. (6 rows)
    222. drop table range_range;
    223. CREATE TABLE hash_list
    224. (
    225. month_code VARCHAR2 ( 30 ) NOT NULL ,
    226. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    227. user_no VARCHAR2 ( 30 ) NOT NULL ,
    228. sales_amt int
    229. )
    230. PARTITION BY hash (month_code) SUBPARTITION BY LIST (dept_code)
    231. (
    232. PARTITION p_201901
    233. (
    234. SUBPARTITION p_201901_a VALUES ( '1' ),
    235. SUBPARTITION p_201901_b VALUES ( '2' )
    236. ),
    237. PARTITION p_201902
    238. (
    239. SUBPARTITION p_201902_a VALUES ( '1' ),
    240. SUBPARTITION p_201902_b VALUES ( '2' )
    241. )
    242. );
    243. insert into hash_list values('201901', '1', '1', 1);
    244. insert into hash_list values('201901', '2', '1', 1);
    245. insert into hash_list values('201901', '1', '1', 1);
    246. insert into hash_list values('201903', '2', '1', 1);
    247. insert into hash_list values('201903', '1', '1', 1);
    248. insert into hash_list values('201903', '2', '1', 1);
    249. select * from hash_list;
    250. month_code | dept_code | user_no | sales_amt
    251. ------------+-----------+---------+-----------
    252. 201903 | 2 | 1 | 1
    253. 201903 | 2 | 1 | 1
    254. 201903 | 1 | 1 | 1
    255. 201901 | 2 | 1 | 1
    256. 201901 | 1 | 1 | 1
    257. 201901 | 1 | 1 | 1
    258. (6 rows)
    259. drop table hash_list;
    260. CREATE TABLE hash_hash
    261. (
    262. month_code VARCHAR2 ( 30 ) NOT NULL ,
    263. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    264. user_no VARCHAR2 ( 30 ) NOT NULL ,
    265. sales_amt int
    266. )
    267. PARTITION BY hash (month_code) SUBPARTITION BY hash (dept_code)
    268. (
    269. PARTITION p_201901
    270. (
    271. SUBPARTITION p_201901_a,
    272. SUBPARTITION p_201901_b
    273. ),
    274. PARTITION p_201902
    275. (
    276. SUBPARTITION p_201902_a,
    277. SUBPARTITION p_201902_b
    278. )
    279. );
    280. insert into hash_hash values('201901', '1', '1', 1);
    281. insert into hash_hash values('201901', '2', '1', 1);
    282. insert into hash_hash values('201901', '1', '1', 1);
    283. insert into hash_hash values('201903', '2', '1', 1);
    284. insert into hash_hash values('201903', '1', '1', 1);
    285. insert into hash_hash values('201903', '2', '1', 1);
    286. select * from hash_hash;
    287. month_code | dept_code | user_no | sales_amt
    288. ------------+-----------+---------+-----------
    289. 201903 | 2 | 1 | 1
    290. 201903 | 2 | 1 | 1
    291. 201903 | 1 | 1 | 1
    292. 201901 | 2 | 1 | 1
    293. 201901 | 1 | 1 | 1
    294. 201901 | 1 | 1 | 1
    295. (6 rows)
    296. drop table hash_hash;
    297. CREATE TABLE hash_range
    298. (
    299. month_code VARCHAR2 ( 30 ) NOT NULL ,
    300. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    301. user_no VARCHAR2 ( 30 ) NOT NULL ,
    302. sales_amt int
    303. )
    304. PARTITION BY hash (month_code) SUBPARTITION BY range (dept_code)
    305. (
    306. PARTITION p_201901
    307. (
    308. SUBPARTITION p_201901_a VALUES LESS THAN ( '2' ),
    309. SUBPARTITION p_201901_b VALUES LESS THAN ( '3' )
    310. ),
    311. PARTITION p_201902
    312. (
    313. SUBPARTITION p_201902_a VALUES LESS THAN ( '2' ),
    314. SUBPARTITION p_201902_b VALUES LESS THAN ( '3' )
    315. )
    316. );
    317. insert into hash_range values('201901', '1', '1', 1);
    318. insert into hash_range values('201901', '2', '1', 1);
    319. insert into hash_range values('201901', '1', '1', 1);
    320. insert into hash_range values('201903', '2', '1', 1);
    321. insert into hash_range values('201903', '1', '1', 1);
    322. insert into hash_range values('201903', '2', '1', 1);
    323. select * from hash_range;
    324. month_code | dept_code | user_no | sales_amt
    325. ------------+-----------+---------+-----------
    326. 201903 | 1 | 1 | 1
    327. 201903 | 2 | 1 | 1
    328. 201903 | 2 | 1 | 1
    329. 201901 | 1 | 1 | 1
    330. 201901 | 1 | 1 | 1
    331. 201901 | 2 | 1 | 1
    332. (6 rows)
  • 示例2:对二级分区表进行truncate操作

    1. CREATE TABLE list_list
    2. (
    3. month_code VARCHAR2 ( 30 ) NOT NULL ,
    4. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    5. user_no VARCHAR2 ( 30 ) NOT NULL ,
    6. sales_amt int
    7. )
    8. PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code)
    9. (
    10. PARTITION p_201901 VALUES ( '201902' )
    11. (
    12. SUBPARTITION p_201901_a VALUES ( '1' ),
    13. SUBPARTITION p_201901_b VALUES ( default )
    14. ),
    15. PARTITION p_201902 VALUES ( '201903' )
    16. (
    17. SUBPARTITION p_201902_a VALUES ( '1' ),
    18. SUBPARTITION p_201902_b VALUES ( '2' )
    19. )
    20. );
    21. insert into list_list values('201902', '1', '1', 1);
    22. insert into list_list values('201902', '2', '1', 1);
    23. insert into list_list values('201902', '1', '1', 1);
    24. insert into list_list values('201903', '2', '1', 1);
    25. insert into list_list values('201903', '1', '1', 1);
    26. insert into list_list values('201903', '2', '1', 1);
    27. select * from list_list;
    28. month_code | dept_code | user_no | sales_amt
    29. ------------+-----------+---------+-----------
    30. 201903 | 2 | 1 | 1
    31. 201903 | 2 | 1 | 1
    32. 201903 | 1 | 1 | 1
    33. 201902 | 2 | 1 | 1
    34. 201902 | 1 | 1 | 1
    35. 201902 | 1 | 1 | 1
    36. (6 rows)
    37. select * from list_list partition (p_201901);
    38. month_code | dept_code | user_no | sales_amt
    39. ------------+-----------+---------+-----------
    40. 201902 | 2 | 1 | 1
    41. 201902 | 1 | 1 | 1
    42. 201902 | 1 | 1 | 1
    43. (3 rows)
    44. alter table list_list truncate partition p_201901;
    45. select * from list_list partition (p_201901);
    46. month_code | dept_code | user_no | sales_amt
    47. ------------+-----------+---------+-----------
    48. (0 rows)
    49. select * from list_list partition (p_201902);
    50. month_code | dept_code | user_no | sales_amt
    51. ------------+-----------+---------+-----------
    52. 201903 | 2 | 1 | 1
    53. 201903 | 2 | 1 | 1
    54. 201903 | 1 | 1 | 1
    55. (3 rows)
    56. alter table list_list truncate partition p_201902;
    57. select * from list_list partition (p_201902);
    58. month_code | dept_code | user_no | sales_amt
    59. ------------+-----------+---------+-----------
    60. (0 rows)
    61. select * from list_list;
    62. month_code | dept_code | user_no | sales_amt
    63. ------------+-----------+---------+-----------
    64. (0 rows)
    65. insert into list_list values('201902', '1', '1', 1);
    66. insert into list_list values('201902', '2', '1', 1);
    67. insert into list_list values('201902', '1', '1', 1);
    68. insert into list_list values('201903', '2', '1', 1);
    69. insert into list_list values('201903', '1', '1', 1);
    70. insert into list_list values('201903', '2', '1', 1);
    71. select * from list_list subpartition (p_201901_a);
    72. month_code | dept_code | user_no | sales_amt
    73. ------------+-----------+---------+-----------
    74. 201902 | 1 | 1 | 1
    75. 201902 | 1 | 1 | 1
    76. (2 rows)
    77. alter table list_list truncate subpartition p_201901_a;
    78. select * from list_list subpartition (p_201901_a);
    79. month_code | dept_code | user_no | sales_amt
    80. ------------+-----------+---------+-----------
    81. (0 rows)
    82. select * from list_list subpartition (p_201901_b);
    83. month_code | dept_code | user_no | sales_amt
    84. ------------+-----------+---------+-----------
    85. 201902 | 2 | 1 | 1
    86. (1 row)
    87. alter table list_list truncate subpartition p_201901_b;
    88. select * from list_list subpartition (p_201901_b);
    89. month_code | dept_code | user_no | sales_amt
    90. ------------+-----------+---------+-----------
    91. (0 rows)
    92. select * from list_list subpartition (p_201902_a);
    93. month_code | dept_code | user_no | sales_amt
    94. ------------+-----------+---------+-----------
    95. 201903 | 1 | 1 | 1
    96. (1 row)
    97. alter table list_list truncate subpartition p_201902_a;
    98. select * from list_list subpartition (p_201902_a);
    99. month_code | dept_code | user_no | sales_amt
    100. ------------+-----------+---------+-----------
    101. (0 rows)
    102. select * from list_list subpartition (p_201902_b);
    103. month_code | dept_code | user_no | sales_amt
    104. ------------+-----------+---------+-----------
    105. 201903 | 2 | 1 | 1
    106. 201903 | 2 | 1 | 1
    107. (2 rows)
    108. alter table list_list truncate subpartition p_201902_b;
    109. select * from list_list subpartition (p_201902_b);
    110. month_code | dept_code | user_no | sales_amt
    111. ------------+-----------+---------+-----------
    112. (0 rows)
    113. select * from list_list;
    114. month_code | dept_code | user_no | sales_amt
    115. ------------+-----------+---------+-----------
    116. (0 rows)
    117. drop table list_list;
  • 示例3:对二级分区表进行split操作

    1. CREATE TABLE list_list
    2. (
    3. month_code VARCHAR2 ( 30 ) NOT NULL ,
    4. dept_code VARCHAR2 ( 30 ) NOT NULL ,
    5. user_no VARCHAR2 ( 30 ) NOT NULL ,
    6. sales_amt int
    7. )
    8. PARTITION BY LIST (month_code) SUBPARTITION BY LIST (dept_code)
    9. (
    10. PARTITION p_201901 VALUES ( '201902' )
    11. (
    12. SUBPARTITION p_201901_a VALUES ( '1' ),
    13. SUBPARTITION p_201901_b VALUES ( default )
    14. ),
    15. PARTITION p_201902 VALUES ( '201903' )
    16. (
    17. SUBPARTITION p_201902_a VALUES ( '1' ),
    18. SUBPARTITION p_201902_b VALUES ( default )
    19. )
    20. );
    21. insert into list_list values('201902', '1', '1', 1);
    22. insert into list_list values('201902', '2', '1', 1);
    23. insert into list_list values('201902', '1', '1', 1);
    24. insert into list_list values('201903', '2', '1', 1);
    25. insert into list_list values('201903', '1', '1', 1);
    26. insert into list_list values('201903', '2', '1', 1);
    27. select * from list_list;
    28. month_code | dept_code | user_no | sales_amt
    29. ------------+-----------+---------+-----------
    30. 201903 | 2 | 1 | 1
    31. 201903 | 2 | 1 | 1
    32. 201903 | 1 | 1 | 1
    33. 201902 | 2 | 1 | 1
    34. 201902 | 1 | 1 | 1
    35. 201902 | 1 | 1 | 1
    36. (6 rows)
    37. select * from list_list subpartition (p_201901_a);
    38. month_code | dept_code | user_no | sales_amt
    39. ------------+-----------+---------+-----------
    40. 201902 | 1 | 1 | 1
    41. 201902 | 1 | 1 | 1
    42. (2 rows)
    43. select * from list_list subpartition (p_201901_b);
    44. month_code | dept_code | user_no | sales_amt
    45. ------------+-----------+---------+-----------
    46. 201902 | 2 | 1 | 1
    47. (1 row)
    48. alter table list_list split subpartition p_201901_b values (2) into
    49. (
    50. subpartition p_201901_b,
    51. subpartition p_201901_c
    52. );
    53. select * from list_list subpartition (p_201901_a);
    54. month_code | dept_code | user_no | sales_amt
    55. ------------+-----------+---------+-----------
    56. 201902 | 1 | 1 | 1
    57. 201902 | 1 | 1 | 1
    58. (2 rows)
    59. select * from list_list subpartition (p_201901_b);
    60. month_code | dept_code | user_no | sales_amt
    61. ------------+-----------+---------+-----------
    62. 201902 | 2 | 1 | 1
    63. (1 row)
    64. select * from list_list subpartition (p_201901_c);
    65. month_code | dept_code | user_no | sales_amt
    66. ------------+-----------+---------+-----------
    67. (0 rows)
    68. select * from list_list partition (p_201901);
    69. month_code | dept_code | user_no | sales_amt
    70. ------------+-----------+---------+-----------
    71. 201902 | 2 | 1 | 1
    72. 201902 | 1 | 1 | 1
    73. 201902 | 1 | 1 | 1
    74. (3 rows)
    75. select * from list_list subpartition (p_201902_a);
    76. month_code | dept_code | user_no | sales_amt
    77. ------------+-----------+---------+-----------
    78. 201903 | 1 | 1 | 1
    79. (1 row)
    80. select * from list_list subpartition (p_201902_b);
    81. month_code | dept_code | user_no | sales_amt
    82. ------------+-----------+---------+-----------
    83. 201903 | 2 | 1 | 1
    84. 201903 | 2 | 1 | 1
    85. (2 rows)
    86. alter table list_list split subpartition p_201902_b values (3) into
    87. (
    88. subpartition p_201902_b,
    89. subpartition p_201902_c
    90. );
    91. select * from list_list subpartition (p_201902_a);
    92. month_code | dept_code | user_no | sales_amt
    93. ------------+-----------+---------+-----------
    94. 201903 | 1 | 1 | 1
    95. (1 row)
    96. select * from list_list subpartition (p_201902_b);
    97. month_code | dept_code | user_no | sales_amt
    98. ------------+-----------+---------+-----------
    99. (0 rows)
    100. select * from list_list subpartition (p_201902_c);
    101. month_code | dept_code | user_no | sales_amt
    102. ------------+-----------+---------+-----------
    103. 201903 | 2 | 1 | 1
    104. 201903 | 2 | 1 | 1
    105. (2 rows)
    106. drop table list_list;