当前位置: 首页 > news >正文

PostgreSQL 数据定义语言 DDL

文章目录

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

表创建

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 intoscore
(id,student_id,math_score,english_score,chinese_score)values
(1,1,66,66,66);insert intoscore
(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>> ]
[ DECLAREdeclarations ]
BEGINstatements
END [ label ];

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

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

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

-- 构建一个删除学生分数的触发器函数。
create function trigger_function_delete_student_score() returns trigger as $$
begindelete 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:INSERTUPDATE [ OF column_name [, ... ] ]DELETETRUNCATE

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 $$
declarei int := 0;
beginwhile i < 3000000 loopi = i + 1;insert intotb_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;

相关文章:

PostgreSQL 数据定义语言 DDL

文章目录 表创建主键约束非空唯一约束检查约束外键约束默认值约束 触发器表空间构建表空间 视图索引索引的基本概念索引的分类创建索引 物化视图 表创建 PostgreSQL表的构建语句与所有数据库都一样&#xff0c;结构如下&#xff0c;其核心在于构建表时&#xff0c;要指定上一些…...

设计模式-行为型模式-策略模式

一、什么是策略模式 策略模式是一种行为设计模式&#xff0c;它允许在运行时选择算法或行为&#xff0c;并将其封装成独立的对象&#xff0c;使得这些算法或行为可以相互替换&#xff0c;而不影响使用它们的客户端。&#xff08;ChatGPT生成&#xff09; 主要组成部分&#xff…...

ResizeObserver观察元素宽度的变化

ResizeObserver观察元素宽度的变化 ResizeObserver观察元素宽度的变化 ResizeObserver观察元素宽度的变化 ResizeObserver 构造函数创建一个新的 ResizeObserver 对象&#xff0c;它可以用于监听 Element 内容盒或边框盒或者 SVGElement 边界尺寸的大小。查看详细说明 案例 &l…...

斐波那契数列,剑指offer,力扣

目录 题目地址&#xff1a; 我们直接看题解吧&#xff1a; 解题方法&#xff1a; 难度分析&#xff1a; 审题目事例提示&#xff1a; 解题思路&#xff08;动态规划&#xff09;&#xff1a; 代码实现&#xff1a; 补充说明&#xff1a; 代码&#xff08;优化&#xff09;&…...

Mac安装CocoaPods

安装HomeBrew 安装 % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"安装失败 % /bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"curl: (28) F…...

APP专项测试方法和工具的使用(测试新手必看)

APP专项测试 1、网络测试 可使用抓包工具辅助网格测试推荐&#xff1a;fiddler&#xff0c;Charles &#xff08;1&#xff09;网络切换2G-3G-4G-wifi-网络信号差--无网&#xff08;2&#xff09;网络信号弱关注是否出现ANR、crash 2、中断测试 &#xff08;1&#xff09;…...

WordPress网站迁移实战经验

前几日,网站服务器到期,换了服务商,就把我的WordPress的网站迁移到本地电脑了。方便以后文章迁移。 本次迁移网站主要经历以下几个步骤。 1.域名转出。 2.备份数据库及网站文件下载。 3.重新搭建WordPress网站。 4.网站文件及数据库导入。 下面详细介绍下每个步骤的操作…...

3D全景视角,足不出户感知真实场景的魅力

近年来&#xff0c;随着科技的快速发展&#xff0c;普通的平面静态视角已经无法满足我们了&#xff0c;不管是视角框架的限制还是片面的环境展示&#xff0c;都不足以让我们深入了解场景环境。随着VR全景技术的日益成熟&#xff0c;3D全景技术的出现为我们提供了全新的视觉体验…...

C编译环境和预处理(非常详细,建议收藏)

C编译环境和预处理&#xff08;非常详细&#xff0c;建议收藏&#xff09; 一、程序的翻译环境和执行环境二、 详解编译链接2.1 翻译环境2.2 编译本身的几个阶段符号汇总、符号表、合并段表、符号表的合并和重定位分别是什么&#xff1f; 2.2 运行环境 三、预处理详解3.1 预定义…...

LeetCode669. Trim a Binary Search Tree

