3、PostgreSQL之高级特性

PostgreSQL之高级特性

1、视图

之前我们查询过城市的天气情况,假设天气记录和城市位置的组合列表对我们的应用有用,但我们又不想每次需要使用它时都敲入整个查询。我们可以在该查询上创建一个视图,这会给该查询一个名字,我们可以像使用一个普通表一样来使用它:

CREATE VIEW myview ASSELECT city, temp_lo, temp_hi, prcp, date, locationFROM weather, citiesWHERE city = name;SELECT * FROM myview;

对视图的使用是成就一个好的SQL数据库设计的关键方面。视图允许用户通过始终如一的接口封装表的结构细节,这样可以避免表结构随着应用的进化而改变。

视图几乎可以用在任何可以使用表的地方。

2、外键

还是之前查询城市天气的例子,考虑以下问题:我们希望确保在cities表中有相应项之前任何人都不能在weather表中插入行。就是说只有在cities表中已经存在的城市,才能往weather表中插入。这叫做维持数据的引用完整性。为了满足这个特性,我们就要用到 外键

来看看在PostgreSQL中外键怎么使用:

CREATE TABLE cities (city     varchar(80) primary key,location point
);CREATE TABLE weather (city      varchar(80) references cities(city),temp_lo   int,temp_hi   int,prcp      real,date      date
);

现在当我们往weather表中插入一条,cities中不存在的城市的天气情况:

INSERT INTO weather VALUES ('Berkeley', 45, 53, 0.0, '1994-11-28');

那么就会报错:

ERROR:  insert or update on table "weather" violates foreign key constraint "weather_city_fkey"
DETAIL:  Key (city)=(Berkeley) is not present in table "cities".

这里只是简单介绍一下。

3、事务

事务是所有数据库系统的基础概念。**事务最重要的一点是它将多个步骤捆绑成了一个单一的、要么全完成要么全不完成的操作。**步骤之间的中间状态对于其他并发事务是不可见的,并且如果有某些错误发生导致事务不能完成,则其中任何一个步骤都不会对数据库造成影响。

举个例子:

例如,考虑一个保存着多个客户账户余额和支行总存款额的银行数据库。假设我们希望记录一笔从Alice的账户到Bob的账户的额度为100.00美元的转账。

那么完成这个问题的SQL命令就是下面这样(这个代码我们不用过多的去解读,我们只需要知道,要完成这么一个需求,是分了多个步骤去执行的。):

UPDATE accounts SET balance = balance - 100.00WHERE name = 'Alice';
UPDATE branches SET balance = balance - 100.00WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Alice');
UPDATE accounts SET balance = balance + 100.00WHERE name = 'Bob';
UPDATE branches SET balance = balance + 100.00WHERE name = (SELECT branch_name FROM accounts WHERE name = 'Bob');

​ 这种场景,我们是不希望分多个步骤去完成的。因为这很容易出现因为系统错误导致Bob收到100美元而Alice并未被扣款的情况。所以,我们需要一种保障,当操作中途某些错误发生时已经执行的步骤不会产生效果。将这些更新组织成一个事务就可以给我们这种保障。一个事务被称为是原子的从其他事务的角度来看,它要么整个发生要么完全不发生。

​ 我们同样希望能**保证一旦一个事务被数据库系统完成并认可,它就被永久地记录下来且即便其后发生崩溃也不会被丢失。**例如,如果我们正在记录Bob的一次现金提款,我们当然不希望他刚走出银行大门,对他账户的扣款就消失。一个事务型数据库保证一个事务在被报告为完成之前它所做的所有更新都被记录在持久存储(即磁盘)。

​ 事务型数据库的另一个重要性质与原子更新的概念紧密相关:**当多个事务并发运行时,每一个都不能看到其他事务未完成的修改。**例如,如果一个事务正忙着总计所有支行的余额,它不会只包括Alice的支行的扣款而不包括Bob的支行的存款,或者反之。所以事务的全做或全不做并不只体现在它们对数据库的持久影响,也体现在它们发生时的可见性。一个事务所做的更新在它完成之前对于其他事务是不可见的,而之后所有的更新将同时变得可见。

