CMU 15-445 -- Embedded Database Logic - 12

news2024/10/5 21:15:34

CMU 15-445 -- Embedded Database Logic - 12

  • 引言
  • User-Defined Functions (UDF)
    • SQL Functions
    • External Programming Language
  • Stored Procedures
    • Stored Procedures 与 UDF 的区别
  • Database Triggers
  • Change Notifications
  • User-Defined Types (UDT)
    • Views
      • views vs select...into
      • views update
  • Materialized Views
  • Conclusion


引言

本系列为 CMU 15-445 Fall 2022 Database Systems 数据库系统 [卡内基梅隆] 课程重点知识点摘录,附加个人拙见,同样借助CMU 15-445课程内容来完成MIT 6.830 lab内容。


到目前为止,我们都假设所有的业务逻辑都位于应用本身,应用通过与 DBMS 通过多次通信,来达到最终业务目的,如下图所示:

在这里插入图片描述

这种做法有两个坏处:

  • 多个 RTT,更多延迟
  • 不同的应用无法复用查询逻辑

如果能将部分业务逻辑转移到 DBMS 中,就能够在以上两个方面得到优化。本节将介绍将业务逻辑转移到 DBMS 中的几种方法:

  • User-defined Functions
  • Stored Procedures
  • Triggers
  • Change Notifications
  • User-defined Types
  • Views

注意:将业务逻辑嵌入 DBMS 中也有坏处,比如不同版本的应用依赖于不同版本的 Stored Procedures 等,后期将增加 DBMS 的运维成本,因此这种做法也有其劣势,要具体问题具体分析。


User-Defined Functions (UDF)

UDF 允许应用开发者在 DB 自定义函数,根据返回值类型可以分为:

  • Scalar Functions:返回单个数值
  • Table Functions:返回一张数据表

UDF 函数计算的定义可以通过两种方式:

  • SQL Functions
  • External Programming Languages

SQL Functions

SQL Functions 包含一列 SQL 语句,DBMS 按顺序执行这些语句,以最后一条语句的返回值作为整个 Function 的返回值:

CREATE FUNCTION get_foo(int) RETURNS foo AS $$
SELECT * FROM foo WHERE foo.id = $1;
$$ LANGUAGE SQL;

External Programming Language

一些 DBMSs 支持使用非 SQL 定义 UDF:

  • SQL Standard:SQL/PSM
  • Oracle/DBS:PL/SQL
  • Postgres:PL/pgSQL
  • MySQL/Sybase:Transact-SQL

以下是 PL/pgSQL 的例子:

CREATE OR REPLACE FUNCTION sum_foo(i int) RETURN int AS $$
  DECLARE foo_rec RECORD;
  DECLARE out INT;
  BEGIN
    out := 0
    FOR foo_rec IN SELECT id FROM foo
                    WHERE id > i LOOP
      out := out + foo_rec.id;
    END LOOP;
    RETURN out;
  END;
$$ LANGUAGE plpgsql;

Stored Procedures

Stored Procedure 同样允许应用开发者自定义复杂逻辑,它的主要特点是:

  • 可以有多个输入和输出值
  • 可以修改数据表及数据结构
  • 通常不在 SQL 查询中调用

通常应用程序会直接调用 Stored Procedures,如下图所示:

在这里插入图片描述


Stored Procedures 与 UDF 的区别

抛开具体特征,从语义出发:

  • UDF: perform a subset of a read-only computation within a query
  • Stored Procedure: perform a complete computation that is independent of a query

Database Triggers

Trigger 通常被用来连接事件与 UDF:当某个 DB 事情发生时,监听相关事件的 trigger 负责调用对应的 UDF。

通常开发者需要定义:

  • 触发的事件类型: INSERT, UPDATE, DELETE, TRUNCATE, CREATE, ALTER, DROP

  • 事件的定义域: TABLE, DATABASE, VIEW, SYSTEM

  • 触发的时机:

    • before the statement executes
    • after the statement executes
    • before each row that the statement affects
    • instead of the statement

举例如下:

CREATE TABLE foo (
  id INT PRIMARY KEY,
  val VARCHAR(16)
);

CREATE TABLE foo_audit (
  id SERIAL PRIMARY KEY,
  foo_id INT REFERENCES foo (id),
  orig_val VARCHAR,
  cdate TIMESTAMP
);

CREATE OR REPLACE FUNCTION log_foo_updates() RETURNS trigger AS $$
  BEGIN
    IF NEW.val <> OLD.val THEN
      INSERT INTO foo_audit (foo_id, orig_val, cdate)
        VALUES(OLD.id, OLD.val, NOW());
    END IF
    RETURN NEW
  END
