PostgreSQL10.0內建分割槽表
標籤
PostgreSQL , 10.0 , 分割槽表 , partitiion table , range , list
背景
PostgreSQL 和它的LOGO大象一樣,給人非常強大的安全感。
就拿它的Feature來說,一個大的feature要打磨很多年才能正式的合併到master分支。
比如平行計算的特性,從9.4就開始準備,加入了work process和dynamic shared memory的功能,奠定了多程式並行執行的基礎。
一致到9.6,經歷了3年的開發,大量的測試,終於RELEASE了。
今天要說一說它的分割槽表,經歷了幾年的醞釀,終於在10.0加入到master了。(PG的企業版本EDB很早就支援分割槽表了)
如果你現在需要這個功能,可以使用postgrespro的外掛, pg_pathman,否則就等10.0吧,明年9月份左右release。
《PostgreSQL 9.5+ 高效分割槽表實現 – pg_pathman》
PostgreSQL 10.0 分割槽表的設計
PostgreSQL的分割槽表依舊使用了繼承的特性,好訊息是, 終於不需要手工寫規則了。
在使用方面,我們需要先建立主表,然後建立分割槽(即子表)。老頑固啊,就是要讓你記住PG是有繼承的概念的嗎?
目前支援range、list分割槽(10.0 release時應該會支援更多的方法),分割槽列的型別必須支援btree索引介面(幾乎涵蓋所有型別, 後面會說到檢查方法)。
語法
1. 建立主表
[ PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ COLLATE collation ] [ opclass ] [, ... ] ) ]
2. 建立分割槽
PARTITION OF parent_table [ (
{ column_name [ column_constraint [ ... ] ]
| table_constraint }
[, ... ]
) ] FOR VALUES partition_bound_spec
and partition_bound_spec is:
{ IN ( expression [, ...] ) -- list分割槽
|
FROM ( { expression | UNBOUNDED } [, ...] ) TO ( { expression | UNBOUNDED } [, ...] ) } -- range分割槽, unbounded表示無限小或無限大
語法解釋
1. 建立主表
partition by 指定分割槽表的型別range或list
指定分割槽列,或表示式作為分割槽鍵。
range分割槽表鍵:支援指定多列、或多表示式,支援混合(鍵,非表示式中的列,會自動新增not null的約束)
list分割槽表鍵:支援單個列、或單個表示式
分割槽鍵必須有對應的btree索引方法的ops(可以檢視系統表得到)
select typname from pg_type where oid in (select opcintype from pg_opclass);
主表不會有任何資料,資料會根據分割槽規則進入對應的分割槽表
如果插入資料時,分割槽鍵的值沒有匹配的分割槽,會報錯
不支援全域性的unique, primary key, exclude, foreign key約束,只能在對應的分割槽建立這些約束
PARTITION BY { RANGE | LIST } ( { column_name | ( expression ) } [ opclass ] [, ...] )
The optional PARTITION BY clause specifies a strategy of partitioning the table.
The table thus created is called a partitioned table. The parenthesized list of columns or expressions forms the partition key for the table.
When using range partitioning, the partition key can include multiple columns or expressions, but for list partitioning, the partition key must consist of a single column or expression.
If no btree operator class is specified when creating a partitioned table, the default btree operator class for the datatype will be used. If there is none, an error will be reported.
A partitioned table is divided into sub-tables (called partitions), which are created using separate CREATE TABLE commands.
The partitioned table is itself empty. A data row inserted into the table is routed to a partition based on the value of columns or expressions in the partition key.
If no existing partition matches the values in the new row, an error will be reported.
Partitioned tables do not support UNIQUE, PRIMARY KEY, EXCLUDE, or FOREIGN KEY constraints;
however, you can define these constraints on individual partitions.
When using range partitioning, a NOT NULL constraint is added to each non-expression column in the partition key.
2. 建立分割槽
主表建立好之後,需要再建立分割槽(為了體現繼承麼?就不能一次幹掉?)
建立分割槽表需要指定它的主表是哪個?
指定分割槽鍵的屬性(範圍,LIST值),範圍,LIST不能有重疊(這個很好理解,否則重疊部分的資料到底插到哪個分割槽去呢?)
分割槽表和主表的 列數量,定義 必須完全一致,(包括OID也必須一致,要麼都有,要麼都沒有)
可以為分割槽表的列單獨增加Default值,或約束。
使用者還可以對分割槽表增加表級約束
如果新增的分割槽表check約束,名字與主表的約束名一致,則約束內容必須與主表一致
當使用者往主表插入資料庫時,記錄被自動路由到對應的分割槽,如果沒有合適的分割槽,則報錯
如果更新資料,並且更新後的KEY導致資料需要移動到另一分割槽,則會報錯,(意思是分割槽鍵可以更新,但是不支援更新後的資料移出到別的分割槽表)
修改主表的欄位名,欄位型別時,會自動同時修改所有的分割槽
TRUNCATE 主表時,會清除所有繼承表分割槽的記錄(如果有多級分割槽,則會一直清除到所有的直接和間接繼承的分割槽)
如果要清除單個分割槽,請對分割槽進行操作
如果要刪除分割槽表,可以使用DROP TABLE的DDL語句,注意這個操作會對主表也加access exclusive lock。
PARTITION OF parent_table FOR VALUES partition_bound_spec
partition_bound_spec is:
{ IN ( expression [, ...] ) |
FROM ( { expression | UNBOUNDED } [, ...] ) TO ( { expression | UNBOUNDED } [, ...] ) }
Creates the table as partition of the specified parent table.
The partition bound specification must correspond to the partitioning method and partition key of the parent table, and must not overlap with any existing partition of that parent.
A partition cannot have columns other than those inherited from the parent. That includes the oid column, which can be specified using the WITH (OIDS) clause.
Defaults and constraints can optionally be specified for each of the inherited columns.
One can also specify table constraints in addition to those inherited from the parent.
If a check constraint with the name matching one of the parent`s constraint is specified, it is merged with the latter, provided the specified condition is same.
Rows inserted into a partitioned table will be automatically routed to the correct partition. If no suitable partition exists, an error will occur.
Also, if updating a row in a given partition causes it to move to another partition due to the new partition key, an error will occur.
A partition must have the same column names and types as the table of which it is a partition.
Therefore, modifications to the column names or types of the partitioned table will automatically propagate to all children, as will operations such as TRUNCATE which normally affect a table and all of its inheritance children.
It is also possible to TRUNCATE a partition individually, just as for an inheritance child.
Note that dropping a partition with DROP TABLE requires taking an ACCESS EXCLUSIVE lock on the parent table.
例子
測試版本編譯
wget https://git.postgresql.org/gitweb/?p=postgresql.git;a=snapshot;h=55caaaeba877eac1feb6481fb413fa04ae9046ac;sf=tgz
tar -zxvf postgresql-55caaae.tar.gz
cd postgresql-55caaae
./configure --prefix=/home/digoal/pgsql10.0
make world -j 32
make install-world
export PGPORT=5299
export PGDATA=/disk1/pgdata/pg_root10
export LANG=en_US.utf8
export PGHOME=/home/digoal/pgsql10.0
export LD_LIBRARY_PATH=$PGHOME/lib:/lib64:/usr/lib64:/usr/local/lib64:/lib:/usr/lib:/usr/local/lib:$LD_LIBRARY_PATH
export DATE=`date +"%Y%m%d%H%M"`
export PATH=$PGHOME/bin:$PATH:.
export MANPATH=$PGHOME/share/man:$MANPATH
export PGHOST=$PGDATA
export PGUSER=postgres
export PGDATABASE=postgres
initdb -D $PGDATA -U postgres -E SQL_ASCII --locale=C
vi $PGDATA/postgresql.conf
cat postgresql.conf|grep "^[a-z]"|awk -F "#" `{print $1}`
listen_addresses = `0.0.0.0`
port = 5299
max_connections = 500
superuser_reserved_connections = 13
unix_socket_directories = `.`
shared_buffers = 16GB
maintenance_work_mem = 1024MB
dynamic_shared_memory_type = posix
bgwriter_delay = 10ms
bgwriter_lru_maxpages = 1000
bgwriter_lru_multiplier = 5.0
bgwriter_flush_after = 0
max_parallel_workers_per_gather = 0
max_parallel_workers = 0
old_snapshot_threshold = -1
backend_flush_after = 0
wal_buffers = 512MB
wal_writer_delay = 10ms
wal_writer_flush_after = 0
checkpoint_timeout = 55min
max_wal_size = 128GB
min_wal_size = 8GB
checkpoint_completion_target = 0.5
checkpoint_flush_after = 0
random_page_cost = 1.0
effective_cache_size = 400GB
log_destination = `csvlog`
logging_collector = on
log_truncate_on_rotation = on
log_checkpoints = on
log_connections = on
log_disconnections = on
log_error_verbosity = verbose
log_timezone = `PRC`
log_autovacuum_min_duration = 0
datestyle = `iso, mdy`
timezone = `PRC`
lc_messages = `C`
lc_monetary = `C`
lc_numeric = `C`
lc_time = `C`
default_text_search_config = `pg_catalog.english`
pg_ctl start
查詢可用的opclass
由於分割槽表的鍵值列必須支援btree索引,所以建議確認一下。
建立主表時,需要指定ops,如果沒有指定,會自動選擇型別預設的btree ops.
postgres=# select opcintype::regtype,opcname from pg_opclass ;
opcintype | opcname
-----------------------------+------------------------
abstime | abstime_ops
anyarray | array_ops
anyarray | array_ops
bit | bit_ops
boolean | bool_ops
character | bpchar_ops
character | bpchar_ops
。。。。。。
分割槽表
1. range 分割槽表
例子為按時間欄位分割槽的分割槽表,使用者在建立主表時,指定分割槽鍵,建立分割槽時,指定每個分割槽的範圍。
1.1 主表
range分割槽表,支援混合式的分割槽鍵(多列,多表示式,或者混合式)
和前面說的一樣,不能使用全域性PK
postgres=# create table t_range(id int primary key, info text, crt_time timestamp) partition by range (crt_time, mod(hashtext(info), 4));
ERROR: 0A000: primary key constraints are not supported on partitioned tables
LINE 1: create table t_range(id int primary key, info text, crt_time...
^
LOCATION: transformColumnDefinition, parse_utilcmd.c:620
postgres=# create table t_range(id int, info text, crt_time timestamp) partition by range (crt_time);
CREATE TABLE
1.2 分割槽
postgres=# create table t_range_0_201610 partition of t_range (id primary key, info , crt_time ) for values from (`2016-10-01`) to (`2016-11-01`); -- >= 20161001 and < 20161101
CREATE TABLE
postgres=# create table t_range_0_201611 partition of t_range (id primary key, info , crt_time ) for values from (`2016-11-01`) to (`2016-12-01`); -- >= 20161101 and < 20161201
CREATE TABLE
甚至你可以將分割槽表放到不同的schema下面
postgres=# create schema x;
CREATE SCHEMA
postgres=# create table x.t_range_0_201612 partition of t_range (id primary key, info , crt_time ) for values from (`2016-12-01`) to (`2017-01-01`);
CREATE TABLE
postgres=# d+ t_range
Table "public.t_range"
Column | Type | Collation | Nullable | Default | Storage | Stats target | Description
----------+-----------------------------+-----------+----------+---------+----------+--------------+-------------
id | integer | | | | plain | |
info | text | | | | extended | |
crt_time | timestamp without time zone | | not null | | plain | |
Partition key: RANGE (crt_time)
Partitions: t_range_0_201610 FOR VALUES FROM (`2016-10-01 00:00:00`) TO (`2016-11-01 00:00:00`),
t_range_0_201611 FOR VALUES FROM (`2016-11-01 00:00:00`) TO (`2016-12-01 00:00:00`),
x.t_range_0_201612 FOR VALUES FROM (`2016-12-01 00:00:00`) TO (`2017-01-01 00:00:00`)
2. list 分割槽表
2.1 主表
postgres=# create table t_list(id int, info text, crt_time timestamp) partition by list ( mod(hashtext(info), 4) );
CREATE TABLE
2.2 分割槽
postgres=# create table t_list_0 partition of t_list (id primary key, info , crt_time ) for values in (0);
CREATE TABLE
postgres=# create table t_list_1 partition of t_list (id primary key, info , crt_time ) for values in (1);
CREATE TABLE
postgres=# create table t_list_2 partition of t_list (id primary key, info , crt_time ) for values in (2);
CREATE TABLE
postgres=# create table t_list_3 partition of t_list (id primary key, info , crt_time ) for values in (3);
CREATE TABLE
多級分割槽
建立主表
create table t_range_list(id int, info text, crt_time timestamp) partition by list ( mod(hashtext(info), 4) );
建立一級分割槽,主表
create table t_range_list_0 partition of t_range_list (id , info , crt_time ) for values in (0) partition by range (crt_time);
create table t_range_list_1 partition of t_range_list (id , info , crt_time ) for values in (1) partition by range (crt_time);
create table t_range_list_2 partition of t_range_list (id , info , crt_time ) for values in (2) partition by range (crt_time);
create table t_range_list_3 partition of t_range_list (id , info , crt_time ) for values in (3) partition by range (crt_time);
建立2級分割槽表
create table t_range_list_0_201611 partition of t_range_list_0 (id primary key, info , crt_time ) for values from (`2016-10-01`) to (`2016-11-01`);
create table t_range_list_0_201612 partition of t_range_list_0 (id primary key, info , crt_time ) for values from (`2016-11-01`) to (`2016-12-01`);
create table t_range_list_1_201611 partition of t_range_list_1 (id primary key, info , crt_time ) for values from (`2016-10-01`) to (`2016-11-01`);
create table t_range_list_1_201612 partition of t_range_list_1 (id primary key, info , crt_time ) for values from (`2016-11-01`) to (`2016-12-01`);
create table t_range_list_2_201611 partition of t_range_list_2 (id primary key, info , crt_time ) for values from (`2016-10-01`) to (`2016-11-01`);
create table t_range_list_2_201612 partition of t_range_list_2 (id primary key, info , crt_time ) for values from (`2016-11-01`) to (`2016-12-01`);
create table t_range_list_3_201611 partition of t_range_list_3 (id primary key, info , crt_time ) for values from (`2016-10-01`) to (`2016-11-01`);
create table t_range_list_3_201612 partition of t_range_list_3 (id primary key, info , crt_time ) for values from (`2016-11-01`) to (`2016-12-01`);
執行計劃
1. 分割槽鍵條件建議使用同型別的常量、如果是函式則必須使用返回值與分割槽鍵型別一致,stable或immutable的函式。
postgres=# explain select * from t_range where crt_time=now()::timestamp; -- 如果需要轉換,轉換函式必須為immutable(常量),這樣可以在進行邏輯推理前被呼叫
QUERY PLAN
---------------------------------------------------------------------------
Append (cost=0.00..23929.55 rows=14 width=42)
-> Seq Scan on t_range (cost=0.00..0.00 rows=1 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201610 (cost=0.00..23870.00 rows=1 width=17)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201611 (cost=0.00..29.78 rows=6 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201612 (cost=0.00..29.78 rows=6 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
(9 rows)
postgres=# create or replace function sysdate() returns timestamp as $$
select now()::timestamp ;
$$ language sql strict immutable;
CREATE FUNCTION
postgres=# explain select * from t_range where crt_time=sysdate();
QUERY PLAN
----------------------------------------------------------------------------------------
Append (cost=0.00..24.12 rows=7 width=44)
-> Seq Scan on t_range (cost=0.00..0.00 rows=1 width=44)
Filter: (crt_time = `2016-12-16 09:58:03.246322`::timestamp without time zone)
-> Seq Scan on t_range_0_201612 (cost=0.00..24.12 rows=6 width=44)
Filter: (crt_time = `2016-12-16 09:58:03.246322`::timestamp without time zone)
(5 rows)
返回型別一致的C程式碼stable函式也可以被排除,否則會被解釋
postgres=# create or replace function sysdate() returns timestamp as $$
select now()::timestamp ;
$$ language sql strict stable;
CREATE FUNCTION
postgres=# explain select * from t_range where crt_time=sysdate();
QUERY PLAN
---------------------------------------------------------------------------
Append (cost=0.00..23929.55 rows=14 width=42)
-> Seq Scan on t_range (cost=0.00..0.00 rows=1 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201610 (cost=0.00..23870.00 rows=1 width=17)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201611 (cost=0.00..29.78 rows=6 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
-> Seq Scan on t_range_0_201612 (cost=0.00..29.78 rows=6 width=44)
Filter: (crt_time = (now())::timestamp without time zone)
(9 rows)
返回型別一致的C程式碼stable函式也可以被排除
postgres=# create table p(id int, info text, crt_time timestamptz);
CREATE TABLE
postgres=# create table t(like p) inherits(p);
NOTICE: merging column "id" with inherited definition
NOTICE: merging column "info" with inherited definition
NOTICE: merging column "crt_time" with inherited definition
CREATE TABLE
postgres=# create table p1(like p) inherits(p);
NOTICE: merging column "id" with inherited definition
NOTICE: merging column "info" with inherited definition
NOTICE: merging column "crt_time" with inherited definition
CREATE TABLE
postgres=# create table p2(like p) inherits(p);
NOTICE: merging column "id" with inherited definition
NOTICE: merging column "info" with inherited definition
NOTICE: merging column "crt_time" with inherited definition
CREATE TABLE
postgres=# alter table t add constraint ck check(crt_time >=`2016-11-01` and crt_time <`2016-12-01`);
ALTER TABLE
postgres=# alter table p1 add constraint ck check(crt_time >=`2016-10-01` and crt_time <`2016-11-01`);
ALTER TABLE
postgres=# alter table p2 add constraint ck check(crt_time >=`2016-09-01` and crt_time <`2016-10-01`);
ALTER TABLE
postgres=# explain select * from p where crt_time=now();
QUERY PLAN
----------------------------------------------------------------------------------------
Append (cost=0.00..0.00 rows=1 width=44)
-> Seq Scan on p (cost=0.00..0.00 rows=1 width=44)
Filter: (crt_time = `2016-12-16 10:02:40.483355+08`::timestamp with time zone)
(3 rows)
繫結分割槽,解綁分割槽
ALTER TABLE可以將表繫結到分割槽表的某個分割槽,也可以將某個已有分割槽從分割槽表剔除。
ALTER TABLE [ IF EXISTS ] name
ATTACH PARTITION partition_name FOR VALUES partition_bound_spec
ALTER TABLE [ IF EXISTS ] name
DETACH PARTITION partition_name
解釋
繫結時,需要指定分割槽鍵的邊界(範圍、或LIST值)
列名與主表一致、列型別一致、列順序一致、NOT NULL、CHECK約束一致、不建議UNIQUE,PK,FK。
不能有任何主表非繼承的CHECK約束,(建議對約束重建,不要加not inherit屬性)
加入的分割槽需要進行全表掃描,確認所有的記錄都在指定的分割槽鍵邊界內。
如果要避免全表掃描,建議在執行繫結前,對這個表加入CHECK約束,確保約束可以保證記錄都在邊界內。 但是這種方法不適用於分割槽鍵包含表示式並且分割槽不允許NULL值的情況。
ATTACH PARTITION partition_name FOR VALUES partition_bound_spec
This form attaches an existing table (which might itself be partitioned) as a partition of the target table using the same syntax for partition_bound_spec as CREATE TABLE.
The partition bound specification must correspond to the partitioning strategy and partition key of the target table.
The table to be attached must have all the same columns as the target table and no more; moreover, the column types must also match.
Also, it must have all the NOT NULL and CHECK constraints of the target table. Currently UNIQUE, PRIMARY KEY, and FOREIGN KEY constraints are not considered.
If any of the CHECK constraints of the table being attached is marked NO INHERIT, the command will fail; such a constraint must be recreated without the NO INHERIT clause.
A full table scan is performed on the table being attached to check that no existing row in the table violates the partition constraint.
It is possible to avoid this scan by adding a valid CHECK constraint to the table that would allow only the rows satisfying the desired partition constraint before running this command.
It will be determined using such a constraint that the table need not be scanned to validate the partition constraint.
This does not work, however, if any of the partition keys is an expression and the partition does not accept NULL values.
If attaching a list partition that will not accept NULL values, also add NOT NULL constraint to the partition key column, unless it`s an expression.
DETACH PARTITION partition_name
This form detaches specified partition of the target table. The detached partition continues to exist as a standalone table, but no longer has any ties to the table from which it was detached.
All the actions except RENAME, SET TABLESPACE, SET SCHEMA, ATTACH PARTITION, and DETACH PARTITION can be combined into a list of multiple alterations to apply in parallel.
For example, it is possible to add several columns and/or alter the type of several columns in a single command. This is particularly useful with large tables, since only one pass over the table need be made.
You must own the table to use ALTER TABLE. To change the schema or tablespace of a table, you must also have CREATE privilege on the new schema or tablespace.
To add the table as a new child of a parent table, you must own the parent table as well. Also, to attach a table as a new partition of the table, you must own the table being attached.
To alter the owner, you must also be a direct or indirect member of the new owning role, and that role must have CREATE privilege on the table`s schema.
(These restrictions enforce that altering the owner doesn`t do anything you couldn`t do by dropping and recreating the table.
However, a superuser can alter ownership of any table anyway.) To add a column or alter a column type or use the OF clause, you must also have USAGE privilege on the data type.
效能測試
range 分割槽表
插入
postgres=# insert into t_range select generate_series(1,1000000),`test`,`2016-10-01`;
INSERT 0 1000000
Time: 3849.514 ms (00:03.850)
直接插分割槽表
postgres=# truncate t_range;
TRUNCATE TABLE
Time: 72.181 ms
postgres=# insert into t_range_0_201610 select generate_series(1,1000000),`test`,`2016-10-01`;
INSERT 0 1000000
Time: 3587.772 ms (00:03.588)
查詢,主表未消除
postgres=# explain (analyze,verbose,timing,costs,buffers) select * from t_range where id=1 and crt_time=`2016-10-01`;
QUERY PLAN
------------------------------------------------------------------------------------------------------------------------------------------------------
Append (cost=0.00..2.45 rows=2 width=30) (actual time=0.037..0.038 rows=1 loops=1)
Buffers: shared hit=4
-> Seq Scan on public.t_range (cost=0.00..0.00 rows=1 width=44) (actual time=0.020..0.020 rows=0 loops=1)
Output: t_range.id, t_range.info, t_range.crt_time
Filter: ((t_range.id = 1) AND (t_range.crt_time = `2016-10-01 00:00:00`::timestamp without time zone))
-> Index Scan using t_range_0_201610_pkey on public.t_range_0_201610 (cost=0.42..2.45 rows=1 width=17) (actual time=0.016..0.016 rows=1 loops=1)
Output: t_range_0_201610.id, t_range_0_201610.info, t_range_0_201610.crt_time
Index Cond: (t_range_0_201610.id = 1)
Filter: (t_range_0_201610.crt_time = `2016-10-01 00:00:00`::timestamp without time zone)
Buffers: shared hit=4
Planning time: 0.248 ms
Execution time: 0.069 ms
(12 rows)
on conflict do
postgres=# insert into t_range select generate_series(1,1000000),`test`,`2016-10-01` on conflict do nothing;
ERROR: 0A000: ON CONFLICT clause is not supported with partitioned tables
LOCATION: transformInsertStmt, analyze.c:825
Time: 0.350 ms
參考
1. https://www.postgresql.org/docs/devel/static/sql-createtable.html
《PostgreSQL 9.5+ 高效分割槽表實現 – pg_pathman》
相關文章
- PostgreSQL:內建分割槽表SQL
- oracle分割槽表和分割槽表exchangeOracle
- Linux分割槽方案、分割槽建議Linux
- oracle分割槽表和非分割槽表exchangeOracle
- PostgreSQL/LightDB 分割槽表之分割槽裁剪SQL
- PG的非分割槽表線上轉分割槽表
- 【MYSQL】 分割槽表MySql
- 非分割槽錶轉換成分割槽表
- [oracle] expdp 匯出分割槽表的分割槽Oracle
- Oracle分割槽表基礎運維-07增加分割槽(3列表分割槽)Oracle運維
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- 移動分割槽表和分割槽索引的表空間索引
- Oracle分割槽表基礎運維-04列表分割槽Oracle運維
- Oracle查詢Interval partition分割槽表內資料Oracle
- Oracle分割槽表基礎運維-07增加分割槽(2 HASH分割槽)Oracle運維
- 分割槽表-實戰
- MySQL 分割槽表探索MySql
- Oracle分割槽表基礎運維-06分割槽表索引Oracle運維索引
- 【Linux】MBR磁碟分割槽表只能有四個分割槽?Linux
- oracle 線上重新定義,普通表改變分割槽表,分割槽表可以更改型別、分割槽欄位等Oracle型別
- Oracle分割槽表基礎運維-07增加分割槽(1範圍分割槽)Oracle運維
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維
- Oracle分割槽表基礎運維-09刪除分割槽Oracle運維
- Oracle分割槽表基礎運維-05組合分割槽Oracle運維
- Oracle分割槽表基礎運維-02範圍分割槽Oracle運維
- Oracle分割槽表基礎運維-03HASH分割槽Oracle運維
- 分割槽表之自動增加分割槽(11G)
- Mysql表分割槽實操MySql
- OceaBase 分割槽表建立技巧
- Mysql表分割槽實現MySql
- PostgreSQL:傳統分割槽表SQL
- SQL SERVER之分割槽表SQLServer
- ORACLE分割槽表梳理系列Oracle
- Spark操作Hive分割槽表SparkHive
- mysql 進行表分割槽MySql
- oracle將表配置為分割槽表Oracle
- oracle 普通表-分割槽表改造流程Oracle
- Oracle 12.2之後ALTER TABLE .. MODIFY轉換非分割槽表為分割槽表Oracle
- 增加表分割槽時,為local分割槽索引指定不同表空間的方法索引