1. 程式人生 > >PostgreSQL分割槽表(Table Partitioning)應用

PostgreSQL分割槽表(Table Partitioning)應用

一、簡介

  在資料庫日漸龐大的今天,為了方便對資料庫資料的管理,比如按時間,按地區去統計一些資料時,基數過於龐大,多有不便。很多商業資料庫都提供分割槽的概念,按不同的維度去存放資料,便於後期的管理,PostgreSQL也不例外。

  PostgresSQL分割槽的意思是把邏輯上的一個大表分割成物理上的幾塊兒。分割槽不僅能帶來訪問速度的提升,關鍵的是,它能帶來管理和維護上的方便。

  分割槽的具體好處是:

  • 某些型別的查詢效能可以得到極大提升。
  • 更新的效能也可以得到提升,因為表的每塊的索引要比在整個資料集上的索引要小。如果索引不能全部放在記憶體裡,那麼在索引上的讀和寫都會產生更多的磁碟訪問。
  • 批量刪除可以用簡單的刪除某個分割槽來實現。
  • 可以將很少用的資料移動到便宜的、轉速慢的儲存介質上。

  在PG裡表分割槽是通過表繼承來實現的,一般都是建立一個主表,裡面是空,然後每個分割槽都去繼承它。無論何時,都應保證主表裡面是空的。

  小表分割槽不實際,表在多大情況下才考慮分割槽呢?PostgresSQL官方給出的建議是:當表本身大小超過了機器實體記憶體的實際大小時(the size of the table should exceed the physical memory of the database server),可以考慮分割槽。

  PG目前(9.2.2)僅支援範圍分割槽和列表分割槽,尚未支援雜湊分割槽。

二、環境

系統環境:CentOS release 6.3 (Final)

PostgreSQL版本:PostgreSQL 9.2.2 on x86_64-unknown-linux-gnu, compiled by gcc (GCC) 4.4.6 20120305 (Red Hat 4.4.6-4), 64-bit

三、實現分割槽

3.1 建立主表

