3、PostgreSQL之高级特性

news/2024/10/18 6:02:38/

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.ppmy.cn/news/1476852.html

相关文章

【LeetCode】80.删除有序数组中的重复项II

1. 题目 2. 分析 3. 代码 class Solution:def removeDuplicates(self, nums: List[int]) -> int:if len(nums) < 3:return len(nums)i 0j 1k 2while(k < len(nums)):if (nums[i] nums[j]):while(k < len(nums) and nums[j] nums[k] ):k1if (k < len(nums…

Vue的依赖注入:组件树中的共享数据与功能

引言 在构建大型前端应用时,组件间的通信和状态共享是一个常见问题。Vue.js 提供了一种类似于 React 的 Context 机制的依赖注入系统,允许开发者在组件树中共享数据和功能。provide 和 inject 是 Vue 依赖注入的两个关键概念。本文将深入探讨 Vue 的依赖注入机制,讨论如何使…

Hadoop基础组件介绍!

Hadoop是一个由Apache基金会所开发的分布式系统基础架构&#xff0c;Hadoop生态系统已经远远超出了这些基本组件&#xff0c;现在包括了多种组件和技术&#xff0c;详情介绍如下&#xff1a; HDFS&#xff08;Hadoop Distributed File System&#xff09; HDFS是Hadoop的核心组…

git使用、git与idea结合、gitee、gitlab

本文章基于黑马程序javase模块中的"git"部分 先言:git在集成idea中,不同版本的idea中页面显示不同,操作时更注重基于选项的文字;git基于命令操作参考文档实现即可,idea工具继承使用重点掌握 1.git概述 git是目前世界上最先进的分布式文件版本控制系统 分布式:将…

戴尔电脑开机出现no boot device found错误提示原因分析及解决方法

戴尔电脑是一款不的品牌,戴尔电脑一直以来都是以IT直销享誉全球的。而旗下的戴尔笔记本&#xff0c;更是深受用户们的追捧和喜爱。最近有网友反馈戴尔电脑开机出现no boot device found错误提示是怎么回事&#xff1f;后来发现有很多网友将引导模式改成legacymbr后发现启动时出…

均值滤波算法及实现

均值滤波器的使用场景&#xff1a; 均值滤波器使用于处理一些如上述蓝色线的高斯噪声场景 红色曲线是经过均值滤波处理后的数据。主要因为均值滤波设置数据缓冲区&#xff08;也即延时周期&#xff09;&#xff0c;使得测量值经过缓冲不会出现特别大的变化。 黄色曲线为高斯噪声…

10款免费好用的在线 PDF工具,PDF转换器

在当今数字化时代&#xff0c;PDF文件因其可移植性和安全性而被广泛使用。然而&#xff0c;处理这些文件时&#xff0c;我们常常需要一些高效的工具来帮助我们完成各种任务&#xff0c;如转换、编辑和压缩等。下面小编就来和大家分享10款免费且实用的在线PDF工具。 1. Smallpd…

二十、【机器学习】【非监督学习】- 均值漂移 (Mean Shift)

系列文章目录 第一章 【机器学习】初识机器学习 第二章 【机器学习】【监督学习】- 逻辑回归算法 (Logistic Regression) 第三章 【机器学习】【监督学习】- 支持向量机 (SVM) 第四章【机器学习】【监督学习】- K-近邻算法 (K-NN) 第五章【机器学习】【监督学习】- 决策树…