postgresql分割槽表實現方式
1. 概述分割槽表
分割槽的意思是把邏輯上的一個大表分割成物理上的幾塊兒,分割槽可以提供若干好處:
1). 某些型別的查詢效能可以得到極大提升。
2). 更新的效能也可以得到提升,因為表的每塊的索引要比在整個資料集上的索引要小。如果索引不能全部放在記憶體裡,那麼在索引上的讀和寫都會產生更多的磁碟訪問。
3). 批次刪除可以用簡單地刪除某個分割槽來實現。
4). 將很少用的資料可以移動到便宜的、慢一些地儲存介質上。
假設當前的資料庫並不支援分割槽表,而我們的應用所需處理的資料量也非常大,對於這種應用場景,我們不得不人為的將該大表按 照一定的規則,手工拆分成多個小表,讓每個小表包含不同區間的資料。這樣一來,我們就必須在資料插入、更新、刪除和查詢之前,先計算本次的指令需要操作的小表。對於有些查詢而言,由於查詢區間可能會跨越多個小表,這樣我們又不得不將多個小表的查詢結 果進行 union 操作,以合併來自多個表的資料,並最終形成一個結果集返回給客戶端。可見,如果我們正在使用的資料庫不支援分割槽 表,那麼在適合其應用的場景下,我們就需要做很多額外的程式設計工作以彌補這一缺失。然而需要說明的是,儘管功能可以勉強應付, 但是效能卻和分割槽表無法相提並論。
目前 PostgreSQL 支援的分割槽形式主要為以下兩種:
1).範圍分割槽: 表被一個或者多個鍵字欄位分割槽成"範圍",在這些範圍之間沒有重疊的數值分佈到不同的分割槽裡。比如,我們可以為特定的商業物件根據資料範圍分割槽,或者根據識別符號範圍分割槽。
2).列表分割槽: 表是透過明確地列出每個分割槽裡應該出現那些鍵字值實現的。
2.測試案例
--登入到資料庫
postgres=# select current_database();
current_database
------------------
postgres
(1 row)
--建立資料庫
postgres=# create database mytest;
--切換資料庫
postgres=# \c mytest;
You are now connected to database "mytest" as user "postgres".
--建立父表
mytest=# create table parent(dpart_id bigserial,person_id bigserial,name varchar(20),birth date);
CREATE TABLE
mytest=# select * from parent;
dpart_id | person_id | name | birth
----------+-----------+------+-------
(0 rows)
--建立子表
pgsql本身像oracle那樣的分割槽定義什麼的,透過子表對父表的繼承定義實現的,所以有多少個分割槽,我們就必須建多少個子表。
mytest=# create table child_t01(check(dpart_id > 0 and dpart_id < 20)) inherits(parent);
CREATE TABLE
mytest=# create table child_t02(check(dpart_id >= 20 and dpart_id < 40)) inherits(parent);
CREATE TABLE
mytest=# create table child_t03(check(dpart_id >= 40 and dpart_id < 60)) inherits(parent);
CREATE TABLE
mytest=# create table child_t04(check(dpart_id >= 60 and dpart_id < 80)) inherits(parent);
CREATE TABLE
mytest=# create table child_t05(check(dpart_id >= 80 and dpart_id < 100)) inherits(parent);
CREATE TABLE
mytest=# create table child_t06(check(dpart_id >= 100)) inherits(parent);
--建立規則
建立好子表與父表的繼承關係後,不必須定義規則,然後才能把相應的資料插入到指定的子表中,具體過程如下:
mytest=# CREATE OR REPLACE RULE t01_qualified AS
ON INSERT TO parent WHERE dpart_id > 0 and dpart_id < 20
DO INSTEAD
INSERT INTO child_t01 VALUES(NEW.*);
CREATE RULE
其它幾個子表也按這種方式建立。
--插入資料測試
mytest=# insert into parent(dpart_id,person_id,name,birth) values(10,10011,'TOM',date'1984-05-04');
INSERT 0 0
mytest=# select * from parent;
dpart_id | person_id | name | birth
----------+-----------+------+------------
10 | 10011 | TOM | 1984-05-04
(1 row)
mytest=# select * from only parent;
dpart_id | person_id | name | birth
----------+-----------+------+-------
(0 rows)
可以看到資料並沒有儲存到父表中,而儲存在子表中
mytest=# select count(1) from parent;
count
-------
23
(1 row)
mytest=# select count(*) from only parent;
count
-------
0
(1 row)
總共插入了23條,我們可以看到父表中沒有資料,都透過子表的。
mytest=# explain select * from parent where dpart_id = 120;
QUERY PLAN
----------------------------------------------------------------
Append (cost=0.00..1.05 rows=2 width=78)
-> Seq Scan on parent (cost=0.00..0.00 rows=1 width=78)
Filter: (dpart_id = 120)
-> Seq Scan on child_t06 (cost=0.00..1.05 rows=1 width=78)
Filter: (dpart_id = 120)
從子表中查詢出來的。
mytest=# explain select * from parent where dpart_id > 20 and dpart_id <=70;
QUERY PLAN
----------------------------------------------------------------
Append (cost=0.00..3.18 rows=4 width=78)
-> Seq Scan on parent (cost=0.00..0.00 rows=1 width=78)
Filter: ((dpart_id > 20) AND (dpart_id <= 70))
-> Seq Scan on child_t02 (cost=0.00..1.06 rows=1 width=78)
Filter: ((dpart_id > 20) AND (dpart_id <= 70))
-> Seq Scan on child_t03 (cost=0.00..1.06 rows=1 width=78)
Filter: ((dpart_id > 20) AND (dpart_id <= 70))
-> Seq Scan on child_t04 (cost=0.00..1.06 rows=1 width=78)
Filter: ((dpart_id > 20) AND (dpart_id <= 70))
(9 rows)
3、其它方式
在pgsql中,分割槽表透過父表與子表的繼承關係,再加上定義的規則實現。當然也可以透過其它方式實現,如觸發器
首先建立一個函式
CREATE OR REPLACE FUNCTION parent_insert_f()
RETURNS TRIGGER AS
$$
BEGIN
IF(NEW.dpart_id > 0 and NEW.dpart_id < 20) THEN
INSERT INTO child_t01 VALUES (NEW.*);
END IF;
IF(NEW.dpart_id >= 20 and NEW.dpart_id < 40) THEN
INSERT INTO child_t02 VALUES (NEW.*);
END IF;
.............. --以此推算
RETURN NULL;
END;
$$
LANGUAGE plpgsql ;
透過trigger呼叫函式
CREATE TRIGGER parent_insert_tr
BEFORE INSERT ON parent
FOR EACH row
EXECUTE PROCEDURE parent_insert_f() ;
4、總結
總的說來,分割槽表實現還是比較麻煩的,不如oracle靈活,如果遇到複雜情況,就比較麻煩了。並且支援的分割槽也相對少一些。
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/29371470/viewspace-2123262/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- PostgreSQL使用表繼承實現分割槽表SQL繼承
- PostgreSQL/LightDB 分割槽表之分割槽裁剪SQL
- PostgreSQL:傳統分割槽表SQL
- PostgreSQL:內建分割槽表SQL
- Mysql表分割槽實現MySql
- PostgreSQL分割槽表更新思路SQL
- Oracle 到 PostgreSQL參考分割槽實現OracleSQL
- PostgreSQL LIST分割槽實現:繼承表+函式+觸發器。SQL繼承函式觸發器
- HGDB的分割槽表實現SQL Server的分割槽檢視SQLServer
- 分割槽表-實戰
- PostgreSQL/LightDB分割槽表之常見問題SQL
- oracle分割槽表和分割槽表exchangeOracle
- PostgreSQL分割槽表、繼承表記錄去重方法SQL繼承
- Mysql表分割槽實操MySql
- oracle分割槽表和非分割槽表exchangeOracle
- postgresql 9.6 分割槽表測試方案與記錄SQL
- PostgreSQL11preview-分割槽表增強彙總SQLView
- PostgreSQL 原始碼解讀(98)- 分割槽表#4(資料查詢路由#1-“擴充套件”分割槽表)SQL原始碼路由套件
- PG的非分割槽表線上轉分割槽表
- 實現MySQL表結構自動分割槽指令碼MySql指令碼
- 【MYSQL】 分割槽表MySql
- 非分割槽錶轉換成分割槽表
- [oracle] expdp 匯出分割槽表的分割槽Oracle
- Oracle分割槽表基礎運維-07增加分割槽(3列表分割槽)Oracle運維
- Oracle12c:建立主分割槽、子分割槽,實現自動分割槽插入效果Oracle
- oracle 分割槽表move和包含分割槽表的lob moveOracle
- 移動分割槽表和分割槽索引的表空間索引
- 線上重定義方式將普通表修改為分割槽表
- PostgreSQL 原始碼解讀(96)- 分割槽表#3(資料插入路由#3-獲取分割槽鍵值)SQL原始碼路由
- Oracle分割槽表基礎運維-04列表分割槽Oracle運維
- Oracle分割槽表基礎運維-07增加分割槽(2 HASH分割槽)Oracle運維
- MySQL 分割槽表探索MySql
- PostgreSQL9.x,10,11hash分割槽表用法舉例SQL
- Oracle分割槽表基礎運維-06分割槽表索引Oracle運維索引
- 【Linux】MBR磁碟分割槽表只能有四個分割槽?Linux
- oracle 線上重新定義,普通表改變分割槽表,分割槽表可以更改型別、分割槽欄位等Oracle型別
- Oracle分割槽表基礎運維-07增加分割槽(1範圍分割槽)Oracle運維
- Java中實現流的分割槽Java
- Oracle分割槽表基礎運維-01分割槽表分類Oracle運維