文章目录 一、题目二、题解 一、题目 Given the root of a binary search tree and the lowest and highest boundaries as low and high, trim the tree so that all its elements lies in [low, high]. Trimming the tree should not change the relative structure of the …...

YOLOv8优化策略:轻量级Backbone改进 | VanillaNet极简神经网络模型 | 华为诺亚2023

🚀🚀🚀本文改进:一种极简的神经网络模型 VanillaNet,支持vanillanet_5, vanillanet_6, vanillanet_7, vanillanet_8, vanillanet_9, vanillanet_10, vanillanet_11等版本 🚀🚀🚀YOLOv8改进专栏:http://t.csdnimg.cn/hGhVK 学姐带你学习YOLOv8,从入门到创新,…...

【数据结构(二)】稀疏 sparsearray 数组(1)

文章目录 1. 稀疏数组的应用场景1.1. 一个实际的需求1.2. 基本介绍 2. 稀疏数组转换的思路分析3. 稀疏数组的代码实现3.1. 二维数组转稀疏数组3.2. 稀疏数组转二维数组 4. 课后练习 1. 稀疏数组的应用场景 1.1. 一个实际的需求 问题&#xff1a;     编写的五子棋程序中&…...

MySQL的执行器是怎么工作的

作为优化器后的真正执行语句的层&#xff0c;执行器有三种方式和存储引擎&#xff08;一般是innoDB&#xff09;交互 主键索引查询 查询的条件用到了主键&#xff0c;这个是全表唯一的&#xff0c;优化器会选择const类型来查询&#xff0c;然后while循环去根据主键索引的B树结…...

【目标测距】雷达投影测距

文章目录 前言一、读取点云二、点云投影图片三、读取检测信息四、点云投影测距五、学习交流 前言 雷达点云投影相机。图片目标检测&#xff0c;通过检测框约束等等对目标赋予距离。计算消耗较大&#xff0c;适合离线验证操作。在线操作可以只投影雷达检测框。 一、读取点云 py…...

uniapp、小程序canvas相关

1、圆形or圆形头像 //示例 const ctx uni.createCanvasContext(myCanvas); //canvas const round uni.upx2px(72) / 2; // 半径 const x uni.upx2px(92); //目标x轴位置 const y uni.upx2px(236); //目标y轴位置//if 图片是不是静态资源 async > const imgSrc https:/…...

[工业自动化-23]:西门子S7-15xxx编程 - 软件编程 - 西门子PLC人机界面交互HMI功能概述、硬件环境准备、软件环境准备

目录 一、什么是人机界面 二、什么是PLC人机交互界面HMI 三、人机界面设计的功能列表 四、开发主机与PLC的连接方式 五、开发主机与HMI的连接方式 六、HMI组态 一、什么是人机界面 人机界面是指人与机器或系统之间的交互界面。它是人类与计算机或其他设备之间进行信息交换…...

在Ubuntu系统中安装VNC并结合内网穿透实现公网远程访问

&#x1f337;&#x1f341; 博主猫头虎&#xff08;&#x1f405;&#x1f43e;&#xff09;带您 Go to New World✨&#x1f341; &#x1f984; 博客首页——&#x1f405;&#x1f43e;猫头虎的博客&#x1f390; &#x1f433; 《面试题大全专栏》 &#x1f995; 文章图文…...

java基础练习缺少项目?看这篇文章就够了(上)!

公众号&#xff1a;全干开发 。 专注分享简洁但高质量的动图技术文章&#xff01; 项目概述 本教程适合刚学习完java基础语法的同学&#xff0c;涉及if语句、循环语句、类的封装、集合等基础概念&#xff0c;使用大量gif图帮助读者演示代码操作、效果等&#xff0c;是一个非常…...

鸿蒙为什么使用typescript 作为开发语言 而不是 flutter 或者 kotlin

猜想如下 dev studio 是基于 idea 二次开发的 &#xff0c;使用kotlin 应该是更合理 变成 jetbrain 全家桶&#xff0c; 但是 现在android 开发也是kotlin 是不是为了做分割 &#xff0c;所以不使用kotlin flutter 是谷歌的 安卓也是谷歌的 所以不采用 typescript 是微软的…...

