草庐IT

一文读懂存储过程

LovewiShare 2023-03-28 原文

0 导读

经常听别人说,“调用一个存储过程“,“把处理过程改写为存储过程之后就快了”此类的话,本篇文章我们来聊一聊存储过程。将从以下几个方面去描述存储过程。


1 存储过程解决了什么样的问题?

我们看这样一个场景:假设用户现在正在进行下单操作,那你的数据库需要做这些事。

 1)核对保证库存中有对应的商品。

 2)如果有商品,那商品需要预定防止卖给别人,并且要减少可用的商品数量 以反应正确的库存量。

 3)库存中没有的商品需要订购,这需要与供应商进行某种交互。

 4)关于那些物品入库和哪些物品退订,需要通知到对应的客户。

之前我们接触的场景都是单条的SQL语句,现在这种场景也可以使用一条一条的SQL去处理,但是如果一条一条的SQL去处理,每次需要重新写语句,还得保证不写错。那么存储过程这个时候就诞生了。

存储过程简单来说,就是为以后的使用而保存的一条或多条SQL的集合,通过把零散的处理封装到一个单元中,简化复杂的操作。由于不要求反复建立一系列的处理步骤,这里保证了开发人员和应用系统使用的是同样的一段代码,保障了数据的完整性。简化对变动的管理,如果业务或者表名列名改变,只需要去修改存储过程即可,调用者无需知道具体实现。

每个技术的诞生解决了问题,但是也带来了缺点。


2 存储过程的优缺点是什么?

先讲优点:

提高性能:因为存储过程只需要编译一次,而我们单独的SQL语句每次执行前都需要编译,所以存储过程比SQL要快。

使用存储过程写的代码更加的灵活。

再谈一谈缺点:

一般来说,存储过程比单独的SQL要复杂,这就需要有经验的老开发来编写。而且很多时候可能还没有创建存储过程的权限,许多数据库管理员允许调用,但是不准创建,因为维护的成本比较高。


3 应用场景有哪些?

存储过程内部包含业务规则和智能处理时,他的威力才能真正的显示出来。

对查询出来的订单进行加税处理,这时候用存储过程是比较好的处理方式。

总之在数据量大,计算复杂的场景,就可以考虑是否可以用存储过程来解决。


4 存储过程有哪些组成部分?

首先看创建的语句

create procedure readdata()
begin
select AVG(read_count) AS readaverage
from blog;
end;
这里得注意如果是MySQL需要重定义分隔符,因为mysql默认结束符是“;”,如果按照上面的语句,MySQL以为到from blog;这里存储过程就结束了,不完整。MySQL中正确的定义如下:

delimiter //
create procedure readdata()
begin
select AVG(read_count) AS readaverage
from blog;
end //
delimiter ;
这里需要注意delimiter后面是要空一格,否则执行失败。

其次看一下调用,只需使用call即可:

call readdata();
删除存储过程:

drop procedure readdata;
这里只需要给出名字即可删除。

注:存储过程还可以携带参数,这里只是介绍简单的原理,具体使用需要自己去查。


5 底层原理是怎样的?

create之后数据库做了什么?call调用的时候又是怎样找到的?

创建一个存储过程 (procedure) 时,数据库底层会将其编译成一个可执行的二进制代码,以便在需要执行该存储过程时能够直接调用该代码,而无需重新解析 SQL 查询语句。这有助于提高执行速度,降低数据库服务器的负载。

在存储过程被编译时,数据库会执行以下步骤:

  1. 语法检查:数据库会检查存储过程的语法是否正确,如果存在语法错误则会报错。
  2. 语义分析:数据库会检查存储过程中所引用的表、视图、函数等对象是否存在,并检查参数的数据类型是否正确。
  3. 优化:数据库会对存储过程进行优化,以便在执行时能够尽可能地提高执行效率。
  4. 生成可执行代码:数据库会将存储过程转换成可执行的二进制代码,并将其存储在系统表中,以便在需要执行该存储过程时能够直接调用。
  5. 缓存可执行代码:数据库会将生成的可执行代码缓存到内存中,以便在需要执行该存储过程时能够快速地调用。
当调用存储过程 (procedure) 时,数据库会执行以下步骤:

  1. 检查权限:数据库会检查当前用户是否有执行该存储过程的权限,如果没有则会拒绝执行。
  2. 加载可执行代码:数据库会从系统表中加载该存储过程的可执行代码,并将其缓存到内存中。
  3. 解析参数:如果存储过程有参数,则数据库会解析传入的参数,并将其传递给存储过程。
  4. 执行存储过程:数据库会执行存储过程中的代码,并根据代码的逻辑执行相应的操作,如查询、插入、更新或删除数据等。
  5. 返回结果:存储过程执行完成后,数据库会将执行结果返回给调用者。
总之,调用存储过程可以让数据库执行预定义的逻辑操作,避免了每次执行一组 SQL 语句的开销。数据库会加载存储过程的可执行代码,并解析传入的参数,执行存储过程中的代码并返回执行结果,从而提高了执行效率和性能。






