CREATE DATABASE mytest
WITH ENCODING='UTF8'
OWNER=postgres
CONNECTION LIMIT=-1;
CREATE DATABASE sample_db;
DROP DATABASE sample_db;
ALTER DATABASE mytest RENAME TO mytest1;
ALTER DATABASE mytest1 OWNER TO postgres1;
CREATE TABLE public.ppol
(
id "char",
CONSTRAINT isd1 PRIMARY KEY (id)
)
WITH (
OIDS = FALSE
);
ALTER TABLE public.ppol OWNER TO postgres;
CREATE TABLE tb_empl
(
id INT,
name VARCHAR(25),
depId INT,
salary FLOAT
);
CREATE TABLE tb_empl2
(
id INT PRIMARY KEY,
name VARCHAR(25),
deptId INT,
salary FLOAT
);
CREATE TABLE tb_empl3
(
id INT,
name VARCHAR(25),
deptId INT,
salary FLOAT,
PRIMARY KEY(id)
);
CREATE TABLE tb_empl
(
id INT,
name VARCHAR(25),
deptId INT,
salary FLOAT,
PRIMARY KEY(name, deptId)
);
-- 外键约束
CREATE TABLE tb_dept1
(
id INT PRIMARY KEY,
name VARCHAR(22) NOT NULL,
location VARCHAR(50)
);
CREATE TABLE tb_emp5
(
id INT PRIMARY KEY,
name VARCHAR(25),
depId INT,
salary FLOAT,
CONSTRAINT fk_emp_dept1 FOREIGN KEY(deptId) REFERENCES tb_dept1(id)
);
DROP TABLE IF EXISTS tb_dept2;
-- 删除有关联关系的表时
CREATE TABLE tb_dept2
(
id INT PRIMARY KEY,
name VARCHAR(22),
location VARCHAR(50)
);
CREATE TABLE tb_emp
(
id INT PRIMARY KEY,
name VARCHAR(25),
deptId INT,
salary INT,
CONSTRAINT fk_emp_dept FOREIGN KEY(deptId) REFERENCES tb_dept2(id)
);
DROP TABLE tb_dept2; -- 删除失败(被其它表所依赖)
ALTER TABLE tb_emp DROP CONSTRAINT fk_emp_dept; -- 删除依赖的外键
DROP TABLE tb_dept2; -- 成功
-- 修改字段名称
ALTER TABLE tb_dept1 RENAME location TO loc;
-- 调整字段类型
ALTER TABLE tb_dept1 ALTER COLUMN name TYPE VARCHAR(30);
CREATE TABLE tmp14 (num INT);
INSERT INTO tmp14 VALUES (64);
SELECT num, num+10, num-10, num+5-3, num+36.5 FROM tmp14;
SELECT num, num*2, num/2, num/3, num%3 FROM tmp14;
SELECT 1=0, '2'=2, 2=2, 'b'='b', (1+3)=(2+1), NULL=NULL;
SELECT 'good'<>'god', 1<>2, 4!=4, 5.5!=5, (1+3)!=(2+1), NULL<>NULL;
SELECT 2 IN (1,3,5), 2 NOT IN (1,3,5);
SELECT 'stud' LIKE 'stud', 'stud' LIKE 'stu_', 'stud' LIKE '%d', 'stud' LIKE 't__', 's' LIKE NULL;
CREATE TABLE tmp1 (x SMALLINT, y INT, z BIGINT);
CREATE TABLE tmp2 (x FLOAT(5), y REAL, z DOUBLE PRECISION);
CREATE TABLE tmp3 (x NUMERIC(5, 1), y NUMERIC (5, 2));
INSERT INTO tmp3(9.12, 9.15);
CREATE TABLE tmp4 (t TIME);
INSERT INTO tmp4 VALUES ('10:05:05 '), ('23:23'), ('101112');
SELECT * FROM tmp4;
ALTER TABLE mp4 ALTER COLUMN t TYPE time WITHOUT time zone;
DELETE FROM tmp4;
INSERT INTO tmp4 VALUES (CURRENT_TIME), (NOW());
SELECT * FROM tmp4;
CREATE TABLE tmp5 (d DATE);
INSERT INTO tmp5 VALUES ('1988-08-08'), ('19980808'), ('20101010');
SELECT * FROM tmp5;
DELETE FROM tmp5;
INSERT INTO tmp5 VALUES(NOW());
SELECT * FROM tmp5;
CREATE TABLE tmp6 VALUES (ts TIMESTAMP);
INSERT INTO tmp7 VALUES ('1996-02-02 02:02:02'), (NOW());
SELECT * FROM tmp7;
CREATE TABLE tmp7h (t TIME WITH TIME ZONE);
INSERT INTO tmp7h VALUES ('10:05:05 PST '), ('10:05:05');
SELECT * FROM tmp7h;
CREATE TABLE tmp8
(
ch CHARACTER(4),
vch CHARACTER VARYING (4)
);
INSERT INTO tmp8 VALUES('ab', 'ab'),('abcd', 'abcd'),('ab ', 'ab ');
SELECT CONCAT('(', ch, ')'), CONCAT('(', vch, ')') FROM tmp8;
INSERT INTO tmp8 VALUES('abcde', 'abcde'); -- 报错,太长了
CREATE TABLE tmp9 (te TEXT);
INSERT INTO tmp9 VALUES('ab'), ('abcd'), ('ab ');
SELECT CONCAT('(', te, ')') FROM tmp9;
CREATE TABLE tmp10(b BYTEA);
INSERT INTO tmp10 VALUES(E'\\000');
SELECT * FROM tmp10;
CREATE TABLE tmp11(b BOOLEAN);
INSERT INTO tmp11 VALUES (TRUE),(FALSE),('y'),('no'),('0');
CREATE TABLE tmp12(bt int[]);
INSERT INTO tmp12 VALUES ('{{1,1,1},{2,2,2},{3,3,3}}');
SELECT * FROM tmp12;
SELECT CAST(100 AS CHAR(2));
SELECT CAST(100 AS CHAR(100));
SELECT MD5('mypwd');
SELECT ENCODE('secret', 'hex'), LENGTH(ENCODE('secret', 'hex'));
SELECT DECODE(ENCODE('secret', 'hex'), 'hex'); -- 解密
SELECT CURRENT_DATE;
SELECT CURRENT_TIME;
SELECT LOCALTIME;
SELECT CURRENT_TIMESTAMP, LOCALTIMESTAMP, NOW();
SELECT EXTRACT(DAY FROM TIMESTAMP ‘2012-09-10 10:18:40');
SELECT EXTRACT(YEAR FROM TIMESTAMP ‘2012-09-10 10:18:40');
SELECT EXTRACT(MONTH FROM TIMESTAMP ‘2012-09-10 10:18:40');
SELECT EXTRACT(DOY FROM TIMESTAMP ‘2012-09-10 10:18:40'); -- 一年中的第几天
SELECT EXTRACT(DOW FROM TIMESTAMP ‘2012-09-10 10:18:40'); -- 一周中的第几天
SELECT EXTRACT(QUARTER FROM TIMESTAMP ‘2012-09-10 10:18:40'); -- 一年中的第几季度
SELECT DATE '2012-09-28' + integer '10'; -- 加 10 天
SELECT DATE '2012-09-28' - integer '10';
SELECT DATE '2012-11-01' - DATE '2012-09-10'; -- 相差天数
SELECT 15 * interval '2 day'; -- 30 days
SELECT ABS(2), ABS(-3, 3), ABS(-33);
SELECT PI();
SELECT SQRT(9), SQRT(40);
SELECT MOD(31, 8), MOD(234, 10), MOD(45.5, 6);
SELECT CEIL(-3.35), CEILING(3.35);
SELECT FLOOR(-3.35), FLOOR(3.35);
SELECT ROUND(-1.14), ROUND(-1.67), ROUND(1.14), ROUND(1.66);
SELECT SIGN(-21), SIGN(0), SIGN(21); -- -1 0 1
SELECT POW(2,2), POWER(2,2), POW(2, -2), POWER(2, -2);
SELECT EXP(3);
SELECT LOG(3);
SELECT RADIANS(90); -- 角度转弧度
SELECT DEGREES(PI()); -- 弧度转角度
SELECT SIN(1), ROUND(SIN(PI()));
SELECT
CASE 2
WHEN 1 THEN 'one'
WHEN 2 THEN 'two'
ELSE 'more'
END;
SELECT
CASE WHEN 1<0 THEN 'true'
ELSE 'false'
END;
SELECT VERSION();
SELECT USER, CURRENT_USER;
SELECT CHAR_LENGTH('date'), CHAR_LENGTH('egg');
SELECT LENGTH('date'), LENGTH('egg');
SELECT CONCAT('PostgreSQL', '9.15'), CONCAT('PostgreSQL', NULL, 'SQL');
SELECT CONCAT_WS('-', '1st', '2nd', '3rd'), CONCAT_WS('*', '1st', NULL, '3rd');
SELECT LEFT('FOOTBALL', 5), RIGHT('FOOTBALL', 5);
SELECT LPAD('hello', 4, '??'), LPAD('hello', 10, '??'); -- 填充
SELECT RPAD('hello', 4, '??'), RPAD('hello', 10, '??');
SELECT '( book )', CONCAT('(', LTRIM(' book '), ')');
SELECT '( book )', CONCAT('(', RTRIM(' book '), ')');
SELECT '( book )', CONCAT('(', TRIM(' book '), ')');
SELECT TRIM('xy' FROM 'xyboxyokxyxy'); -- 删除两端的指定字符 xy
SELECT REPEAT('PostgreSQL', 3);
SELECT SUBSTRING('breakfast, 5), SUBSTRING('breakfast', 5, 3), SUBSTRING('lunch', -3);
SELECT REPLACE('xxx.PostgreSQL.com', 'x', w');
CREATE TABLE person
(
id INT NOT NULL,
name CHAR(40) NOT NULL DEFAULT '',
age INT NOT NULL DEFAULT 0,
info CHAR(50) NULL,
PRIMARY KEY (id)
);
INSERT INTO person (id, name, age, info) VALUES (1, 'Green', 21, 'Lawyer');
SELECT * FROM person;
INSERT INTO person (age, name, id, info) VALUES (22, 'Suse', 2, 'Dancer');
SELECT * FROM person;
INSERT INTO person (3, 'Mary', 24, 'Musician'); -- 此时值的顺序需与定义字段的顺序一致
SELECT * FROM person;
INSERT INTO person (id, name, age) VALUES (4, 'Laura', 25);
SELECT * FROM person;
INSERT INTO person
(id, name, age, info)
VALUES
(5, 'Evans', 27, 'secretary'),
(6, 'Dale', 22, 'cook'),
(7, 'Edison', 28, 'singer');
SELECT * FROM person;
-- 值的顺序需与定义字段的顺序一致
INSERT INTO person
VALUES
(8, 'Harry', 21, 'magician'),
(9, 'Harriet', 19, 'pianist');
SELECT * FROM person;
CREATE TABLE person_old
(
id INT NOT NULL,
name CHAR(40) NOT NULL DEFAULT '',
age INT NOT NULL DEFAULT 0,
info CHAR(50) NULL,
PRIMARY KEY (id)
);
INSERT INTO person_old
VALUES
(10, 'Harry', 20, 'student'),
(11, 'Beckham', 31, 'police');
SELECT * FROM person_old;
INSERT INTO person(id, name, age, info)
SELECT id, name, age, info FROM person_old;
SELECT * FROM person WHERE id = 2;
DELETE * FROM person WHERE id = 2;
SELECT * FROM person WHERE id BETWEEN 4 AND 6;
DELETE FROM person WHERE id BETWEEN 4 AND 6;
DELETE FROM person;
SELECT * FROM person WHERE id = 10;
UPDATE person SET age = 15, name = 'Liming' WHERE id = 10;
UPDATE person set info='student' WHERE age BETWEEN 19 AND 22;
SELECT f_name FROM fruits;
SELECT f_name, f_price FROM fruits;
SELECT f_name FROM fruits WHERE f_price = 10.2;
SELECT f_price FROM fruits WHERE f_name='apple';
SELECT f_name, f_price FROM fruits WHERE f_price < 10;
SELECT s_id, f_name, f_price FROM fruits WHERE s_id IN (101, 102) ORDER BY f_name;
-- IN
-- NOT IN
-- BETWEEN AND
-- LIKE '%g%'
-- IS NULL
-- IS NOT NULL
-- AND
-- OR
-- DISTINCT
-- ORDER BY
-- DESC, ASC
-- GROUP BY
-- HAVING
SELECT s_id, f_name, f_price
FROM fruits
WHERE f_price < 9.0
UNION
SELECT s_id, f_name, f_price
FROM fruits
WHERE s_id IN (101, 103);
-- UNION 会去除重复的行
-- UNION ALL
CREATE TABLE fruits
(
f_id CHAR(10) NOT NULL,
s_id INT NOT NULL,
f_name CHAR(255) NOT NULL,
f_price DECIMAL(8, 2) NOT NULL,
PRIMARY KEY (f_id)
);
SELECT COUNT(*) AS cust_num FROM customers;
SELECT COUNT(c_email) AS email_num FROM customers;
SELECT s_id, COUNT(f_name) FROM fruits GROUP BY s_id;
SELECT s_id, MAX(f_price), MIN(f_price), SUM(f_price) AS price_total, AVG(f_price) AS price_avg FROM fruits GROUP BY s_id;
SELECT suppliers.s_id, s_name, f_name, f_price
FROM fruits, suppliers
WHERE fruits.s_id = suppliers.s_id;
SELECT suppliers.s_id, s_name, f_name, f_price
FROM fruits INNER JOIN suppliers
ON fruits.s_id = suppliers.s_id;
SELECT f1.f_id, f1.f_name
FROM fruits AS f1, fruits AS f2
WHERE f1.s_id = f2.s_id AND f2.f_id = 'a1';
SELECT customers.c_id, orders.o_num
FROM customers LEFT OUTER JOIN orders
ON customers.c_id = orders.c_id;
-- RIGHT OUTER JOIN
SELECT customers.c_id, orders.o_num
FROM customers INNER JOIN orders
ON customers.c_id = orders.c_id AND customers.c_id = '10001';
SELECT num1 FROM tb1 WHERE num1 > ANY (SELECT num2 FROM tb1);
SELECT num1 FROM tb1 WHERE num1 > ALL (SELECT num2 FROM tb1);
SELECT o_num FROM orders WHERE c_id IN
(SELECT c_id FROM customers WHERE c_name = 'RedHook');
SELECT s_id, f_name FROM fruits
WHERE s_id =
(SELECT s1.s_id FROM suppliers AS s1 WHERE s1.s_city = 'Tianjian');
SELECT * FROM orders AS o
WHERE o.o_num = 30001;
SELECT * FROM fruits WHERE f_name ~ '^be'; -- 查询以 be 开头的
SELECT * FROM fruits WHERE f_name ~ 'rry'; -- 查询以 rry 结尾
SELECT * FROM fruits WHERE f_name ~ 'a.g'; -- 含 a + 中间任意字符 + g
SELECT * FROM fruits WHERE f_name ~ '^ba*';
SELECT * FROM fruits WHERE f_name ~ '^ba+'; -- b 开头 + 至少一个 a
SELECT * FROM fruits WHERE f_name ~ 'on'; -- 包含 on
SELECT * FROM fruits WHERE f_name ~ 'on|ap'; -- 包含 on 或 ap
SELECT * FROM fruits WHERE f_name LIKE 'on';
SELECT * FROM fruits WHERE f_name LIKE 'apple';
SELECT * FROM fruits WHERE f_name ~ '[ot]'; -- 匹配 ot 中的任意一个
SELECT * FROM fruits WHERE f_id !~ '[a-e1-2]'; -- 不包含 a-e 及 1-2 的
CREATE INDEX customers_id ON customers (c_id AS NULLS LAST);
-- 普通索引
CREATE INDEX bknameidx ON book(bookname);
-- 唯一索引
CREATE UNIQUE INDEX uniqueidx ON book(bookId);
-- 多列(组合)索引
CREATE INDEX bkauandinfoidx ON book(authors,info);
DROP INDEX bkauandinfoidx;
ALTER INDEX public.bkauandinfoidx RENAME TO bkauandinfoidx2;
CREATE VIEW view_t AS SELECT quantity, price, quantity * price FROM t;
SELECT * FROM view_t;
CREATE VIEW view_t2(qty, price, total) AS SELECT quantity, price, quantity * price FROM t;
SELECT * FROM view_t2;
CREATE VIEW stu_glass (id, name, glass)
AS
SELECT student.s_id, student.name, stu_info.glass
FROM student, stu_info
WHERE student.s_id = stu_info.s_id;
SELECT * FROM stu_glass;
-- 修改视图名称
ALTER TABLE stu_glass RENAME TO stu_glass1;
DROP VIEW IF EXISTS stu_glass;
SELECT * FROM information_schema.views;
CREATE TABLE timedb
(
uid INTEGER,
gid INTEGER,
uptime TIMESTAMP WITH TIME ZONE
);
-- 创建触发器函数
CREATE FUNCTION func_timedb() RETURNS trigger AS $func_timedb$
BEGIN
IF (TG_OP = 'UPDATE') THEN
IF NEW.uptime = OLD.uptime THEN
return null;
END IF;
UPDATE timedb SET uptime = NOW WHERE uid = NEW.uid AND gid = NEW.gid
return null;
END;
$func_timedb$ LANGUAGE plpgsql;
-- 创建触发器函数
CREATE TRIGGER timedb_updateTime AFTER INSERT ON timedb
FOR EACH ROW EXECUTE PROCEDURE func_timedb();
INSERT INTO timedb VALUES(1, 3);
SELECT * FROM timedb; -- uid 1/gid 3/uptime 2012-12-28 22:29:56.046
DROP TRIGGER timedb_updateTime ON timedb;
ALTER TRIGGER timedb_updateTime ON timedb RENAME TO timeTrigger;
CREATE TABLE account
(
id INT,
name CHAR(20)
);
CREATE FUNCTION account_stam() RETURNS TRIGGER AS $account_stam$
BEGIN
IF NEW.NAME IS NULL THEN
RAISE EXCEPTION 'name 字段不能为空值';
END IF;
END;
$account_stam$ LANGUAGE plpgsql;
CREATE TRIGGER account_stamp BEFORE INSERT ON account
FOR EACH ROW EXECUTE PROCEDURE account_stam();
INSERT INTO account VALUES (10); -- 错误:name 字段不能为空值
SELECT * FROM person;
BEGIN;
INSERT INTO person VALUES(1003, '路飞', 80, '10456354');
INSERT INTO person VALUES(1004, '张露', 85, '56423424');
INSERT INTO person VALUES(1005, '魏波', 70, '41242774');
ROLLBACK TRANSACTION;
COMMIT;
SELECT * FROM person;
ALTER DATABASE test ONWER TO post4; -- 调整数据库属主
GRANT UPDATE ON book TO postgres; -- 允许用户 postgres 更新 book 表
CREATE ROLE post1
CREATEROLE
VALID UNTIL 'infinity';
CREATE ROLE post2;
SELECT rolname FROM pg_roles;
ALTER ROLE post2 RENAME TO post3;
DROP ROLE post3;
ALTER ROLE post1 CREATEDB CREATEROLE; -- 添加创建数据库、创建角度权限
CREATE ROLE postgres1 LOGIN; -- 创建登录角色
ALTER USE postgres1 CREATEDB CREATEROLE;
ALTER USER postgres1 NOCREATEDB NOCREATEROLE; -- 收回权限
CREATE ROLE post4 LOGIN; -- 创建登录角色(赋予角色登录权限)
CREATE ROLE post5 SUPERUSER; -- 创建超级用户
CREATE ROLE post6 CREATEDB;
CREATE ROLE post7 CREATEROLE;
CREATE ROLE post8 PASSWORD '123456'; -- 创建带有口令的角色
cd C:/Program Files/PostgreSQL/9.1/bin/
pg_dump -U postgres -f C:\test_backup test
# 备份整个数据库
pg_dumpall -U postgres -f C:\dball_backup
cd C:/Program Files/PostgreSQL/9.1/bin/
psql -d test -U postgres -f C:\test_backup
性能优化
优化简介
优化数据库是数据库管理员和数据库开发人员的必备技能。优化一方面是找出系统的瓶颈,提高数据库整体的性能;另一方面,需要合理的结构设计和参数调整,以提高用户操作响应的速度;同时还要尽可能的节省系统资源,以便系统可以提供更大负荷的服务
优化查询
优化数据库结构
优化 PostgreSQL 服务器
高可用、负载均衡和数据复制
常见的解决方案
日志传送备用服务器
日志传送(log shipping)是一种方法,它自动从主服务器备份事务日志,并使该备份自动对备用服务器可访问。一旦将日志文件放到了备用服务器上,它就可以保持与主服务器的相对同步。
数据的流复制
PostgreSQL 9.0 版本开始提供流复制技术,即备用服务器可以实时同步主服务器,如果备用服务器机器性能足够好,延迟时间可以是毫秒级
数据的同步复制
尽管数据的流复制可以让备用服务器实时地同步主服务器的数据,但是流复制技术依然是异步的。当主服务器崩溃时,备用服务器仍然存在数据丢失的风险。为了解决上面的问题,从 PostgreSQL 9.1 开始,可以支持同步复制技术。
服务器配置与数据库监控
服务器配置
监控数据库的活动
监控磁盘的使用
内部结构(Internals)
查询经过的路径
建立连接
PostgreSQL 是用一个简单的“每用户一进程”的 client/server 模型来实现的
分析器阶段
PostgreSQL 规则系统(重写系统)
用于接收分析器阶段创建的查询树,还搜索任何应用到查询树上的规则(存储在系统表里),然后根据给出的规则体进行转换
规划器/优化器
执行器
执行器规划器/优化器传过来的查询规划然后递归地处理它,抽取所需要的行集合
06/01/2019 Saturday 14:38