Flutter NestedScrollView 、SliverAppBar全解析,悬浮菜单的应用

在我们开发过程中经常会使用到悬浮菜单的使用&#xff0c;当我们滑动到指定位置后&#xff0c;菜单会自动悬浮。 实现效果如下&#xff08;左为滑动前、右为滑动后&#xff09;&#xff1a; 上述便是通过NestedScrollView 、SliverAppBar实现的效果&#xff0c;通过两个控件我…...

浅谈 React Hooks

React Hooks 是 React 16.8 引入的一组 API&#xff0c;用于在函数组件中使用 state 和其他 React 特性&#xff08;例如生命周期方法、context 等&#xff09;。Hooks 通过简洁的函数接口&#xff0c;解决了状态与 UI 的高度解耦&#xff0c;通过函数式编程范式实现更灵活 Rea…...

springboot 百货中心供应链管理系统小程序

一、前言 随着我国经济迅速发展&#xff0c;人们对手机的需求越来越大&#xff0c;各种手机软件也都在被广泛应用&#xff0c;但是对于手机进行数据信息管理&#xff0c;对于手机的各种软件也是备受用户的喜爱&#xff0c;百货中心供应链管理系统被用户普遍使用&#xff0c;为方…...

在rocky linux 9.5上在线安装 docker

前面是指南&#xff0c;后面是日志 sudo dnf config-manager --add-repo https://download.docker.com/linux/centos/docker-ce.repo sudo dnf install docker-ce docker-ce-cli containerd.io -y docker version sudo systemctl start docker sudo systemctl status docker …...

JVM垃圾回收机制全解析

Java虚拟机&#xff08;JVM&#xff09;中的垃圾收集器&#xff08;Garbage Collector&#xff0c;简称GC&#xff09;是用于自动管理内存的机制。它负责识别和清除不再被程序使用的对象&#xff0c;从而释放内存空间&#xff0c;避免内存泄漏和内存溢出等问题。垃圾收集器在Ja…...

uniapp微信小程序视频实时流+pc端预览方案

方案类型技术实现是否免费优点缺点适用场景延迟范围开发复杂度​WebSocket图片帧​定时拍照Base64传输✅ 完全免费无需服务器 纯前端实现高延迟高流量 帧率极低个人demo测试 超低频监控500ms-2s⭐⭐​RTMP推流​TRTC/即构SDK推流❌ 付费方案 &#xff08;部分有免费额度&#x…...

三体问题详解

从物理学角度&#xff0c;三体问题之所以不稳定&#xff0c;是因为三个天体在万有引力作用下相互作用&#xff0c;形成一个非线性耦合系统。我们可以从牛顿经典力学出发&#xff0c;列出具体的运动方程&#xff0c;并说明为何这个系统本质上是混沌的&#xff0c;无法得到一般解…...

Unit 1 深度强化学习简介

Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库&#xff0c;例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体&#xff0c;比如 SnowballFight、Huggy the Do…...

Element Plus 表单(el-form)中关于正整数输入的校验规则

目录 1 单个正整数输入1.1 模板1.2 校验规则 2 两个正整数输入&#xff08;联动&#xff09;2.1 模板2.2 校验规则2.3 CSS 1 单个正整数输入 1.1 模板 <el-formref"formRef":model"formData":rules"formRules"label-width"150px"…...

企业如何增强终端安全?

在数字化转型加速的今天&#xff0c;企业的业务运行越来越依赖于终端设备。从员工的笔记本电脑、智能手机&#xff0c;到工厂里的物联网设备、智能传感器&#xff0c;这些终端构成了企业与外部世界连接的 “神经末梢”。然而&#xff0c;随着远程办公的常态化和设备接入的爆炸式…...

零基础在实践中学习网络安全-皮卡丘靶场(第九期-Unsafe Fileupload模块)(yakit方式)

本期内容并不是很难&#xff0c;相信大家会学的很愉快&#xff0c;当然对于有后端基础的朋友来说&#xff0c;本期内容更加容易了解&#xff0c;当然没有基础的也别担心&#xff0c;本期内容会详细解释有关内容 本期用到的软件&#xff1a;yakit&#xff08;因为经过之前好多期…...