PostgreSQL 数据定义语言 DDL

news2024/11/25 4:59:24

文章目录

  • 表创建
    • 主键约束
    • 非空
    • 唯一约束
    • 检查约束
    • 外键约束
    • 默认值约束
  • 触发器
  • 表空间
    • 构建表空间
  • 视图
  • 索引
    • 索引的基本概念
    • 索引的分类
    • 创建索引
  • 物化视图

表创建

PostgreSQL表的构建语句与所有数据库都一样,结构如下,其核心在于构建表时,要指定上一些约束,例如主键、非空、唯一、检查、外键、默认值等。

CREATE TABLE table_name (  
    column1 datatype,  
    column2 datatype,  
    column3 datatype,  
    ...  
);

主键约束

-- 主键约束
drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32)
);

非空

-- 非空约束
drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32) not null
);

唯一约束

drop table test;
create table test(
    id bigserial primary key ,
    name varchar(32) not null,
    id_card varchar(32) unique
);
insert into test (name,id_card) values ('张三','333333333333333333');
insert into test (name,id_card) values ('李四','333333333333333333');
insert into test (name,id_card) values (NULL,'433333333333333333');

检查约束

-- 检查约束
-- 价格的表,price,discount_price
drop table test;
create table test(
    id bigserial primary key,
    name varchar(32) not null,
    price numeric check(price > 0),
    discount_price numeric check(discount_price > 0),
    check(price >= discount_price)
);
insert into test (name,price,discount_price) values ('粽子',122,12);

外键约束

不用

默认值约束

一般公司内,要求表中除了主键和业务字段之外,必须要有5个字段:created,create_id,updated,update_id,is_delete ,通常可以给这些字段设置默认值。

-- 默认值
create table test(
    id bigserial primary key,
    created timestamp default current_timestamp
);

触发器

触发器Trigger,是由事件出发的一种存储过程,当进行insert,update,delete,truncate操作时,会触发表的Trigger。

这里以学生信息和学生分数为例,在删除学生信息的同时,自动删除学生的分数。

先构建表信息,填充数据

create table student(
    id int,
    name varchar(32)
);
create table score(
    id int,
    student_id int,
    math_score numeric,
    english_score numeric,
    chinese_score numeric
);
insert into student (id,name) values (1,'张三');
insert into student (id,name) values (2,'李四');
insert into
    score
(id,student_id,math_score,english_score,chinese_score)
    values
(1,1,66,66,66);

insert into
    score
(id,student_id,math_score,english_score,chinese_score)
    values
(2,2,55,55,55);

select * from student;
select * from score;

为了完成级联删除的操作,需要编写pl/sql。

先查看一下PGSQL支持的plsql,查看一下PGSQL的plsql语法

[ <<label>> ]
[ DECLARE
    declarations ]
BEGIN
    statements
END [ label ];

触发器函数允许使用一些特殊变量

NEW
数据类型是RECORD;该变量为行级触发器中的INSERT/UPDATE操作保持新数据行。在语句级别的触发器以及DELETE操作,这个变量是null。

OLD
数据类型是RECORD;该变量为行级触发器中的UPDATE/DELETE操作保持新数据行。在语句级别的触发器以及INSERT操作,这个变量是null。

构建一个删除学生分数的函数。

-- 构建一个删除学生分数的触发器函数。
create function trigger_function_delete_student_score() returns trigger as $$
begin
    delete from score where student_id = old.id;
    return old;
end;
$$ language plpgsql;

在学生信息表删除时,执行声明的函数

image.png

CREATE [ OR REPLACE ] [ CONSTRAINT ] TRIGGER name { BEFORE | AFTER | INSTEAD OF } { event [ OR ... ] }
    ON table_name
    [ FROM referenced_table_name ]
    [ NOT DEFERRABLE | [ DEFERRABLE ] [ INITIALLY IMMEDIATE | INITIALLY DEFERRED ] ]
    [ REFERENCING { { OLD | NEW } TABLE [ AS ] transition_relation_name } [ ... ] ]
    [ FOR [ EACH ] { ROW | STATEMENT } ]
    [ WHEN ( condition ) ]
    EXECUTE { FUNCTION | PROCEDURE } function_name ( arguments )