在PostgreSQL中,开启一个事务需要将SQL命令用**BEGIN****COMMIT**命令包围起来。

因此我们的银行事务看起来会是这样:

BEGIN;
UPDATE accounts SET balance = balance - 100.00WHERE name = 'Alice';
-- etc etc
COMMIT;

如果,在事务执行中我们并不想提交(或许是我们注意到Alice的余额不足),我们可以发出**ROLLBACK**命令而不是COMMIT命令,这样所有目前的更新将会被取消。

**PostgreSQL实际上将每一个SQL语句都作为一个事务来执行。**如果我们没有发出BEGIN命令,则每个独立的语句都会被加上一个隐式的BEGIN以及(如果成功)COMMIT来包围它。一组被BEGINCOMMIT包围的语句也被称为一个事务块

**值得注意的是:**某些客户端库会自动发出BEGINCOMMIT命令,因此我们可能会在不被告知的情况下得到事务块的效果。

保存点

可以利用保存点来以更细的粒度来控制一个事务中的语句。**保存点允许我们有选择性地放弃事务的一部分而提交剩下的部分。**在使用**SAVEPOINT**定义一个保存点后,我们可以在必要时利用**ROLLBACK TO**回滚到该保存点。该事务中位于保存点和回滚点之间的数据库修改都会被放弃,但是早于该保存点的修改则会被保存。

在回滚到保存点之后,它的定义依然存在,因此我们可以多次回滚到它。反过来,如果确定不再需要回滚到特定的保存点,它可以被释放以便系统释放一些资源。记住不管是释放保存点还是回滚到保存点都会释放定义在该保存点之后的所有其他保存点。

所有这些都发生在一个事务块内,因此这些对于其他数据库会话都不可见。当提交整个事务块时,被提交的动作将作为一个单元变得对其他会话可见,而被回滚的动作则永远不会变得可见。

又是那个银行数据库,假设我们从Alice的账户扣款100美元,然后存款到Bob的账户,结果直到最后才发现我们应该存到Wally的账户。我们可以通过使用保存点来做这件事:

BEGIN;
UPDATE accounts SET balance = balance - 100.00WHERE name = 'Alice';
SAVEPOINT my_savepoint;
UPDATE accounts SET balance = balance + 100.00WHERE name = 'Bob';
-- oops ... forget that and use Wally's account
ROLLBACK TO my_savepoint;
UPDATE accounts SET balance = balance + 100.00WHERE name = 'Wally';
COMMIT;

ROLLBACK TO是唯一的途径来重新控制一个由于错误被系统置为中断状态的事务块,而不是完全回滚它并重新启动。

4、窗口函数

窗口函数在一系列与当前行有某种关联的表行上执行一种计算。

这个先放一放,我目前不是很明白。

5、继承

继承是面向对象数据库中的概念,我觉得可以理解为Python中的继承吧。

举个例子:

我们创建俩个表:cities和capital。很明显,首都也是城市,也就是说capitals就是cities的子表。那么我们来看看建表的SQL语句:

CREATE TABLE cities (name       text,population real,altitude   int     -- (in ft)
);CREATE TABLE capitals (state      char(2)
) INHERITS (cities);

你要是面向对象学习的好,我觉得这个代码一看就明白什么意思。capitals的行从它的父亲cities继承了所有列(namepopulationaltitude)。

我为什么说它和Python很像呢?因为它也是支持多继承的,也就是说:一个表可以继承0个或者多个表。

小例子:

如果我要查询所有海拔在500米以上的城市名称(包括首都):

SELECT name, altitudeFROM citiesWHERE altitude > 500;

输出:

  name    | altitude
-----------+----------Las Vegas |     2174Mariposa  |     1953Madison   |      845
(3 rows)

ONLY

那么我要是不包含首都呢?

SELECT name, altitudeFROM ONLY citiesWHERE altitude > 500;

输出:

  name    | altitude
-----------+----------Las Vegas |     2174Mariposa  |     1953
(2 rows)

SELECTUPDATEDELETE — 都支持这个ONLY记号。

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

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

相关文章

MySQL为什么使用B+树而不是跳表?

