pg 数据库

424 阅读28分钟

数据库知识入门

pg 数据库的模式 schema

可以看成是一个数据表的集合,不同的模式中可以存在相同的数据表名, 默认情况下的 schema 是 public

image.png

create schema my_schema;

create table my_schema.test(id int, name varchar(10));

drop table my_schema.test;

drop schema my_schema;

pg 数据库支持创建用户,但是创建用户后需要给用户分配权限

image.png

控制台常用命令总结:

image.png

什么是数据库

数据库是一个长期存储在计算机内的、有组织的、有共享的、统一管理的数据集合。

. 保管数据的仓库

. 数据管理的方法和技术

总结: 是一个计算机软件,用来存储和管理数据的

数据表的概念

是一系列二维数组的集合,纵向的列(字段、属性、列),横向的行(记录、行 )

数据库类型的概念

数据类型决定了数据在计算机中的存储格式和方式

数据库系统的构成

1、数据库

2、数据库管理系统

3、 数据库应用程序

三者之间的关系: 数据库构成之间的关系转存失败,建议直接上传图片文件

SQL 语言

SQL是对数据库进行查询和修改的操作语言

SQL语言包含4个部分:

DDL: DROP、CREATE、ALTER 等语句, 数据库定义语言, 一般用来定义删除 数据库等

DML: INSERT、UPDATE、DELETE 等语句, 数据库操作语言, 一般用来操作数据库

DQL: SELECT 语句, 数据库查询语言, 一般用来查询数据库

DCL: GRANT(授权)、REVOKE(移除权限)、COMMIT、ROLLBACK 等语

数据库控制语言,一般用来授权、撤销授权,分配角色、控制事物提交等

常用的数据库访问技术

1、JDBC:Java 数据库连接,Java 程序通过 JDBC 访问数据库,JDBC 是 Java 语言访问数据库的标准接口,它定义了一组用于执行 SQL 语句并返回结果集的接口。

2、ODBC:Open Database Connectivity,开放数据库连接,ODBC 是一个跨平台数据库接口,它定义了一组用于执行 SQL 语句并返回结果集的接口。

3、PDO:PHP 数据对象,PDO 是 PHP 语言访问数据库的标准接口,它定义了一组用于执行 SQL 语句并返回结果集的接口。

4、ADO.NET:.NET 框架中用于和数据库交互的类库

POSTGREASSQL 历史

image.png

数据库的创建和删除、更新

注意所有的SQL语句都要以 ; 结尾

数据库的创建

create database 数据库名;

如果要添加约束条件

create database 数据库名 with owner = postgres encoding = 'UTF8' connection limit = -1; (-1代表没有限制)

修改数据库

alert database 数据库名 rename to 新数据库名;

如果想修改数据库的其他的信息,只需要指定修改的 参数名 和 修改的名称

删除数据库

 drop database 数据库名;
  • 注意点: 如果删除或更新数据的时候遇到其他地方有活动连接,可以使用一下命令查出数据
 SELECT pid, usename, datname, query 
 FROM pg_stat_activity 
 WHERE datname = '数据库名';

这个命令可以查出是谁在连接数据库

可以通过命令将其杀死

SELECT pg_terminate_backend (pid);

随后再执行删除或更新数据库命令

具体含义: blog.csdn.net/hezuijiudex…

数据表的修改

数据表对象的创建

create table 表名( 列名 数据类型 ,)

 create table student (
    	id int,
    	name varchar(30),
    	birthday date,
    	score numeric(5,2)
       );
  • 注意: 创建表是通过 create table 语句实现的,字段名后面接上类型, 如果有长度的话可以要写在()中

修改数据表的名称

alter table 数据表名 rename to 新表名;
alter table student rename to student1;

修改数据表的字段名称

alter table 数据表名 rename column 旧字段名 to 新字段名;
alter table student1 rename column name to stu_name;

向表中添加字段

alter table 数据表名 add column 字段名称 int;
alter table student1 add column address varchar(200);

删除表中的字段

alter table 数据表名 drop column 字段名称;
alter table student1 drop column birthday;

修改表中数据的类型

alter table 数据表名 alter column 字段名称 type 新类型;
alter table student1 alter column name type varchar(40);

删除一个数据表

drop table 数据表名; // 这种方式如果数据表不存在或则已经被删除,会报错
drop table if exists 数据表名;  // 这种方式会先判断是否存在