$$ LANGUAGE plpgsql;

CREATE TRIGGER foo_updates BEFORE UPDATE ON foo FOR EACH ROW
  EXECUTE PROCEDURE log_foo_updates();

Change Notifications

在数据库中,“change notification”(变更通知)类似于触发器(trigger),但是它是指DBMS向外部实体发送消息,告知数据库中发生了一些值得注意的事件。

可以将其类比为"pub/sub"(发布/订阅)系统,其中数据库作为发布者发布通知,而外部实体作为订阅者接收通知。

"change notification"通常可以与触发器(trigger)链接在一起,以便在发生变更时传递通知。

在SQL标准中,这种机制通常被称为"LISTEN + NOTIFY"。
在这里插入图片描述


User-Defined Types (UDT)

尽管 DBMSs 支持所有基本的原始数据类型,但如果我们想存储组合数据类型,如 struct,该如何做?就已有的知识,我们能想到两种方法:

  • Attribute Splitting:即将组合数据类型单独作为一张表 (pros&cons)
  • Application Serialization:即将组合数据序列化 (pros&cons)

除此之外,DBMS 通常还提供额外的 API,方便用户自定义数据,即 UDT:

  • Oracle supports PL/SQL
  • DB2 supports creating types based on build-in types
  • MySQL/Postgres only support type definition using external languages

在这里插入图片描述


Views

可以将 View 理解成一张虚拟表,这张表是一个只读查询的结果集,可以被其它查询引用。通常 View 的用途包括:

  • 简化查询语句
  • 对某些用户选择性隐藏数据

以下面这张 student 表为例:

