PGSQL学习

PGSQL数据类型

数值类型

类型名称

存储尺寸

描述

范围

smallint

2字节

小整形

-32768至+32767

integer

4字节

整形

-2147483648至+214783647

bigint

8字节

长整型

-9223372036854775808至+9223372036854775807

decimal

变长

用户指定精度,精确

小数点前131072位,到小数点后16383位

numeric

变长

用户指定精度,精确

小数点前131072位,到小数点后16383位

real

4字节

可变精度,不精确

6位十进制精度

double precision

8字节

可变精度,不精确

15位十进制精度

smallserial

2字节

小范围自增整数

1至32767

serial

4字节

自增整数

1至2147483647

bigserial

8字节

大范围自增整数

1至9223372036854775807

字符类型

类型

描述

character varying(n), varchar(n)

变长字符串,最大1GB

character(n), char(n)

定长字符串,不足位空格补齐

text

变长字符串,无长度限制

二进制类型

类型

存储空间

描述

bytea

1或4字节加实际长度

变成二进制值

时间类型

类型

存储空间

描述

最小值

最大值

间隔

timestamp[§] [without time zone]

8字节

不带时区的日期时间

4713 BC

294276 AD

1毫秒

timestamp[§] with time zone

8字节

带时区的日期时间

4713 BC

294276 AD

1毫秒

date

4字节

不带时间的日期

4713 BC

5874897 AD

1天

time[§] [without time zone]

8字节

不带时区的时间

00:00:00

24:00:00

1毫秒

time[§] with time zone

12字节

带时区的时间

00:00:00+1459

24:00:00-1459

1毫秒

interval[fields] [§]

16字节

时间间隔

-178000000 years

178000000 years

1毫秒

布尔值类型

类型

存储空间

描述

boolean

1字节

布尔值,真或假

可用值:

true

false

TRUE

FALSE

‘t’

‘f’

‘true’

‘false’

‘y’

‘n’

‘yes’

‘no’

‘on’

‘off’

‘1’

‘0’

金额类型

类型名称

存储尺寸

描述

范围

money

8 bytes

currency amount

-92233720368547758.08至+92233720368547758.07

网络地址类型

类型

存储空间

描述

cidr

7或19字节

IPv4/IPv6网络地址

inet

7或19字节

IPv4/IPv6网络地址、支持位数表示的掩码

macaddr

6字节

MAC物理地址

macaddr8

8字节

MAC物理地址(EUI-64格式)

几何类型

类型

存储空间

描述

数值表示方法

point

16 bytes


(x, y)

line

32 bytes

无限长的线

(A, B, C)或[(x1, y1), (x2, y2)]

lseg

32 bytes

有限长线段

((x1, y1), (x2, y2))

box

32 bytes

矩形

((x1, y1), (x2, y2))

path

16+16n bytes

封闭路径

((x1, y1), …)

path

16+16n bytes

开放路径

((x1, y1), …)

polygon

40+16n bytes

多边形

((x1, y1), …)

circle

24 bytes


<(x, y), r>(圆心位置和半径)

文档类型

类型

描述

XML

XML文档

json

原文本存储的JSON文档

jsonb

经过分解的二进制方式存储的JSON文档

数组类型

• PostgreSQL允许在各种内置的或者用户自定义的数据类型基础上创建数组类型

• 数组类型的定义是通过在数组元素类型后面添加中括号“[ ]”来实现的

• 多维数组就是使用多对中括号“[ ]”,但实际上是否为多维是取决于数据而不取决于有多少对[],所以[]与[][]的效果是一样的

范围类型

类型

描述

int4range

整形范围

int8range

长整型范围

numrange

数值范围

tsrange

时间戳范围

tstzrange

带时区时间戳范围

daterange

日期范围

PGSQL基本语法

表操作

CREATE TABLE COMPANY(
ID INT PRIMARY KEY NOT NULL ,  
NAME TEXT NOT NULL,  
AGE INT NOT NULL,   
ADDRESS CHAR(50),   
SALARY REAL,   
LOCATION point
);