操作数据库

create database db_xiao;

create database db_xiao1 with owner = postgres encoding = 'utf-8';

alter database db_xiao1 rename to db_1;

alter database db_xiao2 connection limit 20;

drop database db_xiao;

-- 查询数据的活动连接的pid  
SELECT pid, usename, datname, query 
FROM pg_stat_activity 
WHERE datname = 'db_xiao';

-- 删除数据的连接
SELECT pg_terminate_backend (3185);

操作数据库表

create table student (
    id int,
    name varchar(30),
    birthday date,
    score numeric(5,2)
);

-- 修改表的名称
alter table student rename to student1;

-- 修改表中列的名称
alter table student1 column rename id to bh;

-- 修改数据表中数据的类型
alter table student1 alter column name type varchar(40);

-- 删除一个字段
alter table student1 drop column birthday;

-- 添加一个字段
alter table student1 add column address varchar(200);

-- 删除一个数据表, 这种方式删除,如果数据表不存在或则已经被删除会报错
drop table student1;

-- 可以使用下面的方式删除, 他会先判断数据表是否存在
drop table if exists student1;

postgresql 常用的数据类型介绍

数值类型

image.png

  • 整数类型

SMALLINT // 小范围整数, 取值范围: -32768 ~ 32767

INT // 普通大小整数 -2147483648 ~ 2147483647

bigint

...

  • 浮点数类型

REAL // 6位十进制数字精度

NUMERIC(m, n) // 任意精度类型, 这种类型需要两个参数(5, 2),可以存储的数值长度为5位, 保留两位小数点,注意小数点(.)是不占长度的,在使用 numeric 时,注意如果数值长度超过了数据精度,数据库会进行四舍五入

float

...

日期与时间类型

在 postgresql 中,常用日期类型有:

TIME : 只用于一日内时间, 8个字节, 举例: 10:05:05 , 只记录了时分秒

DATE : 只用于日期, 4个字节, 举例: 2018-01-01 , 只用于日期

TIMESTAMP : 用于日期和时间, 8个字节, 举例: 2018-01-01 10:05:05 , 日期和时间

insert into temp1 values ('10:05:05', '2015-06-02', '2016-09-08 10:49:00');

image.png

字符串类型

CHAR(n) / CHARACTER(n): 固定长度字符串, 不足补空白

VARCHAR(n) / CHARACTER VARYING(n): 可变长度字符串,有长度的限制, 长度不够不会补足空白

TEXT: 不限制长度, 变长字符串

create table temp(
            x smallint,
            y int,
            z real,
            n numeric(5,2)
        );

        insert into temp values (2, 3, 2.55, 6.88);

        alter table temp rename x to a;

        insert into temp values (3, 4, 3.333, 6.998); -- 会四舍五入

        select * from temp;


        create table temp1(
            t time,
            d date,
            tm timestamp
        );

        select * from temp1;

        insert into temp1 values ('10:05:05', '2015-06-02', '2016-09-08 10:49:00');

        create table temp3(
            ch char(10),
            vch varchar(30),
            t text
        );
        insert into temp3 values ('事事如意', '事事顺心', '万事可乐');

        select concat('(', ch ,')') , concat('(', vch , ')'), concat('(', t, ')') from temp3;

image.png

postgreSql 运算符的介绍

算术运算符

加 + 减 - 乘 * 除 / 求余 %

select 3+2, 3-1, 3*8, 4/1, 5%3;

比较运算符

= : 等于

<>(!=) : 不等于

=  : 等于
<>!=) : 不等于
>  : 大于
<  :小于
>=  : 大于等于
<= : 小于等于
LEAST : 在有两个或则多个参数时, 返回最小值
GREATEST : 在有两个或则多个参数时, 返回最大值
BETWEEN AND : 判断一个值是否在两个值之间
IN : 判断一个值是否在指定的值列表中, 也有 not in 这种写法,判断一个数不在一个数中
LIKE : 通配符匹配, 主要用来做一个模糊匹配 , 也有 not like 这种写法

在 postgersql 数据库中 null 值与任何一个数比较都为null , 字符串与字符串比较会默认为字符串比较, 如果一个字符串和一个数字比较, 则会默认将字符串转换为数字进行比较。

select 3+2, 3-1, 3*8, 4/1, 5%3;

select 1= 0, '2'=2, 'b'='b', null = null, null =1;