![在这里插入图片描述![](https://img-blog.csdnimg.cn/7e0281a5b4b74e2a912239e3f07ff33f.png)

创建 cs_students View:

CREATE VIEW cs_students AS
  SELECT sid, name, login
    FROM student
   WHERE login LIKE '%@cs';

在这里插入图片描述

创建 cs_gpa View:

CREATE VIEW cs_gpa AS
  SELECT AVG(gpa) AS avg_gpa
    FROM student
   WHERE login LIKE '%@cs';

在这里插入图片描述


views vs select…into

VIEW:

  • 视图(VIEW)是一种虚拟表,它仅在需要时动态地生成结果。它不包含实际数据,而是根据与视图相关联的查询来生成结果。每当查询引用该视图时,视图将立即执行,并返回查询结果。

SELECT…INTO:

  • SELECT…INTO语句用于从一个表中选择数据,并将其复制到新的静态表中。新表的结构将根据SELECT语句的结果自动创建,并且不会随原始表的更新而更新。这意味着一旦数据被选择并复制到新表中,新表的内容将保持不变,即使原始表的数据发生更改也不会影响新表的内容。

在总结上述两个概念:

  • 视图是动态的,每次引用视图时都会生成最新的结果。
  • SELECT…INTO创建一个静态表,一旦数据复制到新表中,该表的内容不会随原始表的更改而更新。

views update

根据SQL-92标准规定,如果一个视图具备以下特性,应用程序可以对其进行修改:

  1. 仅包含一个基本表:该视图应该基于单个底层表。它不能是多个表的组合,也不能包含子查询。

  2. 不包含分组、去重、联合或聚合:该视图不能涉及GROUP BY、HAVING、UNION或聚合函数(例如SUM、COUNT、AVG等)等操作。它应该是对单个基本表的简单、直接的数据表示。

如果一个视图满足以上两个条件,就被认为是可更新的。这意味着应用程序可以对该视图执行修改(插入、更新、删除)操作,并且这些更改将应用到底层的基本表中。然而,如果一个视图是基于多个表或包含复杂的操作(如分组或聚合),那么数据库管理系统将更难确定如何应用更改,此时该视图可能不具备可更新性。


Materialized Views

View 对应的查询在 View 每次被使用时都会被执行一次,如果我们希望 View 实体化,提高查询效率,可以使用 Materialized Views,后者的数据会随着底层数据改变而被自动更新,举例如下:

CREATE MATERIALIZED VIEW cs_gpa AS
  SELECT AVG(gpa) AS avg_gpa
    FROM student
   WHERE login LIKE '%@cs';

“Materialized views” (物化视图)是数据库中的特殊类型视图。与普通视图不同,物化视图实际上存储了视图的结果集,而不是每次查询时动态生成。这使得物化视图能够在查询时更快地返回结果,因为它们避免了每次查询都执行复杂的计算。

物化视图的特点如下:

  1. 存储实际数据:物化视图将视图的结果集存储在磁盘上,以表的形式存在。因此,当查询物化视图时,它会直接从磁盘中获取数据,而不是每次执行查询时都重新计算结果。

  2. 自动更新:虽然物化视图存储了结果数据,但底层的基本表在更新时可能导致物化视图的数据变得过时。因此,可以配置物化视图定期自动更新,以确保其数据与基本表保持同步。

  3. 提高查询性能:由于物化视图存储了结果数据,所以当查询物化视图时,它可以直接从存储中获取结果,而不需要再次执行复杂的查询计算,从而显著提高了查询性能。

尽管物化视图提供了查询性能的提升,但也需要权衡存储空间和数据更新的成本。因此,在选择使用物化视图时,需要考虑数据更新的频率和数据的变化程度,以及对查询性能的要求。物化视图通常在数据仓库和大型数据集的环境中使用,以加速复杂查询的执行。


Conclusion

将应用逻辑放入 DBMS 中的各有利弊:

  • Pros
    • 减少 RTT,提高效率
    • 不同应用之间实现逻辑重用
  • Cons
    • 迁移性差
    • 运维成本高

本节对应教材PDF

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

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

相关文章

区别出过孔的内径、外径、单边孔环、电镀铜厚

自记&#xff1a; 这个参数是啥&#xff1f;下图区别出过孔的内径、外径、单边孔环、电镀铜厚 嘉立创单双面最小过孔内径0.3mm/外径0.6mm&#xff08;极限0.56mm&#xff09;&#xff0c;四、六层最小过孔内径0.2mm/外径0.45mm&#xff08;极限0.40mm&#xff09;&#xff0c;外…

学习day50

自定义指令总结&#xff1a; 一&#xff1a;定义语法&#xff1a; (1)局部指令&#xff1a; new Vue({ directives{指令名&#xff0c;配置对象} }) 或 new Vue({ directives{指令名&#xff0c;回调函数} }) (2)全局对象 Vue.dir…

基于Gym Anytrading 的强化学习简单实例

近年来强化学习(RL)在算法交易领域受到了极大的关注。强化学习算法从经验中学习并基于奖励优化行动使其非常适合交易机器人。在这篇文章&#xff0c;我们将简单介绍如何使用Gym Anytrading环境和GME (GameStop Corp.)交易数据集构建一个基于强化学习的交易机器人。 强化学习是…

【Java从0到1学习】05 Java 数组

1. 数组概述 需求&#xff1a;现在需要统计某公司员工的工资情况&#xff0c;例如计算平均工资、找到最高工资等。假设该公司有80名员工&#xff0c;用前面所学的知识&#xff0c;程序首先需要声明80个变量来分别记住每位员工的工资&#xff0c;然后在进行操作&#xff0c;这样…

MySQL一些知识

六、MySQL命令参数 七、远程登录 use mysql 八、SQL语句和常见的SQL操作 九、数据库和表的创建及插入 指定字段名称&#xff0c;按照表的字段名称顺序写&#xff1a; 指定字段名称&#xff1a; 字段名称可以不全部指定&#xff1a;

SpringBoot(三)

文章目录 前言一.日志的作用二.日志的使用2.1 自定义日志打印三.日志的级别3.1 日志级别的作用3.2 日志级别的分类和使用 四.⽇志持久化 前言 日志在应用程序中扮演着至关重要的角色&#xff0c;它是软件开发、运维和故障排查中不可或缺的工具。无论是大型企业级应用还是小型个…

node插件的安装、HTTP协议

接口测试与UI测试&#xff08;功能测试&#xff0c;UI的自动化测试&#xff09;有什么区别&#xff1f; 1、接口测试更多测试的是客户端与后端之间的交互 2、接口测试也是可以完全的测试产品功能测试场景 UI测试&#xff1a; 1、页面的交互 2、页面的各种提示信息的验证 …

C#栈、List结构的简单搭建

1、栈是一种先进后出的结构&#xff0c;如图&#xff1a; 我们用代码&#xff0c;简单实现一下&#xff1a; public class StackTest<T>{private T[] stack { get; set; }public int length { get; set; }public StackTest(){length 0;stack new T[length];}public vo…

[JVM]String str1 = new String(“yhz“)和 String str2 = “yhz“ 的区别

文章目录 0、前情1、相同之处2、不同之处3、解释前情 0、前情 为什么str1 str2 就返回true&#xff0c;而str1str3 就返回false&#xff1f;先看内存图解释 1、相同之处 String str1new String(“yhz”)和String str2“yhz”&#xff0c;都会先去字符串常量池中查看是否已经存…

Helm KinD kubectl krew Istio急速安装

本篇更新网上许多安装失效的工具&#xff0c;如krew和KinD。 本篇测试使用时间为2023/7/20&#xff0c;基本都为最新版本或最新稳定版本。 前置 Helm 是 Kubernetes 的一个包管理工具&#xff0c;用于简化 Kubernetes 应用的部署和管理。Helm 使用名为 "chart" 的打…

QDialog的两种显示方式

QDialog的两种显示方式 模态显示非模态显示 QDialog不能嵌入到其他窗口中显示&#xff08;无论继承与否&#xff09; 模态显示 d->exec(); 阻塞程序的执行 非模态显示 d->show(); 不阻塞程序

A--玉米大炮--2022河南萌新联赛第(三)场:河南大学

输入 3 3 1 1 2 2 3 3 输出 0 说明 开始时,小蓝控制所有大炮立即发射炮弹,僵王博士受到 666 点伤害,直接被击溃。 示例2 输入 2 20 5 1 5 3 输出 2 说明 开始时,小蓝控制所有大炮立即发射炮弹,僵王博士受到 101010 点伤害, 一秒后一号大炮装填完毕,小蓝控制其攻击僵王…

力扣 -- 152. 乘积最大子数组

一、题目&#xff1a; 题目链接&#xff1a;152. 乘积最大子数组 - 力扣&#xff08;LeetCode&#xff09; 二、解题步骤 下面是用动态规划的思想解决这道题的过程&#xff0c;相信各位小伙伴都能看懂并且掌握这道经典的动规题目滴。 三、参考代码&#xff1a; class Solut…

分布式数据库 Join 查询设计与实现浅析

目录 前言&#xff1a; ①Mysql 分库分表 Join 查询场景 sharding-jdbc Code Insight SQL 路由策略 ②Elasticsearch Join 查询场景 elasticsearch-sql Code Insight ③More Than Join Join 算法 Elasticsearch Nested 类型 前言&#xff1a; 分布式数据库 Join 查…

Unity 2D 针对单个物体的空气墙(能指定物体的碰撞器)

笔者也是废了九牛二虎之力才发现这个API并选择一种相对效率高还简单的实现方法 克服了同层级空气墙的问题 这样可以实现只跟列表里的物体能发生碰撞 在使用之前请确保&#xff1a;空气墙 原本 可以与列表指定的物体发生碰撞 然后本脚本会自动取消列表外的全部碰撞&#xff…

使用spark进行hbase的bulkload

使用spark进行hbase的bulkload 一、 背景 HBase 是一个面向列&#xff0c;schemaless&#xff0c;高吞吐&#xff0c;高可靠可水平扩展的 NoSQL 数据库&#xff0c;用户可以通过 HBase client 提供的 put get 等 api 实现在数据的实时读写。在过去的几年里&#xff0c;HBase …

C++面向对象程序设计-基础入门(超详细)

目录 一、c概述 二、初识c 1、第一个c程序 2、c面向对象的三大特性&#xff08;重要&#xff09; 三、作用域运算符&#xff1a;&#xff1a; 1、使用关键字namespace创建一个命名空间 2、命名空间只能定义在全局 3、 命名空间嵌套 4、随时将新的成员加入命名空间 5、命…

uni-app : 监听路由变化

在App.vue中 在 onLaunch中,利用拦截器监听 navigateTo等, 切记要在 invoke回调函数中查看, 要是再 success回调函数中,都路由完成了,还看啥? onLaunch(){ uni.addInterceptor(navigateTo, { //监听跳转invoke(e) {console.log(******** invoke-navigateTo ********, e.url)}…

AI工具集:【stablefoundation】satblediffusion官方免费实验机器人

stablefoundation是satble diffusion官方免费实验机器人,与midjourney一样在discord上操作 视频教程 https://v.douyin.com/ibgQTU7/ 图文教程 1、打开网址: https://stabledigest.substack.com/ 2、点击discord 3、加入stable foundation 4、点击找到机器人频道&#xf…

Linux —— 环境变量

环境变量&#xff08;environment variables&#xff09;&#xff0c;一般指在操作系统中用来指定操作系统运行环境的一些参数&#xff1b;如在编写的C/C代码链接时&#xff0c;所链接的动态、静态库的位置&#xff0c;就是通过相关环境变量帮助编译器进行查找的&#xff1b;环…