# 删除表
drop table if exists company;

drop table if exists weather;

CREATE TABLE cities (
    city_id          varchar(10),
    name            varchar(80),
    location        point
);

INSERT INTO cities VALUES ('xa','西安', '(-194.0, 53.0)');

UPDATE cities SET NAME='西安市', LOCATION='(-196.12,63.22)' WHERE CITY_ID ='xa';

DELTE FROM cities WHERE CITY_ID =’xa’;

模式(SCHEMA)

PostgreSQL 模式(SCHEMA)可以看着是一个表的集合。

一个模式可以包含视图、索引、数据类型、函数和操作符等。

相同的对象名称可以被用于不同的模式中而不会出现冲突,例如 schema1 和 myschema 都可以包含名为 mytable 的表。

CREATE SCHEMA myschema.mytable (
...
);

# 创建一个模式,并模式下创建一个表格
create schema myschema;
create table myschema.company(
   ID   INT              NOT NULL,
   NAME VARCHAR (20)     NOT NULL,
   AGE  INT              NOT NULL,
   ADDRESS  CHAR (25),
   SALARY   DECIMAL (18, 2),
   PRIMARY KEY (ID)
);

# 查看表格
select * from myschema.company;

# 删除一个为空的模式(其中的所有对象已经被删除)
drop schema myschema;

# 删除一个模式以及其中包含的所有对象(cascade 层叠/大量)
drop schema myschema cascade;

CRUD

# 插入语句 JOIN_DATE 字段使用 DEFAULT 子句来设置默认值
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (3, 'Teddy', 23, 'Norway', 20000.00, DEFAULT );

# 插入多行数据
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY,JOIN_DATE) VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00, '2007-12-13' ), (5, 'David', 27, 'Texas', 85000.00, '2007-12-13');

# 查询
select * from company;
SELECT (17 + 6) AS ADDITION;
SELECT COUNT(*) AS "RECORDS" FROM COMPANY;
SELECT CURRENT_TIMESTAMP;

# 子查询
SELECT AGE FROM COMPANY WHERE EXISTS (SELECT AGE FROM COMPANY WHERE SALARY > 65000);

# 更新
UPDATE COMPANY SET SALARY = 15000 WHERE ID = 3;
UPDATE COMPANY SET ADDRESS = 'Texas', SALARY=20000;

# 删除
DELETE FROM COMPANY WHERE ID = 2;

聚合操作

SELECT column1, column2
FROM table1, table2
WHERE [ conditions ]
GROUP BY column1, column2
HAVING [ conditions ]
ORDER BY column1, column2

# like  将整型数据类型转化为字符串数据类型,再模糊搜索
SELECT * FROM COMPANY WHERE AGE::text LIKE '2%';

# limit 从第三位开始提取3个记录
SELECT * FROM COMPANY LIMIT 4;
SELECT * FROM COMPANY LIMIT 3 OFFSET 2;

# GROUP BY 在一个 SELECT 语句中,放在 WHRER 子句的后面,ORDER BY 子句的前面。
SELECT NAME, SUM(SALARY) FROM COMPANY GROUP BY NAME ORDER BY NAME DESC;

# HAVING 子句可以让我们筛选分组后的各组数据。
SELECT NAME FROM COMPANY GROUP BY name HAVING count(name) < 2;

# DISTINCT 关键字与 SELECT 语句一起使用,用于去除重复记录,只获取唯一的记录。
SELECT DISTINCT name FROM COMPANY;

WITH子句

在 PostgreSQL 中,WITH 子句提供了一种编写辅助语句的方法,以便在更大的查询中使用;

WITH 子句有助于将复杂的大型查询分解为更简单的表单,便于阅读。这些语句通常称为通用表表达式(Common Table Express, CTE),也可以当做一个为查询而存在的临时表;

WITH 子句是在多次执行子查询时特别有用,允许我们在查询中通过它的名称(可能是多次)引用它;WITH 子句在使用前必须先定义;