select 'good'<>'god', 1<>2, 2>1, 4!=4, 2>=1, 1>=1;

select 2 between 1 and 3, 3 between 1 and 6, 2 between 7 and 9;
select 2 in (2,3,4), 3 in (5,6,7), 2 not in (4,5);


-- % 通配符代表 0 - 任意个字符, 下划线通配符通常代表匹配一个字符
select 'abc' like '%a', 'abc' like '_b_', 'abc' not like '%d';

create table times (
    id int primary key,
    time1 time,
    time2 time,
    time3 time
);

insert into times values(1, '10:20:33', '10:20:40', '10:20:50');
select * from times;

-- 使用 greatest(查询数据中最大的值) 和 least(查询数据中最小的值) 方法
select id ,greatest(time1, time2, time3) as maxval, least(time1, time2, time3) as minval from times;

逻辑运算符

NOT (逻辑非) 取反操作:

AND (逻辑与) 并且的关系:

OR (逻辑或)或的关系:

-- 数据库中的 1 和 y 是真, 0 和 n 是假

-- not 操作运算符
select not 'n', not '1', not 'n', not 'y';

-- and 操作运算符 (且的关系)
select '1' and 'y', '1' and '0', '0' and 'n';

-- or 操作运算符 (或的关系)
select '1' or 'y', '1' or '0', '0' or 'n';

运算符的优先级

加上 () 会提升优先级 image.png

PostgreSQL 函数、索引和视图

在工作中我们会经常遇到这些函数, 但并不是只有这些函数,如果需要查看其他方法,可以查找资料

PostgreSQL 常用函数介绍

  • 函数的作用 封装一些方法,方便我们使用

  • 常用的数值函数
    image.png

  • AVG() 返回某列的平均值
  • COUNT() 返回某列的行数
  • MAX() 返回某列的最大值
  • MIN() 返回某列的最小值
  • SUM() 返回某列值的和
 create table employee(
    	id int primary key,
    	gender varchar(6),
    	salary real,
    	hiredate date
    );

    insert into employee values (1, 'female', 2000.11, '2023-01-21');
    insert into employee values (2, 'male', 9000.11, '2023-01-21');
    insert into employee values (3, 'male', 8000.11, '2023-01-21');
    insert into employee values (4, 'female', 1000.11, '2023-01-21');

    select * from employee;

    -- 查询某列的最大值和最小值
    select max(salary), min(salary) from employee;

    -- 返回某列的平均值
    select avg(salary) from employee;

    -- 返回某列的行数
    select count(salary) from employee;

    -- 返回某列值的和
    select sum(salary) from employee;
  • 常用的字符串函数

image.png

  • LENGTH() 返回字符串长度
  • CONCAT(S1, S2, ...) 字符串合并函数
  • LTRIM(S)/ RTRIM(S) / TRIM(S) 去除字符串空格空格函数
  • REPLACE(S, S1, S2) 字符串替换函数
  • SUBSTRING(S, n, LEN) 字符串截取函数, 获取子串函数
  • UPPER(S)/ LOWER(S) 字符串大小写转换函数
create table employee(
    	id int primary key,
    	gender varchar(6),
    	salary real,
    	hiredate date
    );

    insert into employee values (1, 'female', 2000.11, '2023-01-21');
    insert into employee values (2, 'male', 9000.11, '2023-01-21');
    insert into employee values (3, 'male', 8000.11, '2023-01-21');
    insert into employee values (4, 'female', 1000.11, '2023-01-21');

    alter table employee add column name varchar;

    update employee set name = '张三' where id =1;
    update employee set name = '德里不饶' where id =2;
    update employee set name = '张三疯' where id = 3;
    update employee set name = '不回人' where id =4;

    select * from employee;

    -- 查询某列的最大值和最小值
    select max(salary), min(salary) from employee;

    -- 返回某列的平均值
    select avg(salary) from employee;

    -- 返回某列的行数
    select count(salary) from employee;

    -- 返回某列值的和
    select sum(salary) from employee;

    -- 字符串常用函数
    -- length
    select name , length(name) from employee;

    -- concat, 可以将多个字段的值连接到一起展示
    select name, salary, gender, concat(name , salary, gender) from employee;
  • 常用的日期和时间函数

