Professional Documents
Culture Documents
PostgreSQL 8.3
Manual
Copyright © 2009 by Peekanung 2
Page
1. เก่ียวกับ PostgreSQL 3
2. Installation PostgreSQL บน Ubuntu 4
2.1 เก่ียวกับ pg_hba.conf 6
2.2 เก่ียวกับ postgresql.conf 7
2.3 Install pgAdmin GUI Application 8
3. การใช้งาน PostgreSQL 10
3.1 postgreSQL-Client Application (psql) 10
3.2 การจัดการ Database 10
3.3 การจัดการ Table และ View 12
3.3.1 Table 12
3.3.2 View 14
3.4 การจัดการ Roles 15
3.5 Data type 19
3.6 การ Import/Export data 20
3.7 postgreSQL Functions 21
3.8 Partitioning Table 22
3.9 Materialized View 24
3.9.1 Snapshot 24
3.9.2 Eager 27
3.9.3 Lazy 32
3.9.4 Very Lazy 32
3.10 การสำารองข้อมูล 35
3.10.1 Backup 35
3.10.2 Restore 36
3.11 Database Maintenance 37
Copyright © 2009 by Peekanung 3
1. เก่ย
ี วกับ PostgreSQL
PostgreSQL เปน object-relational database management system (ORDBMS) พัฒนามาจาก POSTGRES
Version 4.2 โดย University of California at Berkeley ภาควิชา Computer Science
PostgreSQL เปนโปรแกรม Open source สามารถนำ าไปใช้งานได้โดยไมมีคาใช้จาย และสนั บสนุนมาตรฐาน SQL:2003
ซ่ึงมีความสามารถตางๆ เชน
complex query
foreign keys
triggers
views
transactional integrity
multiversion concurrency control
รายละเอียดทั่วไปเกี่ยวกับ PostgreSQL
ขนาดฐานข้อมูล : ไมจำากัด
ขนาดตารางข้อมูล(table) : ไมเกิน 32 TB
ขนาดของข้อมูลแตละรายการ(row) : ไมเกิน 400 GB
ขนาดของข้อมูลแตละ field : 1GB
จำานวนรายการ(rows) ในตารางข้อมูล(table) : ไมจำากัด
จำานวน columns ในตารางข้อมูล(table): 250-1600 columns ขึ้นอยูกับชนิ ด column
จำานวน indexes ในตารางข้อมูล(table) : ไมจำากัด
การตัง้ช่ ือ
ขึ้นต้นด้วยตัวอักษรหรือ underscore(_)
ความยาวไมเกิน 31 ตัวอักษร
ไมซ้ำากับ reserve word หรือถ้าต้องการให้ใช้ Quote(“”)
การใช้ Quote(“”) จะทำาให้ช่ือท่ีอยูใน Quote(“”)เปนแบบ Case Sensitive
ช่ ือท่ีอยูในประเภทเดียวกันต้องไมซ้ำากัน เชน
■ ช่ ือ Database ท่ีอยูใน Cluster เดียวกันต้องไมซ้ำากัน
■ ช่ ือ Table ท่ีอยูใน Database เดียวกันต้องไมซ้ำากัน
■ ช่ ือ Column ท่ีอยูใน Table เดียวกันต้องไมซ้ำากัน
■ ช่ ือ Index ท่ีอยูใน Database เดียวกันต้องไมซ้ำากัน
หมายเหตุ
1. สามารถเข้าใช้งาน database โดยใช้คำาสัง่ psql ตามด้วยช่ ือ Database และช่ ือ User ตามลำาดับ โดยไมต้องระบุ option
เน่ ืองจาก default format เป็ น psql <database name> <user name>
เชน $ psql mydb user01
Copyright © 2009 by Peekanung 5
สามารถ connect โดยไมระบุ option ได้ แตต้องเรียงตามลำาดับดังนี้ : host (ถ้ามี), ช่ ือ database, ช่ ือ user เชน
$ psql mydb abc // สามารถ connect ได้ โดย Database = mydb , User = abc
Note: ไฟล์ postgresql.conf เป็ นไฟล์ท่ีใช้เก็บ Configuation ตางๆ ของ PostgreSQL ดังนี้ (เฉพาะ parameter ท่ีเปิ ดใช้อยูเทานั ้น)
# FILE LOCATIONS
data_directory = '/var/lib/postgresql/8.3/main' // Directory ท่ใี ช้เก็บ data และ configuration file ของ database
hba_file = '/etc/postgresql/8.3/main/pg_hba.conf' // Configuration file เก่ียวกับสิทธิก
์ ารเข้าถึง database
ident_file = '/etc/postgresql/8.3/main/pg_ident.conf' // Configuration file ท่ีใช้ map user กับ identifier user เพือใช้งานระบบ
external_pid_file = '/var/run/postgresql/8.3-main.pid' // path file ท่ีใช้บันทึก process id
แตละข้อความ สามารถอธิบายได้ดังนี้
local เปนการเช่ ือมตอในรูปแบบท่ีเคร่ ืองลูกขาย (client) และฐานข้อมูลอยูในเคร่ ืองเดียวกัน
host เปนเช่ ือมตอของเคร่ ืองลูกขายโดยใช้ TCP/IP ซ่ึงข้อมูลเปนแบบเข้ารหัสหรือไมก็ได้
hostssl เปนเช่ ือมตอของเคร่ ืองลูกขายโดยใช้ TCP/IP ซ่ ึงข้อมูลเปนแบบเข้ารหัสเทานั ้น
hostnossl เปนเช่ ือมตอของเคร่ ืองลูกขายโดยใช้ TCP/IP ซ่ ึงข้อมูลเปนแบบไมเข้ารหัส
CIDR-ADDRESS (Classless Inter-Domain Routing ) ระบุหมายเลข ip ของเคร่ ือง client ท่ีจะอนุญาตให้เข้าใช้งาน (ไม
สามารถระบุเปน domain หรือ ช่ ือเคร่ ือง)
OPTION ใส option ขึ้นกับวาเลือกการพิสูจน์ตัวตน (authentication) แบบไหน เชนถ้าใช้ method แบบ ident หรือ pam ท่ี
option นี้จะต้องระบุช่ือผู้ให้บริการ
listen_addresses = ‘*’ : เพ่ ืออนุญาตให้เคร่ ือง Client ท่ีใช้หมายเลข IP (IP address) อ่ ืนๆ ท่ีไมใช localhost
สามารถติดตอเข้าใช้งานฐานข้อมูล
data_directory : path directory ท่ีใช้เก็บโปรเเกรมระบบฐานข้อมูลและ configure file ของระบบ
hba_file : path file ท่ีใช้ในการควบคุมการเข้าใช้งานระบบฐานข้อมูลของ host
ident_file : path file ท่ีใช้ในการ map user กับ identifier user เพือใช้งานระบบ
external_pid_file : '/var/run/postgresql/8.3-main.pid' > path file ท่ีใช้บันทึก process id
port = 5432 : port ท่ีถูกเปิ ดใช้งานระบบฐานข้อมูล
max_connections = 100 : requires สูงสุดท่ีสามารถให้บริการ
unix_socket_directory = '/var/run/postgresql' : set path ในการเรียกใช้งานระบบ
ssl = true : ระบุการสงข้อมูลในรูปแบบของการเข้ารหัส
password_encryption = on : ระบุรูปแบบการสงข้อมูลวาจะมีการเข้ารหัสตัวข้อมูลด้วยหรือไม
shared_buffers = 24MB : shared buffers มีขนาดให้ใช้งานเทากับ 24MB
Copyright © 2009 by Peekanung 8
การเข้าใช้งาน
ไปท่ี Applications > Programming > pgAdmin III
3. การใช้งาน PostgreSQL
$ psql --help
Options:
-d <ช่ ือฐานข้อมูล> กำาหนด database name ท่ีต้องการติดตอ (default: postgres)
-f <ช่ ือไฟล์> Execute queries จากไฟล์
-h <host> กำาหนด database server host (default: localhost)
-l แสดงรายการฐานข้อมูลท่ีมีอยูทัง้หมด
-p <port> กำาหนด database server port (default: 5432)
-q ทำางานโดยไมแสดงข้อความจากระบบ แสดงเฉพาะผลลัพธ์ท่ีได้จาก query
-U <username> กำาหนด database username (default: postgres)
-V แสดง version information
-W Prompt เพ่ ือใส password (ปกติจะต้อง ใส password อยูแล้ว)
Options:
-D, --tablespace=TABLESPACE กำาหนด tablespace ให้กับ database
-E, --encoding=ENCODING กำาหนด encoding ให้กับ database
-O, --owner=OWNER กำาหนด user ท่ีจะเป็ นเจ้าของ database
-T, --template=TEMPLATE สร้าง database ตาม template ท่ีกำาหนด
-e, --echo กำาหนดให้แสดงคำาสัง่ท่จี ะถูกสงไป server
-q, --quiet กำาหนดให้ไมต้องแสดงผลจากการสัง่ create
--help แสดงตัวชวยเหลือเก่ียวกับการสร้าง database
--version แสดงเวอร์ชัน
่
Connection options:
-h, --host=HOSTNAME database server host หรือ socket directory
-p, --port=PORT database server port
-U, --username=USERNAME กำาหนด user name ท่ีใช้ connect
-W, --password กำาหนดให้ระบุ password ทันที
Copyright © 2009 by Peekanung 11
ตัวอยาง
$ createdb test with encoding='win874'
// สร้าง database ช่ ือ 'test' โดยกำาหนด encoding เป็ น 'win874'
$ createdb test –U postgres –E win874 –O user1
// สร้าง database ช่ ือ 'test' โดยกำาหนด username ท่ีใช้ connect เป็ น 'postgres' กำาหนด encoding
เป็ น 'win874' และให้ user1 เป็ นเจ้าของ database
(2) ลบ database
$ dropdb [OPTION]... [DBNAME] [DESCRIPTION]
Options:
-e, --echo กำาหนดให้แสดงคำาสัง่ท่จี ะถูกสงไป server
-i ,--interactive กำาหนดให้ตรวจสอบความถูกต้องของคำาสัง่กอนทำางาน
-h, --host=HOSTNAME database server host หรือ socket directory
-p, --port=PORT database server port
-U, --username=USERNAME กำาหนด user name ท่ีใช้ drop database
-W, --password กำาหนดให้ระบุ password ทันที
ตัวอยาง
$ dropdb demo // ลบ database ช่ ือ 'demo'
$ dropdb -i demo –U postgres // ลบ database ข่ ือ 'domo' ด้วย user 'postgres'
ตัวอยาง
SQL > DROP DATABASE test; / ลบ database ช่ ือ 'test'
*หมายเหตุ ฐานข้อมูลท่ีเปดใช้อยู ไมสามารถลบได้ ต้องปดกอน โดยใช้คำาสัง่ \q หรือ เปิ ดฐานข้อมูลอ่ ืน เชน \c test
(3) ด้ database
$ psql -l
ตัวอยาง
SQL > SELECT * FROM pg_database ; // pg_database จะแสดงรายละเอียดทัง้หมดของ database
datname|datdba|encoding|datistemplate|datallowconn|datconnlimit|datlastsysoid|datfrozenxid| dattablespace | datconfig | datacl
----------+---------+-----------+-----------------+-----------------+---------------+-----------------+---------------+-------------------+-------------+------------
db01 |16535 | 6 |f |t | -1 | 11510 | 379 | 16538| |
SQL Command
SQL > ALTER DATABASE name [ [ WITH ] option [ ... ] ]
Options:
CONNECTION LIMIT connlimit จำากัดการเข้าถึง database โดยถ้ากำาหนดเป็ น -1 จะหมายถึง unlimit
RENAME TO newname เปล่ียนช่ ือ database
OWNER TO new_owner เปล่ียนเจ้าของ database
SET configuration_parameter {TO|=}{value|DEFAULT} แก้ไข parameter ของ database (กำาหนดเอง)
SET configuration_parameter FROM CURRENT แก้ไข paramter ให้เป็ นไปตาม session นี้
RESET configuration_parameter reset configuration ของ database
RESET ALL reset ทุก configuration ของ database
ตัวอยาง
SQL > ALTER DATABASE test RENAME TO test_01;
// แก้ไข database โดยเปล่ียนช่ ือจาก 'test' เป็ นช่ ือ 'test_01'
SQL > ALTER DATABASE test OWNER TO user01;
// แก้ไข database โดยเปล่ียนเจ้าของเป็ น 'user01'
SQL > ALTER DATABASE test SET enable_indexscan TO off;
// แก้ไข database 'test' โดยกำาหนดเป็ นแบบไม่ใช้ index scaning
หมายเหตุ
OIDs คือ Object Identifier เป็ น Internal ID ของ postgreSQL ถ้าระบุเป็ น WITH OIDS จะสามารถใช้คำาสัง่
SELECT เพ่ ือดู OIDs ได้ โดย
SQL > SELECT oid, * FROM a;
oid | a_id | v
----------+------+----
16880 | 1 | 11
16881 | 2 | 22
(2 rows)
ตัวอยาง
SQL > CREATE TABLE testtable (id int, name varchar(30));
SQL > CREATE TABLE person (
did integer,
name varchar(40),
PRIMARY KEY(did) );
SQL > CREATE TABLE distributors (
did integer PRIMARY KEY DEFAULT nextval(’serial’),
name varchar(40) NOT NULL CHECK (name <> ”) );
หรือ
SQL > SELECT * FROM pg_tables ; // pg_tables จะแสดงผลเฉพาะ Table
หรือระบุช่ือ table
SQL > SELECT * FROM pg_tables where tablename = 'shipment';
schemaname | tablename | tableowner | tablespace | hasindexes | hasrules | hastriggers
-------------------+--------------+----------------+---------------+----------------+------------+-------------
public | shipment | user01 | |t |f |t
(1 row)
ด้โครงสร้างของ Table
SQL > \d table_name;
เชน SQL > \d shipment;
Table "public.shipment"
Column | Type | Modifiers
-------------------+-----------------------------+-------------------------------------------------------
id | integer | not null default nextval('shipment_id_seq'::regclass)
address | text | not null
shipping_date | timestamp without time zone | not null
Indexes:
"shipment_pkey" PRIMARY KEY, btree (id)
Triggers:
shipment_insert_trigger BEFORE INSERT ON shipment FOR EACH ROW EXECUTE PROCEDURE shipment_insert()
3.3.2 View
Views เปนตารางข้อมูลเทียม ซ่ ึง view จะเกิดจากตารางข้อมูล(Table) ท่ีมีอยูในฐานข้อมูล โดยใช้คำาสัง่ SELECT
ข้อมูลมาแสดงตามท่ีกาำ หนด View จะมีการกำาหนดสิทธิตางๆแยกจาก ตาราง และสวนตางๆ ของฐานข้อมูล ดังนั ้นเราจึง
สามารถกำาหนดสิทธิให้ผู้ใช้ท่ีเราต้องการกำาหนดเห็นเฉพาะข้อมูลในสวนท่ีต้องการได้
SQL > CREATE [ OR REPLACE ] [ TEMP | TEMPORARY ] VIEW name [ ( column_name [, ...] ) ]
AS query
ตัวอยาง
SQL > CREATE VIEW myview AS
SELECT city, temp_lo, temp_hi, prcp, date, location
FROM weather, cities
WHERE city = name;
(2) การด้View
ด้โครงสร้าง view SQL > \d view_name;
เชน SQL > \d myview;
View "public.myview"
Column | Type | Modifiers
------------+-----------------------+-----------
city | character varying(80) |
temp_lo | integer |
temp_hi | integer |
prcp | real |
date | date |
name | text |
population | real |
altitude | integer |
View definition:
SELECT weather.city, weather.temp_lo, weather.temp_hi, weather.prcp, weather.date, cities.name,
cities.population, cities.altitude
FROM weather, cities
WHERE weather.city::text = cities.name;
Copyright © 2009 by Peekanung 15
การด้ข้อม้ลใน View
SQL > SELECT * FROM myview;
Parameters:
IF EXISTS ถ้าไมมีช่ือ view ท่ีต้องการลบ ให้แสดง notice แทน error
name ช่ ือ view
CASCADE กรณี ท่ีมี objects ใดขึ้นอยูกับ view นี้ ให้ถูกลบโดยอัตโนมัติ
RESTRICT กรณี ท่ีมี objects ใดขึ้นอยูกับ view นี้ จะไมอนุญาตให้ drop view (เป็ นคา default)
ตัวอยาง
กรณี veiw 'v_myveiw' ไมมีอย้จริง
SQL > DROP view v_myview;
ERROR: view "v_myview" does not exist //ไม่สามารถลบ view ได้เน่ ืองจากไม่มีช่ือ view นี้อย่่จริง
postgreSQL ใช้ 'roles' ในการจัดการ การเข้าถึง database สำาหรับ postgreSQL version 8.1 หรือน้ อยกวา
user และ group จะถือเป็ นคนละอยางกัน แตหลังจาก version 8.1 เป็ นต้นมา role สามารถเป็ นได้ทัง้ user , group หรือทัง้
สองอยาง
คำาสัง่ CREATE USER เป็ น alias ของคำาสัง่ CREATE ROLE สามารถใช้แทนกันได้ มีข้อแตกตางเพียงข้อเดียวคือ
CREATE USER จะมี option 'LOGIN' เป็ น default จึงสามารถใช้ในการ Log in ได้เลย
CREATE ROLE จะมี option 'NOLOGIN' เป็ น default ถ้าต้องการใช้ Log in ได้ด้วยต้องระบุ option 'LOGIN'
ตัวอยาง
SQL > CREATE USER user01;
// สร้าง user ช่ ือ 'user01' แบบไม่ระบุ password ( ซ่ ึง user นี้จะยังเข้าใช้งาน database ไม่ได้ ต้อง
กำาหนด
password ให้กับ user ก่อน)
SQL > ALTER USER user01 WITH PASSWORD 'user0123' ;
// กำาหนด password ให้ user ท่ีสร้างไว้แล้ว
SQL > CREATE USER user01 WITH PASSWORD 'user0123';
// สร้าง user ช่ ือ 'user01' แบบระบุ password
SQL > CREATE USER user01 WITH PASSWORD 'user0123' CREATEDB;
// สร้าง user ท่ีสามารถสร้าง Database ได้
SQL > CREATE USER test1 role test2;
// assign role 'test1' ให้ user 'test2' เทียบเท่ากับ SQL > GRANT test1 TO test2 ;
ในกรณี นี้ test1 เป็ น role , test2 เป็ น user (หลัง option role จะเป็ น user)
SQL > CREATE USER test3 in role test2 ;
// assign role 'test2' ให้ user 'test3' เทียบเท่ากับ SQL > GRANT test2 TO test3;
ในกรณี นี้ test2 เป็ น role , test3 เป็ น user (หลัง option in role จะเป็ น role )
SQL > CREATE USER test4 admin test2 ;
// assign role 'test4' ให้ user 'test2' โดย 'test2' สามารถ grant privileges ให้ user อ่ ืนได้
เทียบเท่ากับ SQL > GRANT test2 TO test3 WITH ADMIN OPTION ;
3.4.5 การกำาหนดสิทธิการใช้งานข้อม้ล
เม่ ือมีการสร้างตารางข้อมูลขึ้นมา ผู้ท่ีสร้างตาราง(owner)เทานั ้นท่ีมีสิทธิในการใช้งาน ถ้าต้องการให้ผู้อ่ืนใช้งานได้ด้วย
จะต้องมีการแก้ไขสิทธิของตาราง(Table’s permission) โดยการใช้คำาสัง่ GRANT โดยคำาสัง่นี้ สามารถกำาหนดขอบเข
ตการใช้งาน SELECT, UPDATE, DELETE, RULE,ALL โดยท่ีกำาหนดการใช้ เปนรายบุคคล กลุม หรือทัง้หมด(Public)
และ REVOKE เปนคำาสัง่ ยกเลิกการกำาหนดสิทธิตางๆ ท่เี กิดจากคำาสัง่ GRANT
(1) GRANT
SQL > GRANT { { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ] ;
SQL > GRANT { { CREATE | CONNECT | TEMPORARY | TEMP } [,...] | ALL [ PRIVILEGES ] }
ON DATABASE dbname [, ...]
TO { [ GROUP ] rolename | PUBLIC } [, ...] [ WITH GRANT OPTION ]
SQL > GRANT role [, ...] TO rolename [, ...] [ WITH ADMIN OPTION ]
Copyright © 2009 by Peekanung 18
ตัวอยาง
SQL > GRANT all ON DATABASE pis TO user1; // กำาหนดให้ user1 มีสิทธิท ์ ุกอย่างบน database pis
SQL > GRANT all ON person TO user1; // กำาหนดให้ user1 มีสิทธิท ์ ุกอย่างบน table person
SQL > GRANT select ON person TO user2; // กำาหนดให้ user2 มีสิทธิ ์ select บน table person
(2) REVOKE
SQL > REVOKE [ GRANT OPTION FOR ]
{ { SELECT | INSERT | UPDATE | DELETE | REFERENCES | TRIGGER }
[,...] | ALL [ PRIVILEGES ] }
ON [ TABLE ] tablename [, ...]
FROM { [ GROUP ] rolename | PUBLIC } [, ...]
[ CASCADE | RESTRICT ]
เชน
SQL > CREATE FUNCTION tax(numeric)
RETURNS numeric
AS
'SELECT ($1*0.07::numeric(8,2))::numeric(8,2);'
LANGUAGE 'sql';
อธิบาย
− ช่ ือ Function คือ tax
− จำานวน Argument 1 การเรียกใช้ argument กำาหนดตามลำาดับ $1 $2 $3
− ชนิ ดข้อมูลของแตละ Argument คือ numeric
− Function return type เป็ น numeric
− การทำางาน คือ SELECT ($1*0.07::nueric(8,2)):: nueric(8,2);
ในคำาสัง่การทำางานสามารถใช้ INSERT UPDATE DELETE ได้รวมทัง้ Multiple Queries แยกคำาสัง่โดยใช้
semicolons คัน ่ แตละคำาสัง่
− ภาษาท่ีใช้ในการทำางาน คือ SQL
** หมายเหตุ
ในกรณี ท่ีสร้าง Function แล้วเกิด error
ERROR: language "plpgsql" does not exist
HINT: Use CREATE LANGUAGE to load the language into the database.
วิธีแก้ไขคือ ต้อง Login ด้วย user ท่ีเป็ นเจ้าของ Database แล้วใช้คำาสัง่
Copyright © 2009 by Peekanung 22
การทำา Partitioning Table คือ การแบงข้อมูลใน Table ออกเป็ น Table ยอยหลายๆ Table เหมาะสำาหรับ Table ท่ีมีข้อมูล
จำานวนมาก ซ่ึงมีข้อดีตา งๆ ดังนี้
Manageability
สามารถจัดการกับข้อมูลสวนยอยได้โดยไมกระทบกับข้อมูลทัง้หมด
การ Backup / Recovery สามารถแยกทำาแตละ partition ได้ ทำาให้การทำางานเร็วขึ้น และไมมีผลกระทบกับ
partition อ่ ืน
สามารถแยก Tablespace ของแตละ Partition ได้ ทำาให้การจัดการ tablespace ทำาได้งายขึ้น
Availability
เม่ ือต้องมีการจัดการบางอยางเดียวกับ Disk เชน เปล่ียน หรือซอม disk ระบบยังสามารถทำางานตอไปได้ เน่ ืองจาก
ไมมีผลกระทบใดๆ ตอข้อมูลท่ีอยูตาง disk กัน (กรณี ท่ีแตละ partition มีการแยก disk กัน)
Perfermance
การ Query ข้อมูลจาก partition จะเร็วกวาการ query จาก master table เน่ ืองจากข้อมูลมีจำานวนน้ อยกวา
2. หลังจากนั ้นให้ restart service ของ database โดยต้อง log in ด้วย user : root แล้วใข้คำาสัง่
$ service postgresql-8.3 restart
4.สร้าง 'Child tables' เพ่ ือใช้เป็ น partition ของ Master table โดยมี Contraints เป็ นตัวข้อกำาหนด column key ในการ
แบง partition
SQL > CREATE TABLE shipment_part_2008 (
CHECK (shipping_date >= DATE '2008-01-01'
AND shipping_date < DATE '2009-01-01')
) INHERITS (shipment);
5. สร้าง Index ให้แตละ child table (โดยใช้ key เดียวกับ column key ของ constrains ดังตัวอยาง คือ shipping_date )
SQL > CREATE INDEX shipping_date_2008 ON shipment_part_2008 (shipping_date);
SQL > CREATE INDEX shipping_date_pre2008 ON shipment_part_pre2008 (shipping_date);
SQL > CREATE INDEX shipping_date_post2008 ON shipment_part_post2008 (shipping_date);
6. สร้าง Function เพ่ ือกำาหนดให้มีการจัดเก็บข้อมูลใน partition table ท่ีถูกต้อง ในท่ีนี้ต้องการแบงเป็ น 3 partition คือ
ปี 2008 (shipment_part_2008),กอนปี 2008 (shipment_part_pre2008) และหลังปี 2008 (shipment_part_post 2008)
Copyright © 2009 by Peekanung 23
7. สร้าง Trigger เพ่ ือเป็ นการสัง่ execute function กอนมีการ Insert data เข้า master table ทุกครัง้
SQL > CREATE TRIGGER shipment_insert_trigger
BEFORE INSERT ON shipment
FOR EACH ROW EXECUTE PROCEDURE shipment_insert();
Materialized view (mview) เหมือน View ตรงท่ีมี link definition อยูกับ base table และเหมือน table ตรงท่ีมันจะเก็บ
ข้อมูลไว้ท่ต
ี ัวเอง DBA จะเป็ นผู้กำาหนดวาจะมีการ refresh data บอยแคไหน โดยท่ี user ไมจำาเป็ นต้องรู้วามี mview อยู เพราะ
สามารถ select statement ผาน base table ได้เหมือนเดิม
หมายเหตุ
Postgresql ไมสามารถใช้ Insert, Update, Delete กับ view ได้
Oracle สามารถใช้คำาสัง่ Insert, Update, Delete ได้ ในกรณี ท่ี view ไมได้เกิดจากการ join table การคำานวณ
หรือ virtual column ตัวอยาง virtual column เชน
SQL > create view v1 as select id, 'abc' as name from table1;
//name เป็ น virtual column ไม่สามารถใช้คำาสัง่ Insert, Update, Delete กับ column 'name' ได้
(แต่ใช้กับ 'id' โดยไม่ระบุ 'name'ได้)
SQL > insert into v1(id,name) values (2,'name02') ;
// insert ไม่ได้ เน่ ืองจาก name เป็ น virtual column
SQL > insert into v1(id) values (2) ;
// insert ได้เน่ ืองจากระบุเฉพาะ column 'id' ซ่ ึงเป็ น column ท่ีมีอย่่จริง
3. Lazy
■ ข้อมูลจะเปล่ียนแปลงตาม base table เม่ ือมีการ commit เทานั ้น ดังนั ้นข้อมูลจะไมมีการเปล่ียนแปลงบอย
เทาแบบ Eager แตข้อมูลจะถูกต้องตรงกับ base table มากกวาแบบ snapshot เน่ ืองจากไมต้องรอให้มีการ
สัง่ refresh
■ ข้อมูลใน mview กับ base table อาจจะไมตรงกันชัว ่ ขณะ (ขณะท่ียังอยูใน transaction แตยังไมได้
commit)
4. Very lazy
■ คล้ายแบบ snapshot คือข้อมูลจะเปล่ียนแปลงเม่ ือมีการสัง่ refresh data แตการ update ข้อมูลจะทำาได้เร็ว
กวา และใช้ทรัพยากรน้ อยกวา
WITH OIDS;
1.2 สร้าง Function create_matview เพ่ ือให้เก็บข้อมูลลง table matviews ทุกครัง้ท่ีมีการสัง่ refresh data
พร้อมเช็ควาช่ ือ mviews ต้องไมซำา้
SQL > CREATE OR REPLACE FUNCTION create_matview(NAME, NAME)
RETURNS VOID
SECURITY DEFINER
LANGUAGE plpgsql AS
'DECLARE
matview ALIAS FOR $1;
view_name ALIAS FOR $2;
entry matviews%ROWTYPE;
BEGIN
SELECT * INTO entry FROM matviews WHERE mv_name = matview;
IF FOUND THEN
RAISE EXCEPTION ''Materialized view ''''%'''' already exists.'',
matview;
END IF;
EXECUTE ''REVOKE ALL ON '' || view_name || '' FROM PUBLIC'';
EXECUTE ''GRANT SELECT ON '' || view_name || '' TO PUBLIC'';
EXECUTE ''CREATE TABLE '' || matview || '' AS SELECT * FROM '' || view_name;
EXECUTE ''REVOKE ALL ON '' || matview || '' FROM PUBLIC'';
EXECUTE ''GRANT SELECT ON '' || matview || '' TO PUBLIC'';
INSERT INTO matviews (mv_name, v_name, last_refresh)
VALUES (matview, view_name, CURRENT_TIMESTAMP);
RETURN;
END ';
1.3 สร้าง Function drop_matview เพ่ ือให้ลบ materialized view ออกจาก table matviews
SQL > CREATE OR REPLACE FUNCTION drop_matview(NAME) RETURNS VOID
SECURITY DEFINER
LANGUAGE plpgsql AS
'DECLARE
matview ALIAS FOR $1;
entry matviews%ROWTYPE;
BEGIN
SELECT * INTO entry FROM matviews WHERE mv_name = matview;
IF NOT FOUND THEN
RAISE EXCEPTION ''Materialized view % does not exist.'',
matview;
END IF;
EXECUTE ''DROP TABLE '' || matview;
DELETE FROM matviews WHERE mv_name=matview;
RETURN;
END';
1.4 สร้าง Function refresh_matview เพ่ ือสัง่ refresh data โดยในการสัง่ refresh data ต้องมีการระบุช่ือ
materialized view ด้วยเสมอ
SQL > CREATE OR REPLACE FUNCTION refresh_matview(name) RETURNS VOID
SECURITY DEFINER
LANGUAGE plpgsql AS '
DECLARE
matview ALIAS FOR $1;
entry matviews%ROWTYPE;
BEGIN
SELECT * INTO entry FROM matviews WHERE mv_name = matview;
IF NOT FOUND THEN
RAISE EXCEPTION ''Materialized view % does not exist.'',
matview;
END IF;
EXECUTE ''DELETE FROM '' || matview;
Copyright © 2009 by Peekanung 26
EXECUTE ''INSERT INTO '' || matview || '' SELECT * FROM '' || entry.v_name;
UPDATE matviews
SET last_refresh=CURRENT_TIMESTAMP
WHERE mv_name=matview;
RETURN;
END';
1.7 เม่ ือต้องการ Refresh data ใช้ function refresh_matviews ซ่ ึงการ refresh ทุกครัง้ ต้อง drop index เดิมกอน
เพ่ ือให้การ refresh ทำาได้เร็วขึ้น แล้วคอยสร้าง index ใหม
SQL > DROP INDEX pname_idx ON player_total_score_mv;
SQL > SELECT refresh_matview('player_total_score_mv');
SQL > CREATE INDEX pname_idx ON player_total_score_mv(pname);
3.9.2 Eager
ข้อมูลของ materialized view จะเปล่ียนแปลงทุกครัง้ท่ี table เปล่ียนแปลง โดยใช้ความสามารถของ trigger ท่ีอยูบน
table ในการจัดการ ซ่ ึง table นี้ เรียกวา 'Underlying table'
SQL > CREATE VIEW b_v AS -- สร้าง view b_v ซ่ ึงมาจากการ join table a, b และ c
SELECT b.b_id AS b_id,
a.v AS a_v,
b.v AS b_v,
sum(c.v) AS sum_c_v
FROM a JOIN b USING (a_id) JOIN c USING (b_id)
WHERE (b.expires IS NULL OR b.expires >= now())
GROUP BY b.b_id, a.v, b.v;
SQL > SELECT create_matview('b_mv', 'b_v');// สร้าง materialized view โดยใช้ function
create_matview
จากตัวอยาง ข้อมูลใน table a 1 แถว อาจมีผลกับหลายแถวใน view b_v ( 1 : m) , ใน table b 1 แถว มีผลกับ 1
แถวใน view b_v (1:1) และหลาย rows ใน table c มีผลกับ view b_v เพียง 1 แถว (m : 1)
UPDATE matviews
Copyright © 2009 by Peekanung 29
RETURN;
END ';
1.2 trigger b_mv_dt จะทำางานหลังจากมีการ delete data ใน table a โดยเรียกใช้ function b_mv_a_dt (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE FUNCTION b_mv_a_dt() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM b_mv_refresh_row(b.b_id) FROM b WHERE b.a_id = OLD.a_id;
RETURN NULL;
END ';
1.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table a โดยเรียกใช้ function b_mv_a_it (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE FUNCTION b_mv_a_it() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM b_mv_refresh_row(b.b_id) FROM b WHERE b.a_id = NEW.a_id;
RETURN NULL;
END';
ELSE
PERFORM b_mv_refresh_row(OLD.b_id);
PERFORM b_mv_refresh_row(NEW.b_id);
END IF;
RETURN NULL;
END';
2.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table b โดยเรียกใช้ function b_mv_b_it (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
3.2 trigger b_mv_dt จะทำางานหลังจากมีการ delete data ใน table c โดยเรียกใช้ function b_mv_c_dt (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL >CREATE FUNCTION b_mv_c_dt() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM b_mv_refresh_row(OLD.b_id);
Copyright © 2009 by Peekanung 31
RETURN NULL;
END';
3.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table c โดยเรียกใช้ function b_mv_c_it (ซ่ ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
3.9.3 Lazy
Lazy materialized view จะ update เม่ ือ transaction commit แล้ว ซ่ ึงจะเหมาะกับกรณี ท่ีข้อมูลในบาง row มีการ
เปล่ียนแปลงบอย
(2) สร้าง function matview_queue_refresh_row เพ่ ือ insert oid และ primary key เข้า table
matview_changes
SQL > CREATE FUNCTION matview_queue_refresh_row(NAME, INTEGER) RETURNS VOID
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
DECLARE
mv OID;
test INTEGER;
BEGIN
SELECT INTO mv oid FROM matviews WHERE mv_name = $1;
RETURN ;
END ';
PERFORM b_mv_refresh_row(b_id)
FROM b, matviews
WHERE matviews.oid = mv
AND b.expires >= matviews.last_refresh
AND b.expires < now();
PERFORM b_mv_refresh_row(pkey)
FROM matview_changes
WHERE mv_oid = mv;
UPDATE matviews
SET last_refresh = now()
WHERE mv_name = ''b_mv'';
END ';
Copyright © 2009 by Peekanung 33
1.2 trigger b_mv_dt จะทำางานหลังจากมีการ delete data ใน table a โดยเรียกใช้ function b_mv_a_dt (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE OR REPLACE FUNCTION b_mv_a_dt() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM matview_queue_refresh_row(''b_mv'', b.b_id)
FROM b WHERE b.a_id = OLD.a_id;
RETURN NULL;
END ';
SQL > CREATE TRIGGER b_mv_dt AFTER DELETE ON a
FOR EACH ROW EXECUTE PROCEDURE b_mv_a_dt();
1.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table a โดยเรียกใช้ function b_mv_a_it (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE OR REPLACE FUNCTION b_mv_a_it() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM matview_queue_refresh_row(''b_mv'', b.b_id)
FROM b WHERE b.a_id = NEW.a_id;
RETURN NULL;
END ';
SQL > CREATE TRIGGER b_mv_it AFTER INSERT ON a
FOR EACH ROW EXECUTE PROCEDURE b_mv_a_it();
2. trigger ของ table b มีดังนี้
2.1 trigger b_mv_ut จะทำางานหลังจากมีการ update data ใน table b โดยเรียกใช้ function b_mv_b_ut (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE OR REPLACE FUNCTION b_mv_b_ut() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
IF OLD.b_id = NEW.b_id THEN
PERFORM matview_queue_refresh_row(''b_mv'', NEW.b_id);
ELSE
PERFORM matview_queue_refresh_row(''b_mv'', OLD.b_id);
PERFORM matview_queue_refresh_row(''b_mv'', NEW.b_id);
END IF;
RETURN NULL;
END ';
Copyright © 2009 by Peekanung 34
2.2 trigger b_mv_dt จะทำางานหลังจากมีการ delete data ใน table b โดยเรียกใช้ function b_mv_b_dt (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
2.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table b โดยเรียกใช้ function b_mv_b_it (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
3.2 trigger b_mv_dt จะทำางานหลังจากมีการ delete data ใน table c โดยเรียกใช้ function b_mv_c_dt (ซ่ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE OR REPLACE FUNCTION b_mv_c_dt() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM matview_queue_refresh_row(''b_mv'', OLD.b_id);
RETURN NULL;
END ';
SQL > CREATE TRIGGER b_mv_dt AFTER DELETE ON c
FOR EACH ROW EXECUTE PROCEDURE b_mv_c_dt();
Copyright © 2009 by Peekanung 35
3.3 trigger b_mv_it จะทำางานหลังจากมีการ insert data ใน table c โดยเรียกใช้ function b_mv_c_it (ซ่ ึงจะ
เรียกใช้ function b_mv_refresh_row อีกที)
SQL > CREATE OR REPLACE FUNCTION b_mv_c_it() RETURNS TRIGGER
SECURITY DEFINER LANGUAGE 'plpgsql' AS '
BEGIN
PERFORM matview_queue_refresh_row(''b_mv'', NEW.b_id);
RETURN NULL;
END ';
SQL > CREATE TRIGGER b_mv_it AFTER INSERT ON c
FOR EACH ROW EXECUTE PROCEDURE b_mv_c_it();
• SQL dump
• File system level backup
• On-line backup
3.10.1 Backup
คำาสัง่ pg_dump เปนคำาสัง่ท่ีนำาเอาฐานข้อมูลท่ีระบุออกมาเปน Text File หรือรูปแบบอ่ ืนๆท่ีระบุ
คำาสัง่ pg_dumpall เป็ นคำาสัง่ท่ีสำารองทุกฐานข้อมูล ออกมาเป็ น Text File หรือรูปแบบอ่ ืนๆ ท่ีระบุ
Options:
-a --data-only สำาเนาเฉพาะข้อมูล ไมเอาโครงสร้าง
-b --blob สำาเนา large objects ด้วย (จะเป็ นคา default เม่ ือระบุ--schema, --table, or –schema-only)
-c --clean กำาหนดให้ output สร้างคำาสัง่ drop database กอน create
(ใช้ได้เฉพาะกรณี ท่ี output เป็ น plain-text format เทานั ้น)
-C --create กำาหนดให้ output สร้างคำาสัง่สำาหรับสร้าง database ไว้ด้วย
(ใช้ได้เฉพาะกรณี ท่ี output เป็ น plain-text format เทานั ้น)
-d --insert ให้นำาข้อมูลเข้าโดยใช้คำาสัง่ INSERT แทนคำาสัง่ COPY ของ PostgreSQL ซ่ ึงจะทำาให้นำาไปใช้กับ
ระบบฐานข้อมูลอ่ ืน เชน oracle ได้
-D --column-inserts เหมือน -d แตมีการระบุ Column ด้วย
-E --encoding ระบุ character set encoding (default คาจะเป็ นคาเดียวกับ database ท่ี dump)
-f --file=file เก็บข้อมูลลงแฟมท่ีกำาหนด
-F, format {c|t|p} เก็บข้อมูลลงแฟมตามรูปแบบท่ีกำาหนด โดย
c (custom) : กำาหนด output เอง (เป็ น default)เชน output.dmp , output.dump ,...
t ( tar) : กำาหนดเป็ น tar archive
p (plain) : เป็ นคา default, output เป็ น plain-text SQL scripts
-h --host database server host name
-n --schema สำาเนาเฉพาะ schema ท่ีกำาหนด
-N --exclude schema ไมสำาเนา schema ท่ีกำาหนด
-O --no owner ไมตัง้คาเจ้าของ ให้ใช้เหมือนเจ้าของเดิม
-o --oids สำาเนา oids ออกมาด้วย
-p --port ระบุหมายเลข port ของ database server
-s --schema-only สำาเนาเฉพาะโครงสร้าง schema ไมสำาเนาข้อมูล
-S --superuser ระบุ superuser เพ่ ือใช้ disable trigger (กรณี ท่ีต้องมีการ disable trigger)
-t --table สำาเนาเฉพาะ table ท่ีกำาหนด
-T --exclude table ไมสำาเนา table ท่ีกำาหนด
Copyright © 2009 by Peekanung 36
ตัวอยาง
$ pg_dump pis -f /tmp/pis.dump
// dump database 'pis' ออกมาโดยเก็บไว้ท่ี /tmp ช่ ือไฟล์ pis.dump
$ pg_dump –c –Fc –Z9 pis > pis.dump
// dump database 'pis' ออกมาโดยใช้ช่ือไฟล์ pis.dump โดยเพ่ิมคำาสัง่ drop database ก่อน
สัง่ create , กำาหนด output file แบบกำาหนดเอง และให้มีการบีบอัดแบบส่งสุด
$ pg_dump –U postgres –c –Fc –Z9 pis > pis.dump
// dump database 'pis' ออกมา โดยใช้ช่ือไฟล์ pis.dump กำาหนด username ท่ีใช้ติดตอคือ postgres
กำาหนด output file แบบกำาหนดเอง และให้มีการบีบอัดแบบส่งสุด
3.10.2 Restore
การนำ าข้อมูลสำารองท่ีได้จาก pg_dump ติดตัง้กลับเข้าฐานข้อมูลนั ้น ต้องพิจารณาใช้คำาสัง่ ท่ีใช้ในการนำ าเข้าจากชนิ ดของ
แฟมข้อมูลสำารอง คือ
• ถ้าแฟมข้อมูลสำารองอยูในรูปบีบอัด(สร้างจาก option –Fc หรือ –Ft) ให้ใช้คำาสัง่
$ PG_RESTORE [options..] [filename]
Options:
-a --data-only restore เฉพาะข้อมูล ไมเอาโครงสร้าง
-c --clean กำาหนดให้ drop database กอนทำาการ restore
- C --create create database กอน install
-d --database-name connect เข้า database ท่ีกำาหนดไว้แล้ว restore ลงใน database นั ้น
-e --exit-on-error ออกจากการทำางานทันทีเม่ ือเกิด error
(default คือ ทำางานตอไปแล้่วแสดง error ออกมา)
-f --file ระบุ output จากการ restore ออกมาเป็ นไฟล์
-F, format {c|t|} restore ข้อมูล ตามรูปแบบท่ีกำาหนด
ปกติถ้าไมกำาหนดคำาสัง่ pg_restore จะตรวจสอบให้อัตโนมัติ
-i --ignore-version ไมตรวจสอบ version ของ database
-I --index restore เฉพาะ index เทานั ้น
-l --list แสดงรายละเอียดของไฟล์
-n --namespace restore เฉพาะ object ท่ีอยูใน schema ท่ีระบุไว้
-O --no-owner ไมต้องตัง้คาเจ้าของให้เหมือนเจ้าของเดิม
-h --host ระบุ database server host name
-p --port ระบุหมายเลข port ของ database server
-s --schema-only restore เฉพาะโครงสร้าง schema ไมสำาเนาข้อมูล
-S --superuser ระบุ superuser เพ่ ือใช้ disable trigger
-t --table restore เฉพาะ table ท่ีกำาหนด
-U --username กำาหนดช่ ือ user ท่ีใช้ในการติดตอ
-W --password กำาหนดให้มีการใส password กอน connect เข้า database
-x --no privileges ไม restore คำาสัง่เก่ียวกับสิทธิการใช้งาน (grant/revoke)
ตัวอยาง
$ pg_restore -C -d postgres db.dump
// restore database โดยสัง่ให้มีการ create database ก่อน restore และระบุช่ือ database เป็ น postgres
$ createdb newtest
// สร้าง database รอไว้ ช่ ือ newtest
$ psql newtest < /tmp/test.dump
// restore เข้า database 'newtest' จากท่ี backup ไว้
เม่ ือมีการ Update/Delete ข้อมูล postgreSQL จะยังคงเก็บข้อมูล version เกาๆเอาไว้ (เป็ นการทำางานของ
Multiversion Concurrency Control : MVCC) ข้อมูลเกาท่ีถูกเก็บไว้นี้จะใช้พ้ืนท่ี disk เพ่ิ่มขึ้นเร่ ือยๆ ซ่ ึงจำาเป็ นต้องมีการกู้
พ้ืนท่ี disk ออกมาเพ่ ือใช้สำาหรับข้อมูลใหม และเพ่ ือป้ องกันการโตขึ้นของพ้ืนท่ี disk สามารถทำาได้โดยการรัน VACUUM
การรัน VACUUM เหมาะสำาหรับ table ท่ีมีการ update/delete ข้อมูลจำานวนมาก หรือบอยครัง้ ซ่ ึงไมมีความจำาเป็ น
นั กสำาหรับ table เล็กๆ หรือ table ท่ีไมคอยมีการเปล่ียนแปลงข้อมูล
VACUUM แบงออกเป็ น 2 ประเภท คือ LAZY VACUUM และ VACUUM FULL
1. LAZY VACUUM
lazy vacuum หรือ vacuum จะทำางานโดยการกำาหนด expire data เกาใน table และ index เพ่ ือใช้งานใหมใน
อนาคต พ้ืนท่ี disk จะไมถูกคืนให้แก OS ข้อดีของ vacuum คือสามารถรันไปพร้อมๆกับการทำางานอ่ ืนๆของ
database ได้ vacuum จึงเหมาะสำาหรับการสัง่ run แบบ routine เพราะไมมีผลกระทบตอการทำางานของ databa
se และใข้ทรัพยากรในการ run น้ อย
2. VACUUM FULL
เป็ นการเรียกคืนพ้ืนท่ีจากการ expire row version ซ่ ึงพ้ืนท่ีจากการสัง่ vacuum full นี้จะถูกคืนให้กับ OS ด้วย แตข้อ
เสียคือ table ท่ีกำาลังทำา VACUUM FULL จะถูก lock จนกวาจะทำางานเสร็จ vacuum full เหมาะสำาหรับกรณี ท่ีต้องการคืน
พ้ืนท่ีให้แก OS หรือกรณี ท่ีมีการ update/delete ข้อมูลจำานวนมาก ซ่ ึงการทำา VACUUM FULL จะใช้เวลาทำานานกวา
VACUUM
คำาสั่ง
SQL > VACUUM [FULL] [FREEZE] [VERBOSE] [ tablename]
SQL > VACUUM [FULL] [FREEZE] [VERBOSE] ANALYZE [ tablename] [(column [,...] )]]
กรณี ท่ีไมระบุช่ือ table จะหมายถึงสัง่ VACUUM ทุก ๆ table ใน database แตสำาหรับคำาสัง่ VACUUM
ANALYZE จะต้องระบุช่ือ table ด้วยเสมอ
parameters