複製程式碼
david=# create table tbl_partition (
david(# id integer,
david(# name varchar(20),
david(# gender boolean,
david(# join_date date,
david(# dept 
char(4)); CREATE TABLE david=#
複製程式碼

3.2 建立分割槽表

複製程式碼
david=# create table tbl_partition_201211 (
check ( join_date >= DATE '2012-11-01' AND join_date < DATE '2012-12-01' )       
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201212 (
check ( join_date >= DATE '2012-12-01' AND join_date < DATE '2013-01-01' )      
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201301 (
check ( join_date >= DATE '2013-01-01' AND join_date < DATE '2013-02-01' )      
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201302 (
check ( join_date >= DATE '2013-02-01' AND join_date < DATE '2013-03-01' )  
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201303 (
check ( join_date >= DATE '2013-03-01' AND join_date < DATE '2013-04-01' ) 
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201304 (
check ( join_date >= DATE '2013-04-01' AND join_date < DATE '2013-05-01' )  
) INHERITS (tbl_partition);
CREATE TABLE
david=# create table tbl_partition_201305 (
check ( join_date >= DATE '2013-05-01' AND join_date < DATE '2013-06-01' )  
) INHERITS (tbl_partition);
CREATE TABLE
david=# 
複製程式碼

3.3 分割槽鍵上建索引

複製程式碼
david=# create index tbl_partition_201211_joindate on tbl_partition_201211 (join_date);
CREATE INDEX
david=# create index tbl_partition_201212_joindate on tbl_partition_201212 (join_date); 
CREATE INDEX
david=# create index tbl_partition_201301_joindate on tbl_partition_201301 (join_date);    
CREATE INDEX
david=# create index tbl_partition_201302_joindate on tbl_partition_201302 (join_date); 
CREATE INDEX
david=# create index tbl_partition_201303_joindate on tbl_partition_201303 (join_date); 
CREATE INDEX
david=# create index tbl_partition_201304_joindate on tbl_partition_201304 (join_date); 
CREATE INDEX
david=# create index tbl_partition_201305_joindate on tbl_partition_201305 (join_date); 
CREATE INDEX
david=# 
複製程式碼

對於開發人員來說,希望資料庫是透明的,只管 insert into tbl_partition。對於資料插向哪個分割槽,則希望由DB決定。這點,ORACLE實現了,但是PG不行,需要前期人工處理下。

3.4 建立觸發器函式

複製程式碼
david=# CREATE OR REPLACE FUNCTION tbl_partition_insert_trigger()                      
RETURNS TRIGGER AS $$  
BEGIN  
    IF ( NEW.join_date >= DATE '2012-11-01' AND    
         NEW.join_date < DATE '2012-12-01' ) THEN  
        INSERT INTO tbl_partition_201211 VALUES (NEW.*);  
    ELSIF ( NEW.join_date >= DATE '2012-12-01' AND  
            NEW.join_date < DATE '2013-01-01' ) THEN  
        INSERT INTO tbl_partition_201212 VALUES (NEW.*);  
    ELSIF ( NEW.join_date >= DATE '2013-01-01' AND  
            NEW.join_date < DATE '2013-02-01' ) THEN  
        INSERT INTO tbl_partition_201301 VALUES (NEW.*);  
    ELSIF ( NEW.join_date >= DATE '2013-02-01' AND  
            NEW.join_date < DATE '2013-03-01' ) THEN  
        INSERT INTO tbl_partition_201302 VALUES (NEW.*);  
    ELSIF ( NEW.join_date >= DATE '2013-03-01' AND  
            NEW.join_date < DATE '2013-04-01' ) THEN  
        INSERT INTO tbl_partition_201303 VALUES (NEW.*);  
    ELSIF ( NEW.join_date >= DATE '2013-04-01' AND  
            NEW.join_date < DATE '2013-05-01' ) THEN  
        INSERT INTO tbl_partition_201304 VALUES (NEW.*);
    ELSIF ( NEW.join_date >= DATE '2013-05-01' AND
            NEW.join_date < DATE '2013-06-01' ) THEN
        INSERT INTO tbl_partition_201305 VALUES (NEW.*); 
    ELSE  
        RAISE EXCEPTION 'Date out of range. Fix the tbl_partition_insert_trigger() function!';  
    END IF;  
    RETURN NULL;  
END;  
$$  
LANGUAGE plpgsql;
CREATE FUNCTION
david=# 
複製程式碼

說明:如果不想丟失資料,上面的ELSE 條件可以改成 INSERT INTO tbl_partition_error_join_date VALUES (NEW.*); 同時需要建立一張結構和tbl_partition 一樣的表tbl_partition_error_join_date,這樣,錯誤的join_date 資料就可以插入到這張表中而不是報錯了。

3.5 建立觸發器

david=# CREATE TRIGGER insert_tbl_partition_trigger
david-#     BEFORE INSERT ON tbl_partition
david-#     FOR EACH ROW EXECUTE PROCEDURE tbl_partition_insert_trigger();
CREATE TRIGGER
david=# 

四、查看錶

4.1 檢視所有表

複製程式碼
david=# \dt
                List of relations
 Schema |         Name         | Type  |  Owner   
--------+----------------------+-------+----------
 public | tbl_partition        | table | postgres
 public | tbl_partition_201211 | table | postgres
 public | tbl_partition_201212 | table | postgres
 public | tbl_partition_201301 | table | postgres
 public | tbl_partition_201302 | table | postgres
 public | tbl_partition_201303 | table | postgres
 public | tbl_partition_201304 | table | postgres
 public | tbl_partition_201305 | table | postgres
(8 rows)

david=# 
複製程式碼

4.2 檢視主表

複製程式碼
david=# \d tbl_partition
         Table "public.tbl_partition"
  Column   |         Type          | Modifiers 
-----------+-----------------------+-----------
 id        | integer               | 
 name      | character varying(20) | 
 gender    | boolean               | 
 join_date | date                  | 
 dept      | character(4)          | 
Triggers:
    insert_tbl_partition_trigger BEFORE INSERT ON tbl_partition FOR EACH ROW EXECUTE PROCEDURE tbl_partition_insert_trigger()
Number of child tables: 7 (Use \d+ to list them.)

david=# 
複製程式碼

4.3 檢視分割槽表

複製程式碼
david=# \d tbl_partition_201304
      Table "public.tbl_partition_201304"
  Column   |         Type          | Modifiers 
-----------+-----------------------+-----------
 id        | integer               | 
 name      | character varying(
            
           

相關推薦

PostgreSQL分割槽Table Partitioning應用

一、簡介   在資料庫日漸龐大的今天,為了方便對資料庫資料的管理,比如按時間,按地區去統計一些資料時,基數過於龐大,多有不便。很多商業資料庫都提供分割槽的概念,按不同的維度去存放資料,便於後期的管理,PostgreSQL也不例外。   PostgresSQ

Table

食品 無法 salesmen 查詢 保存 customers 商品 table 不同 雖然我們已經將不同用途的物品保存在不同的倉庫中了,但是在同一個倉庫中數據的保存仍然存在問題。比如食品分為熟食、生肉、大米等,如果把他們隨意的堆放在一起,就會造成我們無法很容易的對這些食品進

Hive: 建立分割槽partition分割槽匯入csv文字檔案資料

2018.11.21 文章目錄 前言 方法 前言 某專案生產環境中的Hive是按月份分割槽,而測試環境的沒有分割槽,導致部分功能無法驗證。 方法 基本思路:分別建立兩個表,一張是分割槽表,另一

全面總結Oracle中的分割槽

何時使用分割槽表 分割槽表是對錶按照規則進行劃分,這個是要根據業務場景來確定的。 建議值 1 大於2G的表 2 分割槽鍵必須反應業務需求,CUDR儘量不要跨分割槽操作 如果通過有效隔離,全表掃描就變成了分割槽掃描,降低IO,但如果已經使用索引,且結果集較小時,做分割槽不一定會

Oracle分割槽

【轉自:http://linux.chinaunix.net/techdoc/database/2007/11/14/972229.shtml, 部分內容調整並排版】 1.分割槽表的維護注意事項 若分割槽表跨不同表空間,做匯出、匯入時目標資料庫必須預建這些表空間。分表區各區

MySQL分割槽總結

4.13 只有RANG和LIST分割槽能進行子分割槽。HASH和KEY分割槽不能進行子分割槽。 4.14 分割槽表不支援Key caches。 SQL程式碼 mysql> SET GLOBAL keycache1.key_buffer_size=128*1024;   Query OK, 0 rows

主引導扇區MBR分割槽DPT及活動分割槽(DBR)

主引導扇區:硬碟的0柱面、0磁頭、1扇區(也叫主引導記錄MBR),大小為512Byte。 分割槽表(DPT):位於主引導分割槽,從偏移01BEH開始到偏移01FDH結束的64位元組。 活動分割槽DBR:DBR(DOS BOOT RECORD,原意為DOS引導記錄),位於柱面0

PostgreSQL 實現交叉行列轉換的五種方法

這裡我來演示下在POSTGRESQL裡面如何實現交叉表的展示,至於什麼是交叉表,我就不多說了,度娘去哦。原始表資料如下: t_girl=# select * from score;    name  | subject | score    -------+------

SQL Server中模式schema、資料庫databasetable、使用者user之間的關係

SQL Server中模式(schema)、資料庫(database)、表(table)、使用者(user)之間的關係 資料庫的初學者往往會對關係型資料庫模式(schema)、資料庫(database)、表(table)、使用者(user)之間感到迷惘,總感覺他們的關係千絲

SQL Server 2005中的分割槽:將已分割槽錶轉換成普通

我的俄羅斯名叫作“不折騰不舒服斯基”,所以,不將分割槽表好好折騰一下,我就是不舒服。     在前面,我們介紹過怎麼樣直接建立一個分割槽表,也介紹過怎麼將一個普通錶轉換成一個分割槽表。那麼,這兩種方式建立的表有什麼區別呢?現在,我又最新地建立了兩個表:     第

SQL Server 2008中的分割槽:新增一個分割槽

所謂天下大事,分久必合,合久必分,對於分割槽表而言也一樣。前面我們介紹過如何刪除(合併)分割槽表中的一個分割槽,下面我們介紹一下如何為分割槽表新增一個分割槽。     為分割槽表新增一個分割槽,這種情況是時常會 發生的。比如,最初在資料庫設計時,只預計了存放3年的資料

磁碟分割槽形式:主啟動記錄MBR和全域性唯一標識分割槽GPT

       過年放假回家到朋友家玩耍,在與朋友交談的時候提到了計算機,於是朋友便讓我幫他重新安裝系統。他電腦的系統我清楚,是WIN8的,之前就是我幫他安裝了,不過用著WIN8一直不是很順手,因此讓我

sqlserver分割槽1

如果你的資料庫中某一個表中的資料滿足以下幾個條件,那麼你就要考慮建立分割槽表了。     1、資料庫中某個表中的資料很多。很多是什麼概念?一萬條?兩萬條?還是十萬條、一百萬條?這個,我覺得是仁者見仁、智者見智的問題。當然資料表中的資料多到查詢時明顯感覺到資料很慢了,那麼,你就可以考慮使用分割槽表了。如果非

SQL Server 2008中的分割槽:刪除合併一個分割槽

在前面我們介紹過如何建立和使用一個分割槽表,並舉了一個例子,將不 同年份的資料放在不同的物理分割槽表裡。具體的分割槽方式為:     第1個小表:2010-1-1以前的資料(不包含2010-1-1)。     第2個小表:2010-1-1(包含2010-1-1)到20

SQL Server 中的分割槽:什麼是分割槽?為什麼要用分割槽?如何建立分割槽

如果你的資料庫中某一個表中的資料滿足以下幾個條件,那麼你就要考慮建立分割槽表了。     1、資料庫中某個表中的資料很多。很多是什麼概念?一萬條?兩萬條?還是十萬條、一百萬條?這個,我覺得是仁者見仁、智者見智的問題。當然資料表中的資料多到查詢時明顯感覺到資料很慢了,那麼,

劍指Offer-- 翻轉鏈 python版

head 鏈表 pytho blog write ini pre 當前 返回 輸入一個鏈表,反轉鏈表後,輸出鏈表的所有元素。 # -*- coding:utf-8 -*- # class ListNode: # def __init__(self, x): #

USD詞匯USD Glossary

one -a truct 層級 then 比較 一個 site 有著 這篇文章目的是將USD Glossary中比較重要的概念和相關API的說明翻譯出來,詞匯翻譯的列表會按照其重要程度排序,所以會打亂原有順序,這樣做是為了增強可讀性及邏輯性,對原文有興趣的請參考:https

鄰接圖論

個數 一個 des 一定的 -- class 晚自習 節點 ext 鄰接表(圖論) 還是挺狗的卡了我一個晚自習;總的來說就相當於將一條條的邊按鏈表的形式存住;點的個數是一定的所以我們可以建一個link數組記錄每一個節點所指引向的鏈表,即以該點為源頭的路;

聯賽之前的題已完成匯總可能有遺漏

api abi 高精 方差 主席樹 單調隊列 幾何 game 啟發式合並 聯賽之前的搞搞(其實是懶得分類) 博弈論 poj3537 poj1704 hdu5996兩個插頭 HDU1693 Eat the Trees COGS1283. [HNOI2004] 郵遞員kdtr

插頭dp題已完成

noi2007 神奇 zoj scoi2011 nbsp clas blog form class bzoj1814: Ural 1519 Formula 1 bzoj3125: CITY bzoj1210: [HNOI2004]郵遞員 bzoj2331: [SCOI201