image.png

  • EXTRACT (type FROM d) : 获取日期指定值函数
  • CURRENT_DATE : 获取当前日期函数
  • CURRENT_TIME : 获取当前时间函数
  • NOW() : 获取当前日期和时间函数
-- current_date 当前日期, current_time 当前时间, now 当前日期和时间
    select current_date, current_time, now();

-- extract(type from d) 获取日期中的指定值
    select name, gender, extract(year from hiredate), extract(month from hiredate), 
    extract(day from hiredate) from employee;

PostgreSQL 自定义函数

  • 创建函数的语法

基本语法格式:

CREATE FUNCTION        // 声明创建函数

add(integer, integer)  // 定义函数名称,参数类型

RETURNS integer  // 定义函数返回值类型

AS 'select $1 + $2;'   // 定义函数体

LANGUAGE SQL      // 定义函数使用的语言名字

RETURNS NULL ON NULL INPUT; // 定义参数为null 时处理情况
  • 函数的创建
create function add(integer, integer) returns integer
	as ' select $1 + $2'  -- 函数体, 在函数体中引用参数的形式是用 $, $1 代表第一个参数
language sql
returns null on null input;

select add(1, 2);

create or replace function concat_test(real, varchar, date) returns varchar
	as ' select $1 || $2 || $3;'  -- 在postgresql 数据库中 || 就代表将两个拼接到一起的意思
language sql
returns null on null input; -- 处理为null时的情况

select * from employee;

select concat_test(salary, name, hiredate) from employee;

  • 注意: or replace 的含义是, 如果数据库中存在同名的自定义函数,会进行覆盖

  • 函数的删除

// 删除一个函数的时候要带上这个函数名和函数的参数类型,就是你声明的时候怎样就是怎样

drop function concat_test(real, varchar, date);

PostgreSQL 数据库索引介绍

  • 索引的作用

提高数据的检索速度, 类似于目录的作用,当数据非常大的时候,很有用

  • 索引的分类

    • B-tree索引 : 适合处理那些能够按顺序存储数据
    • Hash 索引: 只能处理简单的等于比较, 性能不是特别好
    • GiST索引: 一种索引架构
    • GIN索引: 反转索引, 处理包含多个值的键,数据表中的某一个列上有一个值是数组类型
  • 索引的创建和删除

    通过 create on 这种语法创建的索引默认是b-tree索引,如果需要其他类型的索引,需要使用其他语法

    • 创建: create index 索引名称 on 表名(列名) -- 在某个表中的某个字段上添加索引
    • 删除: drop index 索引名称;
 -- 创建一个索引
    create index name_index on employee(name); -- 默认是 B-tree索引

-- 删除一个索引
    drop index name_index;
  • 使用索引的优点和缺点
    • 优点: 提高数据的查询速度,加速表与表之间的连接
    • 缺点: 创建和维护索引需要耗费时间,在实际开发中不能过多也不能过少,需要占用磁盘空间

PostgreSQL 数据库视图介绍

  • 视图的含义

    数据库中,视图的作用和表的作用很类似, 视图是从一张表或多张表中导出的数据内容, 数据库中视图是与一张表或多张表相关联的, 但是在数据库中并没有为视图存数据,只是存储了视图的定义, 只有在使用视图的时候,视图内部会去查询关联表中的数据,将查询出来的数据为我们展示

    简单的理解: 就是把查询语句封装成另一个类似表(视图), 后期查询这个表就和得出这个封装的查询语句内容

  • 视图的创建

-- 创建一个视图
  create view v_temp_dev as select name, gender, salary, hiredate from employee where id = 4 order by salary desc;
  
-- 查询视图, 视图和表类似
  select * from v_temp_dev;
  • 视图的删除
drop view v_temp_dev;
  • 视图的作用

    • 简单化

      将复杂的查询语句封装起来,只需要查询视图,不需要再写一堆查询语句。

    • 安全性

      视图可以屏蔽关键的表名等, 比如在和其他公司合作的时候,只需要提供视图,其他公司可以获取数据,但是不能够获取到真实的表名,字段等。

    • 逻辑数据独立性

      当查询逻辑发生该改变的时候,只需要改变视图的结构就行,对于上层的业务系统不需要改变

postgresql 数据库操作和数据表约束介绍

简单数据插入操作

  • 向单表中插入数据

    insert into 数据表名 values ();

  • 向指定字段插入数据

    insert into 数据表名 (字段1, 字段2, 字段3) values ();

 -- 向数据库中添加指定的值
    create table student(
    	id integer,
    	name varchar(10),
    	age integer,
    	sex varchar(2)
    );

    select * from student;