B树的设计能够减少磁盘I/O操作,通过一次磁盘读取获取尽可能多的数据。跳表搜索级别越高,IO的操作越多。 MySQL 使用 B 树而不是跳表主要有以下几个原因: 1. 磁盘读取效率 B 树的设计非常适合磁盘存储。B 树的节点包含多个键值对&#xff0c…

junit mockito Base基类

编写单元测试时我们都习惯性减少重复代码 以下基于spring mvc框架&#xff0c;需要手动pom导包 BaseTest类用于启动上下文进行debug调试 MockBaseTset类用于不启动上下文进行打桩mock pom.xml <dependency><groupId>org.mockito</groupId><artifactId…

Qt解析复杂的csv格式文件

/*csv格式是以逗号分隔列的。 * 每行内容是以换行符作为一行的。 * 如果内容中包含换行符&#xff0c;则整个内容要以双引号括起来。 * 如果内容中包含逗号&#xff0c;则整个内容要以双引号括起来。 * 如果内容中又有双引号&#xff0c;则会是2个双引号连在一起表示一个双引号…

单片机程序设计模式

RTOS:多任务拆分交叉执行 Q:状态机和多任务模式有什么区别 Q:任务创建和任务调度器是什么&#xff1f; 裸机程序的设计模式可以分为&#xff1a;轮询、前后台、定时器驱动、基于状态机。前面三种方 法都无法解决一个问题&#xff1a;假设有 A、B 两个都很耗时的函数&#xf…

从PyTorch官方的一篇教程说开去(2 - 源码)

先上图&#xff0c;上篇文章的运行结果&#xff0c;可以看到&#xff0c;算法在迭代了200来次左右达到人生巅峰&#xff0c;倒立摆金枪不倒&#xff0c;可以扛住连续200次操作。不幸的是&#xff0c;然后就出现了大幅度的回撤&#xff0c;每况愈下&#xff0c;在600次时候居然和…

高性能内存对象缓存

1&#xff1a;数据存储方式与数据过期方式 数据存储方式多种多样&#xff0c;以下为常见的几种&#xff1a; 1.关系型数据库&#xff1a;如 MySQL、Oracle 等&#xff0c;通过表格形式组织数据&#xff0c;具有严格的数据结构和关系约束&#xff0c;适用于结构化数据的存储和管…

设计模式第一天|了解设计模式、设计模式七大原则

文章目录 了解设计模式概念优点核心原则 设计模式七大原则单一职责原则里氏替换原则依赖倒置原则接口隔离原则迪米特法则开闭原则合成复用原则 了解设计模式 概念 软件设计模式(Software Design Patten),又称设计模式,是一套被反复使用,多数人只晓的,经过分类编目的,代码设计…

JVM知识点总结(全网最详细)!!!!

JVM知识总结 运行时数据区域程序计数器Java虚拟机栈局部变量表 StackOverflowError异常和OutOfMemoryError异常本地方法栈Java堆方法区运行时常量池 对象的创建对象的内存分配对象的内存布局对象头实例数据对齐填充 对象的访问定位使用句柄直接指针使用句柄和直接指针的优缺点 …

android11 屏蔽usb通过otg转接口外接鼠标设备

硬件平台&#xff1a;QCS6125 软件平台&#xff1a;Android11 需求&#xff1a;Android设备通过接usb转接线连接鼠标功能屏蔽。 考虑到屏蔽的层面可以从两个层面去做&#xff0c;一个是驱动层面不识别&#xff0c;一个就是Android系统层面不识别加载&#xff0c;本篇只讲后者。…

重置Kafka

重置kafka 1、关闭kafka kill -9 进程号 2、删除元数据 1&#xff09;zk zkCli.sh 2&#xff09;删除预kafka有关的所有信息 ls / rmr /config rmr /brokers 3、删除kafka的数据 所有节点都要删除 rm -rf /usr/local/soft/kafka_2.11-2.0.0/data 4、 重启 kafka-server-sta…

PHP房产中介租房卖房平台微信小程序系统源码

​&#x1f3e0;【租房卖房新选择】揭秘房产中介小程序&#xff0c;一键搞定置业大事&#xff01;&#x1f3e1; &#x1f50d;【开篇&#xff1a;告别繁琐&#xff0c;拥抱便捷】&#x1f50d; 还在为找房子跑断腿&#xff1f;为卖房发愁吗&#xff1f;今天给大家安利一个超…

IPython与Pandas:数据分析的动态组

IPython与Pandas&#xff1a;数据分析的动态组合 前言 欢迎来到"iPython与Pandas&#xff1a;数据分析的动态组合"教程&#xff01;无论你是数据分析新手还是希望提升技能的专业人士&#xff0c;这里都是你开始的地方。让我们开始这段数据分析之旅吧&#xff01; …

【.NET全栈】ASP.NET开发Web应用——AJAX开发技术

文章目录 前言一、ASP.NET AJAX基础1、AJAX技术简介2、ASP.NET AJAX技术架构 二、ASP.NET AJAX服务器端扩展1、声明ScriptManager控件2、使用ScriptManager分发自定义脚本3、在ScriptManager中注册Web服务4、处理ScriptManager中的异常5、编程控制ScriptManager控件6、使用Upda…

如何高效定制视频扩散模型?卡内基梅隆提出VADER:通过奖励梯度进行视频扩散对齐

论文链接&#xff1a;https://arxiv.org/pdf/2407.08737 git链接&#xff1a;https://vader-vid.github.io/ 亮点直击&#xff1a; 引入奖励模型梯度对齐方法&#xff1a;VADER通过利用奖励模型的梯度&#xff0c;对多种视频扩散模型进行调整和对齐&#xff0c;包括文本到视频和…

如何评估 5G 毫米波相控阵天线模块

5G 新无线电 (5G NR) 是空中接口或无线接入网络 (RAN) 技术的行业标准和全球规范。它涵盖 6 GHz 及以下频率&#xff08;称为 FR1&#xff09;和 24 GHz 至 50 GHz 或更高频段&#xff08;称为 FR2 或 mmWave&#xff09;的运行。该技术可用于固定或移动接入、回程和日益流行的…

Flutter 插件之 package_info_plus

当使用Flutter开发应用时,通常需要获取应用程序的基本信息,例如包名、版本号和构建号。Flutter提供了一个名为 package_info_plus 的插件,它能方便地帮助我们获取这些信息。 1. 添加依赖 首先,需要在项目的 pubspec.yaml 文件中添加 package_info_plus 的依赖。打开 pubs…

C语言结构体字节对齐技术详解

C语言结构体字节对齐技术详解&#xff08;第一部分&#xff09; 在C语言中&#xff0c;结构体字节对齐是一个重要的概念&#xff0c;它涉及到内存中数据的布局和访问效率。字节对齐可以帮助提高程序的性能&#xff0c;减少内存碎片&#xff0c;并确保数据的一致性和正确性。本…

一些简单的基本知识(与C基本一致)

一、注释 1.单行注释&#xff1a;//&#xff08;快捷键&#xff1a;ctrlshift&#xff1f;&#xff0c;可以选择多行&#xff09; 2.多行注释&#xff1a;/* 文本 */ 二、变量 变量的作用是给一段内存空间起名&#xff0c;方便操作内存中的数据。 通过赋予某数据的…

逆向案例二十五——webpack所需模块函数很多,某翼云登录参数逆向。

解决步骤&#xff1a; 网址&#xff1a;aHR0cHM6Ly9tLmN0eXVuLmNuL3dhcC9tYWluL2F1dGgvbG9naW4 不说废话&#xff0c;密码有加密&#xff0c;直接搜索找到疑似加密位置打上断点。 再控制台打印&#xff0c;分析加密函数 有三个处理过程&#xff0c;b[g]得到的是用户名,b[f] 对…

【ASP.NET网站传值问题】“object”不包含“GetEnumerator”的公共定义,因此 foreach 语句不能作用于“object”类型的变量等

问题一&#xff1a;不允许遍历 原因&#xff1a;实体未强制转化 后端: ViewData["CateGroupList"] grouplist; 前端加上&#xff1a;var catelist ViewData["CateGroupList"] as List<Catelogue>; 这样就可以遍历catelist了 问题二&#xff1a…