where event can be one of:

    INSERT
    UPDATE [ OF column_name [, ... ] ]
    DELETE
    TRUNCATE

CONSTRAINT选项被指定,这个命令会创建一个 约束触发器 。这和一个常规触发器相同,不过触发该触发器的时机可以使用SET CONSTRAINTS调整。约束触发器必须是表上的 AFTER ROW触发器。它们可以在导致触发器事件的语句末尾被引发或者在包含该语句的事务末尾被引发。在后一种情况中,它们被称作是被 延迟 。一个待处理的延迟触发器的引发也可以使用 SET CONSTRAINTS立即强制发生。当约束触发器实现的约束被违背时,约束触发器应该抛出一个异常。

编写触发器,指定在删除某一行学生信息时,触发当前触发器,执行trigger_function_delete_student_score()函数

create trigger trigger_student 
after 
delete 
on student 
for each row 
execute function trigger_function_delete_student_score();
-- 测试效果
select * from student;
select * from score;
delete from student where id = 1;

表空间

在存储数据时,数据肯定要落到磁盘上,基于构建的tablespace,指定数据存放在磁盘上的物理地址。如果没有自己设计tablespace,PGSQL会自动指定一个位置作为默认的存储点。可以通过一个函数,查看表的物理数据存放在了哪个磁盘路径下。

-- 查询表存储的物理地址
select pg_relation_filepath('student');

image.png

这个位置是在$PG_DATA后的存放地址,41000就是存储数据的物理文件。

$PG_DATA == /var/lib/pgsql/12/data/

构建表空间

image.png
构建表空间,构建表空间需要用户权限是超级管理员,其次需要指定的目录已经存在

create tablespace tp_test location '/var/lib/pgsql/12/tp_test';

image.png

构建数据库,以及表,指定到这个表空间中

image.png

其实指定表空间的存储位置后,PGSQL会在$PG_DATA目录下存储一份,同时在咱们构建tablespace时,指定的路径下也存储一份。

这两个绝对路径下的文件都有存储表中的数据信息。

/var/lib/pgsql/12/data/pg_tblspc/41015/PG_12_201909212/41016/41020
/var/lib/pgsql/12/tp_test/PG_12_201909212/41016/41020

进一步会发现,其实在PGSQL的默认目录下,存储的是一个link,连接文件,类似一个快捷方式

视图

跟MySQL一样,把一些复杂的操作封装起来,还可以隐藏一些敏感数据。

视图对于用户来说,就是一张真实的表,可以直接基于视图查询一张或者多张表的信息。视图对于开发来说,就是一条SQL语句。

image.png

在PGSQL中,简单(单表)的视图是允许写操作的。但是强烈不推荐对视图进行写操作,虽然PGSQL默认允许(简单的视图),写入的时候,其实修改的是表本身。

简单视图

-- 构建一个
create view vw_score as 
(select id,math_score from score);

select * from vw_score;
update vw_score set math_score = 99 where id = 2;

多表视图

-- 复杂视图(两张表关联)
create view vw_student_score as 
(select stu.id as id ,stu.name as name ,score.math_score from student stu,score score where stu.id = score.student_id);

select * from vw_student_score;

update vw_student_score set math_score =999 where id = 2;

image.png

索引

索引的基本概念

索引是数据库中快速查询数据的方法。在提升查询效率的同时,也会带来一些问题:

  • 增加了存储空间
  • 写操作时,花费的时间比较多

索引可以提升效率,甚至还可以给字段做一些约束。

索引的分类

  • B-Tree索引:最常用的索引。

  • Hash索引:跟MySQL类似,做等值判断。

  • GIN索引:针对字段的多个值的类型,比如数组类型。

创建索引

image.png

准备大量测试数据,方便查看索引效果

-- 测试索引效果
create table tb_index(
    id bigserial primary key,
    name varchar(64),
    phone varchar(64)[]
);