-- 用这种方式插入值要和字段的顺序相对应,否者会插入null值
    insert into student values (1, '张三', 10, '男');
-- 向指定的字段中添加值
    insert into student (id, age, name) values (2, 20, '牛马');

批量数据插入操作

  • 使用 insert into 语句向数据表中批量添加数据,写法和插入一样,在后面写上多个数据组
  -- 批量向数据表中添加数据
    insert into student values (5, '张三', 10, '男'), (6, '张三', 10, '男'),(7, '张三', 10, '男');
    insert into student (id, name, age, sex) values (8, '里斯', 30, '女'),(9, '琼斯', 30, '女');
  • 使用 select 查询批量向数据表中添加数据
  • 注意: 这种方式,查询出来的数据字段一定要在插入表中有字段存在,否者会报错
-- 使用select向表中插入数据,就是通过select查询出数据后再插入表中
create table student_new(
	id integer,
	name varchar(10),
	age integer,
	sex varchar(2)
);
select * from student_new;
delete from  student_new;

-- 向表中添加数据, 将student表中的值查询出来后插入新表
insert into student_new select * from student;
insert into student_new (id, name) select id, name from student;

数据更新操作

语法: update 数据表名 set 字段名 = 值 where 条件;

update student set birthday = '2023-04-09' where name = '张三';

-- 将指定结果更新到对应字段中
update student set age = '50' + 50 where id = 2;

注意: 如果不用where指定条件,则会批量更新数据表中的数据, ⭐️ 这个操作非常危险,⚠️, 使用前注意是否需要

数据删除操作

⚠️ 数据库的删除操作是很危险的,实际操作过程中谨慎使用

  • 数据删除操作
-- 根据条件删除数据
    delete from student where id = 8;
    delete from student where age between 10 and 20; // 可以换成其他的表达式

-- 删除所有的数据
    delete from student;
  • truncate 数据清空操作
truncate table 表名;
  • delete 与 truncate 之间的区别 image.png

pg数据表主键和外键的介绍

主键就是数据表中唯一标识一条记录的主要方式, 主键是唯一值, 不可能重复

  • 如何定义主键约束

两种方式:

1、 在定义的时候直接在字段后面添加 primary key

2、 使用 constraint 定义主键约束

方式一: 列级约束, 不能指定主键的名称
              create table emp(
                  id int primary key,  -- 创建主键的方式 1, 直接在定义的时候写
                  name varchar(10),
                  salary numeric(5,2)
              );
  
方式二: 表级约束, 可以指定主键的名称
    
    create table emp1 (
        id int,
        name varchar(10),
        salary numeric(9, 2),
        constraint 主键名称 primary key(主键字段)
    );

    create table emp1 (
         id int,
         name varchar(10),
         salary numeric(9, 2),
         constraint pk_emp1 primary key(id)
    );
  
  • 如何定义外键约束

⭐️ 注意: 外键创建的时候, 必须先创建被引用的表, 否则会报错

语法: constraint 外键名称 foreign key (外键字段) references 被引用表(被引用字段), 注意这个被引用的表中的字段一定要是主表中的主键

-- 创建外键约束
create table dependent(
	id int primary key,
	name varchar(10)
);

insert into dependent values (1, '测试部');
insert into dependent values (2, '开发部');

select * from dependent;

create table empl3(
	id int primary key,
	name varchar(10),
	salary numeric(9, 2),
	deptId int,
	constraint fk_emp3_dept foreign key (deptId) references dependent(id)
);
insert into empl3 values (1, '张三', 2000, 1);
insert into empl3 values (2, '李四', 3000, 3); -- 会报错, 原表中不存在ID等于3
insert into empl3 values (2, '李四', 3000, 2);
select * from empl3;

⭐️ 注意: 如果删除有外键引用的数据(可以理解为该数据(部门)下有数据)不能随意删除, 会报错

 delete from dependent where id = 1; -- empl3 表中有数据引用了 id = 1 的数据, 所以会报错
  • 主键约束和外键约束的作用
    • 主键约束: 唯一标识一条记录, 提高检索效率
    • 外键约束: 保证数据完整性(不能随意删除主表数据,如果有引用会报错), 提高检索效率

