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(# deptchar(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)、資料庫(database)、表(table)、使用者(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