-- 添加300W条数据测试效果
do $$
declare
    i int := 0;
begin
    while i < 3000000 loop
        i = i + 1;
        insert into
            tb_index
        (name,phone) 
            values
        (md5(random()::text || current_timestamp::text)::uuid,array[random()::varchar(64),random()::varchar(64)]);
    end loop;
end;
$$ language plpgsql;

在没有索引的情况下,先基于name做等值查询,看时间,同时看执行计划

-- c0064192-1836-b019-c649-b368c2be31ca
select * from tb_index where id = 2222222;
select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
explain select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
-- Seq Scan  代表全表扫描 
-- 时间大致0.3秒左右

在有索引的情况下,再基于name做等值查询,看时间,同时看执行计划

-- name字段构建索引(默认就是b-tree)
create index index_tb_index_name on tb_index(name);
-- 测试效果
select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
explain select * from tb_index where name = 'c0064192-1836-b019-c649-b368c2be31ca';
-- Index Scan 使用索引
-- 0.1s左右

测试GIN索引效果

在没有索引的情况下,基于phone字段做包含查询

-- phone:{0.6925242730781953,0.8569644964711074}
select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
explain select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
-- Seq Scan 全表扫描
-- 0.5s左右

给phone字段构建GIN索引,在查询

-- 给phone字符串数组类型字段构建一个GIN索引
create index index_tb_index_phone_gin on tb_index using gin(phone);
-- 查询
select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
explain select * from tb_index where phone @> array['0.6925242730781953'::varchar(64)];
-- Bitmap Index 位图扫描
-- 0.1s以内完成

物化视图

前面的普通视图,本质就是一个SQL语句,普通的视图并不会在本地磁盘存储,每次查询视图都是执行这个SQL,效率有点问题。

物化视图从名字上就可以看出来,必然是要持久化一份数据的。使用套路和视图基本一致。这样一来查询物化视图,就相当于查询一张单独的表。相比之前的普通视图,物化视图就不需要每次都查询复杂SQL,每次查询的都是真实的物理存储地址中的一份数据(表),并且可以单独设置索引等信息来提升物化视图的查询效率。

但是有好处就有坏处,更新时间不太好把控。 如果更新频繁,对数据库压力也不小。 如果更新不频繁,会造成数据存在延迟问题,实时性就不好了。

如果要更新物化视图,可以采用触发器的形式,当原表中的数据被写后,可以通过触发器执行同步物化视图的操作。或者就基于定时任务去完成物化视图的数据同步。
image.png

-- 构建物化视图
create materialized view mv_test as (select id,name,price from test);
-- 操作物化视图和操作表的方式没啥区别。
select * from mv_test;
-- 操作原表时,对物化视图没任何影响
insert into test values (4,'月饼',50,10);
-- 物化视图的添加操作(不允许写物化视图),会报错
insert into mv_test values (5,'大阅兵',66);

PostgreSQL中,对物化视图的同步,提供了两种方式,一种是全量更新,另一种是增量更新。

全量更新语法,没什么限制,直接执行,全量更新

-- 查询原来物化视图的数据
select * from mv_test;
-- 全量更新物化视图
refresh materialized view mv_test;
-- 再次查询物化视图的数据
select * from mv_test;

增量更新,增量更新需要一个唯一标识,来判断哪些是增量,同时也会有行数据的版本号约束。

-- 查询原来物化视图的数据
select * from mv_test;
-- 给物化视图添加唯一索引。
create unique index index_mv_test on mv_test(id);
-- 增量更新物化视图
refresh materialized view concurrently mv_test;
-- 再次查询物化视图的数据
select * from mv_test;
-- 增量更新时,即便是修改数据,物化视图的同步,也会根据一个xmin和xmax的字段做正常的数据同步

update test set name = '汤圆' where id = 5;
insert into test values (5,'猪头肉',99,40);
select * from test;

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1009643.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

Composition API的优势

1.Options API存在的问题 传统的options api 中&#xff0c;新增或修改一个需求&#xff0c;就需要分别在data,methods,computed里面修改 2.Composition API的优势 我们可以在组织我们的代码&#xff0c;函数。让相关功能的代码更加有序的组织在一起。