pg数据表非空约束、默认值约束、唯一值约束介绍

  • 如何定义非空约束

  • 如何定义唯一约束

  • 如何定义默认值约束

-- 非空约束
create table emp4 (
	id int primary key,
	name varchar(10) not null,
	salary numeric(9, 2)
);

-- 唯一约束
create table emp5(
	id int,
	name varchar(10) not null,
	phone varchar(11) unique,
	salary numeric(9, 2),
	constraint emp_pk primary key(id)
);

-- 唯一约束和主键的区别: 主键不能为空也是唯一值,并且只有一个, 唯一值可以为空,并且一个表中可以有多个

-- 默认值约束
create table emp6(
	id int,
	name varchar(10) not null,
	phone varchar(11) unique,
	salary numeric(9, 2) default 2000,
	constraint emp_pk2 primary key(id)
);
insert into emp6 values (2, 'zh', '12222222822'); -- 最后的salary 会默认补上 2000
select * from emp6;
  • 非空约束、 唯一约束、 默认值约束的作用
    • 维护数据的完整性 (有些值可能就需要有默认值)
    • 在业务层面保证数据正确性 (有些值不能为空)

数据查询操作

前提条件,初始化数据:

create table dept (
	d_no int primary key, -- 部门编号
	d_name varchar(30), -- 部门名称
	d_location varchar(300) -- 部门地址
);

insert into dept values (10, '开发部', '北京市海淀');
insert into dept values (20, '测试部', '北京市东城');
insert into dept values (30, '销售部', '上海市');
insert into dept values (40, '财务部', '武汉市');
insert into dept values (50, '运维部', '广州市');
insert into dept values (60, '集成部', '南京市');


create table employee(
	e_no int primary key,
	e_name varchar(30) not null,
	e_danger char(2) not null,
	dept_no int, -- 所在部门编号
	e_job varchar(50) not null, 
	e_salary numeric(9, 2),
	e_hireDate date,
	constraint fk_emp_deptno foreign key(dept_no) references dept(d_no)
);

insert into employee values (100, '赵德刚', 'f', 10, '开发工程师', 5000, '2001-01-09');
insert into employee values (101, '大宝', 'f', 10, '开发工程师', 5000, '2004-07-09');
insert into employee values (102, '牛皮鲜', 'f', 10, '开发经理', 5000, '2001-01-09');
insert into employee values (103, '花枝', 'f', 20, '测试工程师', 5000, '2013-01-09');
insert into employee values (104, '的船', 'm', 20, '测试工程师', 5000, '2004-01-09');
insert into employee values (105, '牛二', 'f', 20, '测试经理', 5000, '2001-01-09');
insert into employee values (106, '赵三', 'm', 30, '销售人员', 5000, '2003-01-09');
insert into employee values (107, '马平', 'f', 30, '销售人员', 5000, '2001-01-09');
insert into employee values (108, '刘合', 'm', 30, '销售经理', 5000, '2004-01-09');
insert into employee values (109, '李刚', 'f', 30, '销售高级经理', 5000, '2013-01-09');
insert into employee values (110, '闻中', 'f', 40, '财务人员', 5000, '2013-01-09');
insert into employee values (111, '钱莫', 'm', 40, '财务人员', 5000, '2012-01-09');
insert into employee values (112, '林工', 'f', 40, '财务经理', 5000, '2012-01-09');
insert into employee values (113, '刘川枫', 'f', 10, '实习工程师', null, '2023-05-09');
insert into employee values (114, '秋名山', 'f', null, '实习工程师', null, '2023-06-09');
insert into employee values (115, '爆炸头', 'f', null, '实习工程师', null, '2023-01-09');

简单查询操作

  • sql 查询语言介绍

image.png

  • 简单数据查询操作

  • 为表和字段指定别名

    select * from dept;
    select d_no, d_name, d_location from dept; -- 通过穷举的方式来进行查询
    -- 也可以通过表名.字段名的方式来查询, 在真实查询中,from 后面可能跟了很多的表,通过这种饭方式可以区分
    select dept.d_no, dept.d_name from dept;
    -- 如果表名太长我们可以为他指定别名, 通过 as 来建立别名, 在指定表别名的时候 as 不是必须的,可以省略 
    select d.d_no, d.d_name from dept as d;
    -- 也可以为字段取别名, 通过 as 关键字,as 关键字也可以省略, 取了别名,查询出来的名字也随之改变
    select d.d_no as a, d.d_name b from dept d;