有关一文读懂存储过程的更多相关文章

  1. ruby - 解析 RDFa、微数据等的最佳方式是什么,使用统一的模式/词汇(例如 schema.org)存储和显示信息 - 2

    我主要使用Ruby来执行此操作,但到目前为止我的攻击计划如下:使用gemsrdf、rdf-rdfa和rdf-microdata或mida来解析给定任何URI的数据。我认为最好映射到像schema.org这样的统一模式,例如使用这个yaml文件,它试图描述数据词汇表和opengraph到schema.org之间的转换:#SchemaXtoschema.orgconversion#data-vocabularyDV:name:namestreet-address:streetAddressregion:addressRegionlocality:addressLocalityphoto:i

  2. ruby - Rack:如何将 URL 存储为变量? - 2

    我正在编写一个简单的静态Rack应用程序。查看下面的config.ru代码:useRack::Static,:urls=>["/elements","/img","/pages","/users","/css","/js"],:root=>"archive"map'/'dorunProc.new{|env|[200,{'Content-Type'=>'text/html','Cache-Control'=>'public,max-age=6400'},File.open('archive/splash.html',File::RDONLY)]}endmap'/pages/search.

  3. ruby-on-rails - 为什么在 Rails 5.1.1 中删除了 session 存储初始化程序 - 2

    我去了这个website查看Rails5.0.0和Rails5.1.1之间的区别为什么5.1.1不再包含:config/initializers/session_store.rb?谢谢 最佳答案 这是删除它的提交:Setupdefaultsessionstoreinternally,nolongerthroughanapplicationinitializer总而言之,新应用没有该初始化器,session存储默认设置为cookie存储。即与在该初始值设定项的生成版本中指定的值相同。 关于

  4. ruby-on-rails - 尝试设置 Amazon 的 S3 存储桶 : 403 Forbidden error & setting permissions - 2

    我正在关注Hartl的railstutorial.org并已到达11.4.4:Imageuploadinproduction.我做了什么:注册亚马逊网络服务在AmazonIdentityandAccessManagement中,我创建了一个用户。用户创建成功。在AmazonS3中,我创建了一个新存储桶。设置新存储桶的权限:权限:本教程指示“授予上一步创建的用户读写权限”。但是,在存储桶的“权限”下,未提及新用户名。我只能在每个人、经过身份验证的用户、日志传送、我和亚马逊似乎根据我的名字+数字创建的用户名之间进行选择。我已经通过选择经过身份验证的用户并选中了上传/删除和查看权限的框(而不

  5. ruby - 如何打印出 Mechanized 存储的 cookie? - 2

    我正在使用mechanize登录网站,然后检索页面。我遇到了一些问题,我怀疑这是由于cookie中的某些值造成的。当Mechanize登录网站时,我假设它存储了cookie。如何通过Mechanize打印出存储在cookie中的所有数据? 最佳答案 代理有一个cookie方法。agent=Mechanize.newpage=agent.get("http://www.google.com/")agent.cookiesagent.cookies.to_scookie返回一个Mechanize::Cookiesobject

  6. ruby-on-rails - 闪存消息存储在哪里? - 2

    我以为它们存储在cookie中-但不,检查cookie没有任何结果。session也不存储它们。那么,我在哪里可以找到它们?我需要这个来直接设置它们(而不是通过flashhash)。 最佳答案 它们存储在inyoursessionstore.自rails2.0以来的默认设置是cookie存储,但请检查config/initializers/session_store.rb以检查您是否使用默认设置以外的东西。 关于ruby-on-rails-闪存消息存储在哪里?,我们在StackOverf

  7. ruby-on-rails - 在 Rails 中存储(结构化)配置数据的位置 - 2

    对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化

  8. ruby - 如何存储和读取 RubyVM::InstructionSequence? - 2

    有没有办法将RubyVM::InstructionSequence存储到文件中并稍后读取?我尝试了Marshal.dump但没有成功。我收到以下错误:`dump':no_dump_dataisdefinedforclassRubyVM::InstructionSequence(TypeError) 最佳答案 是的,有办法。首先,您需要使InstructionSequence的load方法可访问,默认情况下该方法是禁用的:require'fiddle'classRubyVM::InstructionSequence#RetrieveR

  9. ruby-on-rails - 如何解析位于 Amazon S3 存储桶中的 CSV 文件 - 2

    下面是我用来从应用程序中解析CSV的代码,但我想解析位于AmazonS3存储桶中的文件。当推送到Heroku时它也需要工作。namespace:csvimportdodesc"ImportCSVDatatoInventory."task:wiwt=>:environmentdorequire'csv'csv_file_path=Rails.root.join('public','wiwt.csv.txt')CSV.foreach(csv_file_path)do|row|p=Wiwt.create!({:user_id=>row[0],:date_worn=>row[1],:inven

  10. ruby - 存储外部 API 的密码 - 最佳实践 - 2

    如果我构建了一个应用程序来访问来自Gmail、Twitter和Facebook的一些数据,并且我希望用户只需输入一次他们的身份验证信息,并且在几天或几周后重置,那会怎样是在Ruby中动态执行此操作的最佳方法吗?我看到很多人只是拥有他们客户/用户凭证的配置文件,如下所示:gmail_account:username:myClientpassword:myClientsPassword这看起来a)非常不安全,b)如果我想为成千上万的用户存储此类信息,它就无法工作。推荐的方法是什么?我希望能够在这些服务之上构建一个界面,因此每次用户进行交易时都必须输入凭据是不可行的。

随机推荐