openpnp - 设备电源抗干扰部件的选择

文章目录 openpnp - 设备电源抗干扰部件的选择概述END openpnp - 设备电源抗干扰部件的选择 概述 设备电源部分的干扰主要来自伺服和真空泵. 伺服是设备开机期间, 一直供电, 采用滤波器比较好. 型号为 CW4L2-10A-S(004)或者CW4-10A-S(004) CW4L2-10A-S(004)是二级滤波. CW4-1…

Spring的 webFlux 和 webMVC

看到一个测评文章&#xff0c;并发在300的时候webMVC 和 webFlux的处理能力不相上下&#xff0c; 当并发达到3000的时候, webFlux明显优于webMVC, 有图有真相&#xff0c; 我信了. webMVC 是 one-request-one thread 堵塞模式, flux是非阻塞模式&#xff0c; 是spring家族系列…

大神教你期权平仓操作技巧,期权交易规则一网打尽

期权交易主要是看涨开仓和看跌开仓&#xff0c;平仓就是盈亏或亏损平仓。期权的波动较快&#xff0c;所以开仓平仓也一定比较频繁。具体交易和期货的开仓和平仓都是一样的。期货是买涨、卖跌&#xff0c;期权是看涨、看跌。下文介绍期权如何平仓操作&#xff1f;本文来自&#…

系统架构设计师-数据库系统(1)

目录 一、数据库模式 1、集中式数据库 2、分布式数据库 二、数据库设计过程 1、E-R模型 2、概念结构设计 3、逻辑结构设计 三、关系代数 1、并交差 2、投影和选择 3、笛卡尔积 4、自然连接 一、数据库模式 1、集中式数据库 三级模式&#xff1a; &#xff08;1&#xff09;外…

一文讲解ARMv8内存属性与类型(Memory types and attributes)简介

ARMv8中将内存分为两种类型&#xff1a;Normal memory和Device memory&#xff0c;Normal memory适用于系统中的大部分内存&#xff0c;而Device memory则适用于外设所使用的内存。 1. Normal Memory Normal memory类型属性适用于系统中的大多数内存。它表示架构允许硬件对这…

《动手学深度学习 Pytorch版》 4.10 实战Kaggle比赛:预测比赛

4.10.1 下载和缓存数据集 import hashlib import os import tarfile import zipfile import requests#save DATA_HUB dict() DATA_URL http://d2l-data.s3-accelerate.amazonaws.com/def download(name, cache_diros.path.join(.., data)): #save"""下载一个…

湖北建筑行业建安C证交安C证水安C证报考介绍

湖北建筑行业建安C证交安C证水安C证报考介绍 湖北三类人员分为建设厅安全员C证、交通厅安全员C证、水利厅安全员C证&#xff0c;对应着建筑施工行业、公路工程行业、建筑水利行业等等。 湖北建设厅安全员C证&#xff08;建安C&#xff09; 湖北建筑安管考核管理系统-湖北建安…

JUC相关面试题

&#x1f44f;作者简介&#xff1a;大家好&#xff0c;我是爱发博客的嗯哼&#xff0c;爱好Java的小菜鸟 &#x1f525;如果感觉博主的文章还不错的话&#xff0c;请&#x1f44d;三连支持&#x1f44d;一下博主哦 &#x1f4dd;社区论坛&#xff1a;希望大家能加入社区共同进步…

亲测好用-obsidian无法打开插件库安装或更新的解决办法-结合FastGithub

写在前面 经过半年左右时间的使用情况验证该方案稳定可靠。 方案&#xff1a;插件“Plugin Proxy” 软件“FastGithub” 效果&#xff1a; 插件“Plugin Proxy” 下载地址&#xff1a; https://github.com/gslnzfq/obsidian-proxy-server 插件安装&#xff1a; 插件设置为…

虚拟人三维动画宣传片案例分享 | 广州“五羊”城市文化IP商业体裸眼3D广告影片