单表指定查询操作

  • 查询指定记录
  • in 关键字查询
  • between and 关键字范围查询
  • like 模糊查询
    -- 查询指定记录
    select e_no, e_name, e_salary from employee where e_salary < 5000;
    select e_no, e_name, e_salary from employee where e_salary = 5000;
    select e_no, e_name, e_salary from employee where e_salary > 5000;

    -- 使用 in 关键字
    select e_no, e_name, dept_no from employee where dept_no in (20, 30);
    select e_no, e_name, dept_no from employee where dept_no not in (20, 30);

    -- between 关键字
    select e_no, e_name, e_salary from employee where e_salary between 5000 and 8000;

    -- like 关键字 % 代表一个或多个字符, _代表一个字符
    select e_name from employee where e_name like '赵%';

单表指定条件复杂查询

    -- 检索 null 值, 在数据库中使用 is null 来检索null 
    select * from employee where e_salary is null;
    -- 也可以使用 is not null 来检索 非null值
    select * from employee where e_salary is not null;

    -- 注意以下写法是错误的,在数据库中 null 不与任何值相等
    select * from employee where e_salary = null;


    -- 使用 and 和 or 实现多条件的查询
    select e_no, e_name, e_danger, dept_no from employee where e_danger = 'f' and dept_no =10;
    select e_no, e_name, e_danger, dept_no from employee where e_danger = 'f' and dept_no in (10, 20);

    select e_no, e_name, e_danger, dept_no from employee where e_danger = 'f' or dept_no =10;

    -- order by 排序操作
    select * from employee order by e_salary; -- 默认是升序 asc
    select * from employee order by e_salary desc;

    -- 以下的含义是,如果第一个排序值是一样的,则按第二个字段排序
    select * from employee order by e_salary, e_hiredate desc;

    -- 注意: 如果我们排序时字段值有null值,数据库默认时 nulls last, 也可以改成 nulls first;
    select * from employee order by e_salary nulls first;

    -- 限制查询条数
    select * from employee limit 5;
    -- 对查询值中间一部分数据感兴趣,可以使用 offset (代表前面忽略多少条数据)用于分页展示操作
    select * from employee limit 5 offset 5; -- 从第6条开始

多表连接查询操作

⭐️ 注意: 内连接查询不会将匹配为null的值查询出来

  • inner join 查询操作
  • left join 查询操作
  • right join 查询操作
    select * from dept;
    select * from employee;

    -- 当我们查询 employee 时,关联的外键,只能看到关联的字段值,不直观

    -- 简单的内连接查询操作,这种方式称为隐式内连接查询
    select e_no, e_name, dept_no, d_no, d_name, d_location from employee, dept where dept_no = d_no;

    -- inner join on 内连接查询操作, 这种方式和上面的查询结果一致, 这种方式称为显示内连接查询
    select e_no, e_name, dept_no, d_no, d_name, d_location from employee
    	inner join dept on dept_no = d_no; 

    -- 以上两种方式不会匹配出为 null 的数据, 如果要查询部门详细信息同时查出为 null 的数据,使用 left join on 
    select e_no, e_name, dept_no, d_no, d_name, d_location from employee
    	left join dept on dept_no = d_no;  
    -- left join on 方式会将左表中匹配和不匹配的都查询出来, 如果不匹配会将右表中的数据展示为 null
    -- left outer join on 和 left join on 作用是一样的,只是写法不同
    select e_no, e_name, dept_no, d_no, d_name, d_location from employee
    	left outer join dept on dept_no = d_no; 
    -- 同时也可以拼接其他的条件
    select e_no, e_name, dept_no, d_no, d_name, d_location from employee
    	left join dept on dept_no = d_no where d_no = 10; 

    -- 右连接查询和左连接查询是一样的

子查询操作

子查询是一个查询语句嵌套在另一个查询语句内部的查询,会将内部的查询叫做子查询,将外部查询叫做主查询, 计算这条查询的时候,数据库会将子查询先执行,然后把结果返回给主查询作为过滤条件,主查询再计算。

还存在其他的子查询操作符, 需查资料

  • exists 子查询操作
  • in 子查询操作
  • 标量子查询操作
select * from employee;
select * from dept;

