目录
1、psql入门
2、逻辑结构管理
2.1 数据库基本操作
2.2 模式
2.2.1 模式的定义
2.2.2 公共模式
2.2.3 模式的权限
3、表
3.1 创建表
3.2 临时表
3.3 约束
3.4 修改表结构
3.5 表继承
3.6 分区表
4、 触发器
5、表空间
6、视图
7、索引
8、用户及权限管理
8.1 用户和角色
8.2 权限的管理
9、事务、并发、锁
9.1 事务
psql是PostgreSQL中的一个命令行交互式客户端工具
命令以“\”开头,以“;”结尾
//远程连接数据库
psql -h
-p <端口> 【数据库】【用户】 -h:连接数据库所在的主机名或IP地址
-p:连接数据库端口
//登录
psql 【dbname】(连接数据库,默认用户和数据库都是postgres)
psql -U
-d
\l:显示所有数据库
\d:列出数据库中所有表
\d【表名】:显示表结构
\d+:列出更详细的表信息
\dn:列出所有的schema
\db:显示所有的表空间
\du、\dg:列出所有角色或用户
\dp:显示表的权限分配 \?:查看更命令
\timing:显示SQL已执行的时间
\encoding 【gbk/utf8】:指定客户都安的字符编码
\x:把表中每一行的每列数据都拆分为单行显示
\i 【文件名】:执行存储在外部文件中的SQL语句或命令
\echo 【字符串】:输出一行信息
//补全命令
连续按两个tab键表示把命令补全或给出提示输入
//事务操作
在psql中事务是自动提交的,如果不想自动提交,方法有两种:
1、 begin; SQL语句; rollback;或 commit;
2、AUTOCOMMIT off
//打印执行的SQL
psql -E postgres
在启动psql的命令中加“-E”,把psql各种以“\”开头的命令执行的实际SQL打印出来
PostgregSQL数据库系统中,数据的组织结构可以分为以下三层:
数据库(Database):当应用连接到一个数据库时,一般只能访问这个数据库中的数据
表、索引(Table):一个数据库中有很多表、索引
数据行(Tuple):每张表中有很多行数据
//查看数据库
\l
//创建数据库
CREATE DATABASE 【数据库】;
//删除数据库
DROP DATABASE 【IF EXISTS】 【数据库】;
DROP DATABASE 【数据库】;
//选择数据库
\c 【数据库】;
模式(schema):一个命名空间或目录。不同的模式下可以有相同名称的表、函数对象且不冲突。提出模式的概念是为了便于管理,只要有权限,每个模式的对象可以互相调用。
在PostgreSQL中,一个数据库包含一个或多个模式,模式中又包含了表、函数及操作符等数据库对象。
在PostgreSQL中中,不能同时访问不同数据库中的对象,而模式没有此限制。
使用模式有几个主要原因:
1、允许多个用户在使用同一个数据库时彼此互不干扰。
2、把数据库对象放在不同的模式下,然后组织成逻辑组,让它们更便于管理。
3、第三方的应用可以放在不同的模式中,这样就不会和其他对象的名字冲突了。
//创建模式
CREATE SCHEMA 【模式】;
//查看模式
\dn
//删除一个模式
DROP SCHEMA 【模式】;
//在模式中可以修改名称和属主
ALTER SCHEMA 【旧模式名】 RENAME TO 【新模式名】;
ALTER SCHEMA 【旧模式名】 TO 【新属主】;
每当创建一个新的数据库时,PostgresSQL都会自动创建一个名为 “public” 的模式。当登录到该模式时,如果没有特殊的指定。都是以该模式(public)操作各种数据对象的。
默认情况下,用户无法访问模式中不属于他们的对象。若要访问,模式的所有者必须在模式上赋予他们【USAGE】权限。
用户也可以在别人的模式里创建对象,这需要【GREATE】权限。
//创建表
CREATE TABLE 【表名】(
【字段1】 【数据类型】,
【字段2】 【数据类型】,
【字段3】 【数据类型】,
【字段4】 【数据类型】,
);
//定义表的主键:primary key
CREATE TABLE 【表名】(【字段1】【数据类型】 primary key,【字段2】【数据类似】);
//约束子句:主键由两个及以上的字段组成的复合主键
约束子句是放在列定义后面的
CONSTRAINT 【约束名】 PRIMARY KEY(【字段1】,【字段2】,...)
//唯一键:约束的一种
CONSTRAINT 【约束名】 UNIQUE(【字段1】,【字段2】,...)
//check约束:定义某些字段的值必须满足某种要求
CONSTRAINT 【约束名】 CHECK(【约束表达式】);
CREATE TABLE child(name varchar(20),age int,note text,CONSTRAINT ck_child_age CHECK(age<18));
会话级的临时表:数据可以一直保存在整个会话的生命周期中
事务级的临时表:数据只存在于这个事务的生命周期中
当会话结束时,临时表就会消失。
数据类型限制了在表的一个列中存储什么类型的数据。
SQL允许在字段和表上定义约束,约束允许对数据进行任意控制。如果用户企图在字段里存储违反约束的数据,那么就会抛出一个错误。
字段约束:约束语句附在某个字段上
表约束:约束语句在逗号分隔的列表中以一个独立行的形式出现
约束有以下几类:
检查约束
非空约束
唯一约束
主键
外键
检查约束:设置某个字段里的数值时必须使这个约束的表达式的值为真。
当约束表达式的计算结果为NULL时,检查约束会被认为是满足条件的。
//设置age的字段约束,并创建约束名【check_age】
CREATE TABLE persons(
name varchar(40),
age int CONSTRAINT check_age CHECK (age >= 0 and age <= 150),
sex boolean
);
//表约束
CREATE TABLE books(
book_no integer, name text,
price numeric,
discounted_price numeric,
CHECK(price > 0)
CHECK (discounted_price > 0),
CONSTRAINT valid_discount CHECK (price > discounted_price)
);
非空约束:声明一个字段必须不能为NULL
一个非空约束总是被写出一个字段约束,但是创建一个明确的非空约束要更直观一些。
CREATE TABLE books(
book_no integer Not NULL,
name text,
price numeric NOT NULL CHECK (price > 0)
);
唯一约束:保证在一个字段或一组字段里的数据相较于表中其他行的数据是唯一id,
CREATE TABLE books(
book_no integer UNIQUE,
name text, price numeric
);
外键约束:约束本表中一个字段或多个字段的数值必须出现在另一个表的一个字段或多个字段中。
//外键约束【REFERENCES class(class_no)】表明在学生表中“class_no”的取值必须出现在表“class”中,且为“class_no”中的一个数值。
CREATE TABLE class(
class_no int primary key,
class_name varchar(40)
);
CREATE TABLE student(
student_no int primary key,
student_name varchar(40),
age int, class_no int REFERENCES class(class_no)
);
修改表结构:【alter table】
//增加字段
ALTER TABLE 【表名】 ADD COLUMN 【字段名】 【数据类型】 ;
//删除字段(内容和约束都会被删除)
ALTER TABLE 【表名】 DROP COLUMN 【字段】; //删除字段
ALTER TABLE 【表名】 DROP COLUMN 【字段】 CASCADE;//删除字段和外键
//增加字段
ALTER TABLE 【表名】 ADD CHECK 【约束】; //增加约束
ALTER TABLE 【表名】 ALTER COLUMN 【字段】 SET NOT NULL; //增加非空约束
//删除约束
\d 【表名】 //查询约束名称 ALTER TABLE 【表名】 DROP CONSTRAINT 【约束名】; //删除约束
ALTER TABLE 【表名】 ALTER COLUMN 【字段】 DROP NOT NULL; //删除非空约束
//修改默认值
设置默认值的操作不会影响表中现有的任何数据,只是为将来的INSERT命令修改默认值。
ALTER TABLE 【表名】 ALTER COLUMN 【字段】 SET DEFAULT 【默认值】;
//删除默认值(把默认值设置为NULL)
ALTER TABLE 【表名】 ALTER COLUMN 【字段】 DROP DEFAULT;
//修改字段数据类型
在修改某字段类型之前,最好删除这个字段上的约束,修改为后再把合适的约束添加上去。
ALTER TABLE 【表名】ALTER COLUMN 【字段】TYPE【新数据类型】;
//重命名字段
ALTER TABLE 【表名】RENAME COLUMN 【旧字段名】TO【新字段名】;
//重命名表
ALTER TABLE 【旧表名】RENAME TO 【新表名】;
表继承是PostgresSQL中特有的东西
CREATE TABLE persons( //创建父表
name text,
sex boolean,
age int
);
CREATE TABLE student( //创建子表
class_no int
)INHERITS (persons);
当查询父表的时候,会把这个父表中字表的数据也查询出来,反之则不行。
如果想把父表本身的数据查询出来,只需要在查询的表名前加【ONLY】关键字。
SELECT * FROM ONLY persons;
父表的检查约束和非空约束都会自动被所有子表继承。
PostgresSQL是通过表继承来实现分区表的。
表分区就是把逻辑上的一个大表分割成物理上的几个小块,当表的大小超过了数据库服务器的物理内存大小是使用。
在使用继承实现的分区表时,一般会让父表为空,数据都存储在子表中。
步骤:
1、创建“父表”,所有分区都从它继承;
2、创建几个“子表”,每个都从父表上继承的(分区);
3、给分区表增加约束,定义每个分区允许的键值;
4、对于每个分区,在关键字字段上创建一个索引;
5、定义一个规则或者触发器,把对父表的数据插入重定向到合适的分区表;
6、确保constraint_exclusion里的参数postgresql.conf是打开的。
触发器(trigger):由事件自动触发执行的特殊的存储过程;经常用于加强数据完整性约束和业务规则上的约束等。
先为触发器建一个执行函数,此函数的返回类型为触发器类型;然后即可创建相应的触发器。
语句级触发器:执行每个SQL时,只执行一次。语句级的触发器是按语句进行触发的,而不管这条语句实际操作了多少行的数据,即使在没有更新到数据时,也会被触发。
行级触发器:执行每行语句时就会执行一次。如果执行的语句没有更新到实际的行,行触发器就不会被触发。
一个修改零行的操作仍然会导致合适的语句级触发器被执行。
有时我们需要把不同的表放到不同的存储介质或不同的文件系统下,这时就需要使用表空间。表空间实际上是为表指定一个存储的目录,在创建数据库时可以为数据库指定默认的表空间。
//创建表空间
CREATE TABLESPACE 【表空间名】LOCATION 【'表空间路径'】;
//创建数据库时可以指定默认的表空间,这样以后在这个数据库中创建表、索引时,就可以自动存储到这个表空间指定的目录下
CREATE DATABASE 【数据库】TABLESPACE 【表空间】;
//改变一个数据库的默认表空间
改变数据库的默认表空间时,数据库中已有表的表空间并不会改变
ALTER DATABASE 【数据库】SET TABLESPACE【新表空间】;
//把表从一个表空间移动到另一个表空间
在移动表空间时会锁表(阻塞所有操作)
ALTER TABLE 【表】SET TABLESPACE 【新表空间】;
视图:由查询语句定义的虚拟表;用户看到的视图就如同一张真的表;视图大多是只读的。
1、以自然和直观的方式构建数据,并使其易于查找;
2、它限制对数据的访问,使得用户只能看到有限的数据而不是完整的数据;
3、它归总来自各种表中的数据以生成报告。
//创建视图
CREATE VIEW 【视图】 AS SELECT 【原表字段1】,【原表字段2】,【原表字段3】 FROM 【原表名】;
CREATE TABLE users(
id int,
user_name varchar(40),
password varchar(40),
user_email text
);
CREATE VIEW vw_users AS SELECT id,user_name,user_email FROM users;
//创建临时视图(会话结束后消失)
CREATE TEMP VIEW 【视图】 AS SELECT 【原表字段1】,【原表字段2】,【原表字段3】 FROM 【原表名】;
//为查询的各列定义另一个名称
CREATE VIEW 【视图】(【新字段1】,【新字段2】) AS SELECT【原字段1】,【原字段2】 FROM 【表名】;
//删除视图
DROP VIEW 【视图】;
索引:数据库中一种快速查询数据的方法,记录了表中一列或多列的值于其物理位置之间的对应关系。索引类似于书的索引(目录)。索引加快对表中记录的查找或排序。唯一索引还起到唯一约束的作用。
索引的类别:
B-tree:最常用的索引,适合处理等值查询和范围查询
Hash:只能处理简单的等值查询
GiST:不是一种单独的索引类型,而是一种架构,可以在这种架构上实现很多不同的索引策略。
SP-GiST:空间分区GiST索引
GIN:反转索引。支持用户定义的索引策略:包含操作符@>、被包含操作符<@、相等操作符=、重叠操作符&&。
//单列索引(仅在一个表列中创建索引)
CREATE INDEX 【索引】 ON 【表名】 (【字段】);
//多列索引(使用表的多个列创建索引)
CREATE INDEX 【索引】 ON 【表名】 (【字段1】, 【字段2】);
//唯一索引(不允许向表中插入重复的值,或者在原来表中有相同记录的列上也不能创建索引)
CREATE UNIQUE INDEX 【索引】 on 【表名】 (【字段】);
//修改索引名
ALTER INDEX 【旧索引名】RENAME TO 【新索引名】;
//删除索引
DROP INDEX IF EXISTS【索引】;
什么时候应该避免使用索引?
应该避免在小表上使用索引。
不要为具有频繁,大批量更新或插入操作的表创建索引。
索引不应用于包含大量 NULL 值的列。
不要在经常操作(修改)的列上创建索引。
PostgresSQL使用角色的概念管理数据库访问权限。
角色是一系列相关权限的集合,通常会把一系列相关的数据库权限赋给一个角色,如果哪个用户需要这些权限,就把角色赋予给相应的用户。
在Postgres中,用户和角色唯一不同的是, 用户是带有登录权限的,而角色则没有。
//创建用户
CREATE USER 【用户名】 WITH PASSWORD '【密码】'; //指定密码创建数据库
CREATE USER 【用户名】; //不指定密码
//修改密码
\PASSWORD 【用户】;
//查看数据库存在的角色
SELECT rolname FROM pg_roles;
SELECT * FROM pg_authid;
\du
//切换数据库
\c - rolename
在PostgresSQL数据库中,每个数据库的逻辑结构对象(包括数据库)都有一个所有者,所有者默认拥有所有权限。
//创建用户时设定用户属性
CREATE ROLE role_name WITH optional_permissions;
可以通过\h CREATE ROLE指令查看全部可设置的管理权限
//修改用户权限
ALTER ROLE username WITH attribute_options;
//设置权限
GRANT permission_type ON table_name TO role_name;
事务:是对数据库执行的工作单元。事务是以逻辑顺序完成的工作的单位或顺序,无论是用户手动的方式还是通过某种数据库程序自动执行。
事务具有以下四个标准属性,一般是由首字母缩写词ACID简称:
原子性(Atomicity):确保工作单位内的所有操作成功完成; 否则事务将在故障点中止,以前的操作回滚到其以前的状态。
一致性(Consistency):确保数据库在成功提交的事务时正确更改状态。
隔离性(Isolation):使事务能够独立运作并相互透明。
持久性(Durability):确保在系统发生故障的情况下,提交的事务的结果或效果仍然存在。
以下命令用于控制事务:
BEGIN TRANSACTION:开始事务。
COMMIT:保存更改,或者您可以使用END TRANSACTION命令。
ROLLBACK:回滚更改。
事务控制命令仅用于DML命令INSERT,UPDATE和DELETE。 创建表或删除它们时不能使用它们,因为这些操作会在数据库中自动提交。
BEGIN TRANSACTION命令:
可以使用BEGIN TRANSACTION或简单的BEGIN命令来开始事务。 这样的事务通常会持续下去,直到遇到下一个COMMIT或ROLLBACK命令。 但如果数据库关闭或发生错误,则事务也将ROLLBACK。
//开始事务
BEGIN; or BEGIN TRANSACTION;
COMMIT命令
COMMIT命令是用于将事务调用的更改保存到数据库的事务命令。
COMMIT命令自上次的COMMIT或ROLLBACK命令后将所有事务保存到数据库。
//COMMIT命令
COMMIT; or END TRANSACTION;
ROLLBACK命令
ROLLBACK命令是用于还原尚未保存到数据库的事务的事务命令。自上次发出 COMMIT或ROLLBACK命令以来,ROLLBACK命令只能用于撤销事务。
//ROLLBACK命令:
ROLLBACK;