随着时代的发展元宇宙的助推&#xff0c;裸眼3D形式的宣传方式逐渐出现在大众眼前。以数字人IP的3D立体效果吸引大众目光&#xff0c;让其驻足拍照、录视频分享至社交平台&#xff0c;为企业品牌带来高频传播价值。 近日&#xff0c;广州“五羊”城市文化IP裸眼3D广告宣传片在广…

设计模式解析之模板方法模式:设计灵活可扩展的算法框架

目录 1. 引言2. 概要2.1 概念2.2 结构2.3 类图2.4 工作流程 3. 应用场景3.1 适用情况&#xff1a;3.2 常见例子&#xff1a; 4. 代码衍化过程初版&#xff1a;甲乙学生都抄试卷第二版&#xff1a;提炼代码第三版&#xff1a;抽象出算法骨架第四版&#xff1a;模板方法变化过程总…

视频转gif的几个方法

视频转gif的软件&#xff0c;视频转gif的几个方法~什么是gif图&#xff1f;其实简单一点来说就是一张会动的图片&#xff0c;gif既有图片的属性&#xff0c;也具有视频的特点&#xff0c;因为严格来说gif属于一直图片文件的特殊&#xff0c;但是它的展现方式又和视频非常的像。…

【计算机视觉 | 图像模型】常见的计算机视觉 image model(CNNs Transformers) 的介绍合集(二)

文章目录 一、SqueezeNet二、Inception-v3三、Visual Geometry Group 19 Layer CNN四、MobileNetV1五、Data-efficient Image Transformer六、MobileNetV3七、self-DIstillation with NO labels&#xff08;DINO&#xff09;八、MLP-Mixer九、WideResNet十、Darknet-19十一、HR…

普通项目(java项目)使用lombok报错

java: JPS incremental annotation processing is disabled. Compilation results on partial recompilation may be inaccurate. Use build process "jps.track.ap.dependencies" VM flag to enable/disable incremental annotation processing environment. 解决方…

【ROS】机器人使用Nomachine进行远程控制

官网&#xff1a;NoMachine - Free Remote Desktop for Everybody 支持的系统&#xff1a; WindowsMacLinux 树莓派其他ARM板IOSAndroid 由于网速问题&#xff0c;可以使用我下载好的&#xff1a;&#xff08;8.8.1_1&#xff09; 链接&#xff1a;https://pan.baidu.com/s/…

CSS 修改el-calendar的样式,自定义样式

需求&#xff1a;自定义elementui的日历的样式&#xff1b;给符合条件的时间展示红点。 elementui的原始样式&#xff1a; 目标样式&#xff1a; 代码实现&#xff1a; html: <el-calendar v-model"calendarValue"><template slot"dateCell" …

AI人工智能时代: 大一新生如何入手IT行业?

AI人工智能时代: 大一新生如何入手IT行业? AI人工智能时代: 大一新生如何入手IT行业?引言1. 了解IT行业的基础1.1 什么是IT&#xff1f;1.2 AI是如何改变IT行业的&#xff1f; 2. 如何选择合适的编程语言2.1 常见的编程语言有哪些&#xff1f;2.2 如何选择&#xff1f; 3. 制…

OPCEnum作用OPC常见通讯问题

目录 1 OPCEnum作用 1.1 检索server列表 1.2 检索失败原因 1.3 是否可以没有OPCEnum 2 OPC通讯常见问题 2.1 不能浏览OPCServer列表 2.2不能连接远程OPC Server 2.3 数据显示Bad 2.4 OPC通讯错误码 1 OPCEnum作用 你知道OPCEnum有什么用吗&#xff1f;看完本文你就对O…

Web安全(文件上传的漏洞)

文件上传漏洞和危害 文件上传漏洞是指网络攻击者上传了一个可执行的文件到服务器上&#xff0c;当开发者没有对该文件进行合理的校验及处理的时候&#xff0c;很有可能让程序执行这个上传文件导致安全漏洞。大部分网站都会有文件上传的功能&#xff0c;例如头像、图片、视频等…