语法:name_for_summary_data 是 WITH 子句的名称,name_for_summary_data 可以与现有的表名相同,并且具有优先级。

可以在 WITH 中使用数据 INSERT, UPDATE 或 DELETE 语句,允许您在同一个查询中执行多个不同的操作。

# 1导入数据
DROP TABLE COMPANY;
CREATE TABLE COMPANY(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);

INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (1, 'Paul', 32, 'California', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (2, 'Allen', 25, 'Texas', 15000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (3, 'Teddy', 23, 'Norway', 20000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (4, 'Mark', 25, 'Rich-Mond ', 65000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (5, 'David', 27, 'Texas', 85000.00 );
INSERT INTO COMPANY (ID,NAME,AGE,ADDRESS,SALARY) VALUES (6, 'Kim', 22, 'South-Hall', 45000.00 );
INSERT INTO COMPANY VALUES (7, 'James', 24, 'Houston', 10000.00 );

# 2使用 WITH 子句在上表中查询数据:
With CTE AS
(Select
 ID
, NAME
, AGE
, ADDRESS
, SALARY
FROM COMPANY )
Select * From CTE;

# 3使用 RECURSIVE 关键字和 WITH 子句编写一个查询,查找 SALARY(工资) 字段小于 20000 的数据并计算它们的和
WITH RECURSIVE t(salary) AS (
   VALUES (0)
   UNION ALL
   SELECT SALARY FROM COMPANY WHERE SALARY < 20000
)
SELECT sum(salary) FROM t;

# 4我们建立一张和 COMPANY 表相似的 COMPANY1 表,使用 DELETE 语句和 WITH 子句删除 COMPANY 
#表中 SALARY(工资) 字段大于等于 30000 的数据,并将删除的数据插入 COMPANY1 表,实现将 COMPANY 
#表数据转移到 COMPANY1 表中

CREATE TABLE COMPANY1(
   ID INT PRIMARY KEY     NOT NULL,
   NAME           TEXT    NOT NULL,
   AGE            INT     NOT NULL,
   ADDRESS        CHAR(50),
   SALARY         REAL
);


WITH moved_rows AS (
   DELETE FROM COMPANY
   WHERE
      salary >= 30000
   RETURNING *
)
INSERT INTO COMPANY1 (SELECT * FROM moved_rows);

union, except, intersect

并集: union会移除所有重复的行,要保留重复的行,需要使用 union all
     select name ,age, address,salary from COMPANY  where (salary > 10000)
union
      select name ,age, address,salary from COMPANY1  where (salary > 10000)

差集:except返回在第一张表出现,但在第二张表不存在的记录,两张表查询有先后顺序之别
     select name ,age, address,salary from COMPANY  where (salary > 10000)
except
      select name ,age, address,salary from COMPANY  where (age > 30)

交集:intersect返回既,又两种条件
     select name ,age, address,salary from COMPANY  where (salary > 10000)
intersect
      select name ,age, address,salary from COMPANY  where (age > 20)

级联查询

内连接:inner Join

select co1.* from company co1 inner join  company1 co2 on  co1.id =  co2.id;

select co1.* from  company co1, company1 co2 where  co1.id =  co2.id;


外连接: left join , right join 
   
左连接:
          select co1.* from company co1 left join  company1 co2 on  co1.id =  co2.id;
          
          select co1.* from  company co1, company1 co2 where  co1.id =  co2.id(+);

右连接:
          select co2.* from company co1 right join  company1 co2 on  co1.id =  co2.id;
          
          select co2.* from  company co1, company1 co2 where  co1.id(+) =  co2.id;

PGSQL查看执行计划

1.使用explain命令查看执行计划;

2.客户端点击查看执行计划;

执行计划是从下往上读的

explain报告查询的操作,开启的消耗,查询总的消耗,访问的行数 访问的平均宽度

开启时间消耗是输出开始前的时间例如排序的时间

消耗包括磁盘检索页,cpu时间

注意,每一步的cost包括上一步的,重要的是,explain 不一定是真正的执行一次查询 只是得到查询执行的计划和估计的花费