PostgreSQL 基本使用

第 1 章

  • 初识 PostgreSQL

第 2 章

  • PostgreSQL 的安装和启动
  • pgAdmin 基本操作

第 3 章

  • 创建数据库
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;

第 4 章

  • 创建数据表
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);

第 5 章

  • 常见运算符介绍
    • 算术
    • 比较
    • 逻辑
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;
  • PostgreSQL数据类型
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;

第 6 章

  • 改变数据类型的函数
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 TIMESTAMP2012-09-10 10:18:40');
SELECT EXTRACT(YEAR FROM TIMESTAMP ‘2012-09-10 10:18:40');
SELECT EXTRACT(MONTH FROM TIMESTAMP2012-09-10 10:18:40');
SELECT EXTRACT(DOY FROM TIMESTAMP ‘2012-09-10 10:18:40');  -- 一年中的第几天
SELECT EXTRACT(DOW FROM TIMESTAMP2012-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');

第 7 章

  • 插入数据
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;

第 8 章

  • 单表查询
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 的

第 9 章

  • 创建索引
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;

第 10 章

  • 创建视图
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;

第 11 章

  • 创建触发器
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 字段不能为空值

第 12 章

  • 事务管理简介
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;

第 13 章

  • 数据库权限管理
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';  -- 创建带有口令的角色

第 14 章

  • 数据备份
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

第 15 章

性能优化

  • 优化简介

    优化数据库是数据库管理员和数据库开发人员的必备技能。优化一方面是找出系统的瓶颈,提高数据库整体的性能;另一方面,需要合理的结构设计和参数调整,以提高用户操作响应的速度;同时还要尽可能的节省系统资源,以便系统可以提供更大负荷的服务

  • 优化查询

    • 分析查询语句 EXPLAIN
    • 索引对查询速度的影响
    • 优化子查询
  • 优化数据库结构

    • 删除索引
    • 使用批量插入
    • 删除外键约束
    • 禁止自动提交
    • 使用 COPY 批量导入
  • 优化 PostgreSQL 服务器

    • 优化服务器硬件
    • 优化服务器的参数

第 16 章

高可用、负载均衡和数据复制

  • 常见的解决方案

    • 共享磁盘故障转移
    • 文件系统复制
    • 事务日志
    • 基于语句的复制
    • 异步复制
    • 同步复制
  • 日志传送备用服务器

    日志传送(log shipping)是一种方法,它自动从主服务器备份事务日志,并使该备份自动对备用服务器可访问。一旦将日志文件放到了备用服务器上,它就可以保持与主服务器的相对同步。

  • 数据的流复制

    PostgreSQL 9.0 版本开始提供流复制技术,即备用服务器可以实时同步主服务器,如果备用服务器机器性能足够好,延迟时间可以是毫秒级

  • 数据的同步复制

    尽管数据的流复制可以让备用服务器实时地同步主服务器的数据,但是流复制技术依然是异步的。当主服务器崩溃时,备用服务器仍然存在数据丢失的风险。为了解决上面的问题,从 PostgreSQL 9.1 开始,可以支持同步复制技术。

第 17 章

服务器配置与数据库监控

  • 服务器配置

    • 服务器配置的文件
    • 连接与认证
    • 资源消耗
    • 预写式日志
    • 查询规划
    • 错误报告和日志
    • 运行时统计
    • 自动清理
    • 客户端连接缺省
    • 锁管理
    • 版本和平台兼容性
  • 监控数据库的活动

    • 配置统计收集器
    • 查看收集到的统计信息
  • 监控磁盘的使用

    • 监控磁盘的使用量
    • 磁盘满导致的失效

第 18 章

内部结构(Internals)

  • 查询经过的路径

  • 建立连接

    PostgreSQL 是用一个简单的“每用户一进程”的 client/server 模型来实现的

  • 分析器阶段

    • 分析器
    • 转换处理
  • PostgreSQL 规则系统(重写系统)

    用于接收分析器阶段创建的查询树,还搜索任何应用到查询树上的规则(存储在系统表里),然后根据给出的规则体进行转换

  • 规划器/优化器

    • 规划器/优化器概述
    • 生成可能的规划
  • 执行器

    执行器规划器/优化器传过来的查询规划然后递归地处理它,抽取所需要的行集合

编辑记录

06/01/2019 Saturday 14:38

你可能感兴趣的:(PostgreSQL,SQL,数据库,增删改查,查询)