-- exists 有点像 js 中的 if 判断中的条件
select * from employee where exists (
	select d_no from dept where d_name = '开发部'
);

-- 上面的含义是, 如果()中查询的数据值为 true 那他就会执行外部的查询语句

select * from employee where exists (
	select d_no from dept where d_name = '开发部' and d_no = dept_no
);

-- 上面执行逻辑是前面一部分查询为true后,exists 会将循环查询找到 d_no = dept_no 的数据, 可以使用 not exists
select * from employee where not exists (
	select d_no from dept where d_name = '开发部' and d_no = dept_no
);

-- in 子查询中 in 判断字段值是否在某些固定值中,这里的固定值集合改变成查询语句
select * from employee where dept_no in (
	select d_no from dept where d_name = '开发部'
); -- 会查出所有 dept_no 在 查询出来的 d_no 中的数据

select * from dept;
-- 标量子查询 , || 作用是拼接两个数据
select e_no, e_name, (select d_name || ' ' || d_location from dept
	where dept_no = d_no
	) as address from employee;
-- 标量子查询:将子查询的内容作为查询结果展示

查询结果集合并操作

⭐️ 注意: 在工作中我们要判断是否有有重复的情况,如果评估多表连接没有重复的情况,如果有,那么我们尽量使用 union all 否则尽量使用 union, 同时union和union all 连接的两张表查询结果字段要保持一致,如果不一致会报错(工作中可能会从多张表中查询出数据),如果一张表多出了字段,另一张表没有,我们可以使用 null 占位

  • union all 对查询结果进行合并
  • union 对查询结果进行合并
-- 使用 union all 操作符进行合并操作, 这种方式只是简单的将两条查询语句的结果进行拼接
    select e_no, e_name, dept_no, e_salary from employee where dept_no in (10, 20)
    union all
    select e_no, e_name, dept_no, e_salary from employee where e_salary < 7000;

-- 使用 union 操作符进行合并操作,这种方式可以去重
    select e_no, e_name, dept_no, e_salary from employee where dept_no in (10, 20)
    union
    select e_no, e_name, dept_no, e_salary from employee where e_salary < 7000;
  • 两者的区别
    • union : 可以去重, 查询速度比 union all 慢
    • union all : 不去重, 查询速度比 union 快, 只是简单的将查询的结果拼接在一起

用户权限管理

pg 中没有严格的区分 用户和角色的概念 image.png

创建用户

使用 命令

 create user 用户名称 with password '密码';

注意: 刚创建好的用户是没有权限的,我们需要切换到管理员的用户,一般是 postgres , 我们在进入数据库时候 如果不指定数据库,他默认会找和用户名一样名字的数据库,如果没有会报错

 psql -U 用户名 -d 数据库名

分配权限

1、 先进入管理员用户

数据库授权,赋予指定用户指定数据库的权限

语法:

grant all privileges on database 数据库名 to 用户名;
grant all privileges on database mydb to test;

上面操作执行后,用户还是没有读写数据库的权限,需要给用户授权, 需要进入到指定数据中分配权限

语法:

grant all privileges on all tables in schema 模式 to 用户名;
grant all privileges on all tables in schema public to test;

REVOKE ALL PRIVILEGES ON TABLE table_name FROM role_name; (单个表权限)

通过以上不的步骤,test 用户就可以读写数据库了, 但是并没有其他的权限, 如果要有创建或则删除数据库或表的能力需要分配角色

  • 删除用户和移除权限都要在管理员用户下操作

    • 删除用户: drop user 用户名; -- 在删除前需要将分配的权限移除(需要在分配的数据库下操作)
    • 移除权限: revoke all privileges on database 数据库名 from test;

分配角色

 语法: alter role 用户名/角色名 with 角色属性;

如果要修改角色的属性,需要使用 alter role 角色名 with 角色属性; (同理用户也可以这样) image.png

  • pg 数据库中没有严格区分用户和角色的概念, 有一点注意,创建的角色是不具备登录的, 创建的用户是可以登录的
  • 创建角色
语法: create role 角色名;
  • 查询角色和用户
-- 查询角色
  select * from pg_roles;
-- 查询用户
  select * from pg_user;

删除角色和用户

⭐️ 注意: 删除角色和用户的时候, 一定要将该角色或用户身上绑定过的权限移除(包括一些属性、创建的表等), 否则会报错

    // 语法
    drop role 角色名;
    drop user 用户名;