大型系统必须得要存储过程和触发器吗,from 知乎
通常状况下,Web 应用的瓶颈常在 DB 上,因此会尽量的减小 DB 作的事情,把耗时的服务作成 Scale Out,这种状况下,确定不会使用存储过程;mysql
而若是只是通常的应用(好比,SAP、peopleSoft、ERP 等企业级别应用),DB 没有性能上的问题,在适当的场景下,也可使用存储过程。减小开发成本,毕竟其业务逻辑修改频繁,并且为通用,不少时候会把一些业务逻辑编写成存储过程,像 Oracle 会写成包,比存储过程更强大。另一个缘由是服务器的负载是可控,也即系统的访问人数首先是可控的,没有那么大,并且这些数据又很是关键,为此每每使用的设备也比较好,多用存储柜子支撑数据库sql
至于触发器,我是知道有这东西但历来没用过。我但愿风险可控,遇到问题可以快速的找到缘由,尽量不会去使用触发器。数据库
存储过程简单来讲,就是为之后的使用而保存的一条或多条MySQL语句的集合。可将其视为批文件,虽然它们的做用不限于批处理。安全
使用存储过程的理由(简单,安全,高性能
):服务器
经过把处理封装在容易使用的单元中,简化复杂的操做 - 简单
。网络
因为不要求反复创建一系列处理步骤,这保证了数据的完整性。 若是全部开发人员和应用程序都使用同一(test)存储过程,则所使用的代码都是相同的 -- 即防止错误。须要执行的步骤越多,出错的可能性就越大。防止错误保证了数据一致性。并发
简化对变更的管理。若是表名,列名或业务逻辑有变化,只须要更改存储过程的代码。 -- 即保证安全性
。系统管理员经过执行某一存储过程的权限进行限制,可以实现对相应的数据的访问权限的限制,避免了非受权用户对数据的访问,保证了数据的安全.ide
存储过程能减小网络流量。性能
针对同一个数据库对象的操做(如查询、修改),若是这一操做所涉及的 Transaction-SQL 语句被组织程存储过程,那么当在客户计算机上调用该存储过程时,网络中传送的只是该调用语句,从而大大增长了网络流量并下降了网络负载。fetch
提升性能
。使用存储过程比使用单独sql语句快.
若是某一操做包含大量的 Transaction-SQL 代码或分别被屡次执行,那么存储过程要比批处理的执行速度快不少。由于存储过程是预编译的。在首次运行一个存储过程时查询,优化器对其进行分析 优化,而且给出最终被存储在系统表中的执行计划。而批处理的 Transaction-SQL 语句在每次运行时都要进行编译和优化,速度相对要慢一些。
存储过程的缺陷:
存储过程的编写比基本SQL复杂。
用户可能没有建立存储过程的安全访问权限。
mysql-- 无参数 或者 有参数 Delimiter // CREATE PROCEDURE productpricing( OUT pl DECIMAL(8,2), OUT ph DECIMAL(8,2), OUT pa DECIMAL(8,2), ) BEGIN SELECT MIN(prod_price) INTO pl FROM products; SELECT MAX(prod_price) INTO ph FROM products; SELECT Avg(prod_price) INTO pa FROM products; END // Delimiter ;
调用此修改过的存储过程,指定出三个变量名
mysqlcall productpricing(@pricelow, @pricehigh, @priceaverage);
mysqlselect @priceaverage;
例子2: 检索出产品平均价格
mysqlCREATE PROCEDURE ordertotal( IN onumber INT, OUT ototal DECIMAL(8,2), ) BEGIN SELECT Sum(item_price * quantity) from orderitems where order_num = onumber into ototal END // Delimiter ;
调用存储过程
mysqlcall productpricing(20005, @total);
显示查询
mysqlselect @total;
游标是一个存储在mysql服务器上的数据库查询,他不是一条select语句,而是被该语句检索出来的结果集。
如定义了ordernumbers的游标,用来检索全部订单的select语句。
使用游标的数据:
mysqlcreate procedure processorder() begin -- declare local variables declare o int; -- declare the cursor declare ordernumbers cursor for select order_num from orders; -- open the cursor open ordernumbers; -- get order number fetch ordernumbers into o; -- close the cursor close ordernumbers; end //
事务处理:是用户定义的一个数据库操做序列,这些操做保证成批的MySQL操做要么彻底执行,要么彻底不执行。 transaction processing 能够用来维护数据库的完整性
:若是没有错误发生,整组语句提交给数据库表。若是发生错误,则进行回退(撤销)以恢复数据库到某个已知且安全的状态。
一个事务能够是一条SQL语句,也能够一组SQL语句。事务和程序是两个概念,Generally, 一个程序包含多个事务。
MySQL 的事务支持不是绑定在 MySQL 服务器自己,而是与存储引擎相关:
1.MyISAM:不支持事务,用于只读程序提升性能
2.InnoDB:支持 ACID 事务、行级锁、并发
3.Berkeley DB:支持事务
A 原子性: 事务是数据库的逻辑工做单位,事务中包括的全部操做要么都作,要么都不作,不然事物将被终止在故障点,和之前的操做将回滚到之前的状态。
C 一致性: 事务执行的结果必须是使数据库从一个一致性的状态变到另一个一致性状态。
I 隔离性: 一个事物的执行不能被其余事物干扰。即一个事物内部的操做及使用的数据对其余事物是隔离的,并发执行的各个事物之间互相不干扰。
D 永久性: 一个事物一旦成功提交,对数据库中数据的修改就是永久性。接下来其余的其余操做或故障不该该对其执行结果有任何影响。
管理事务处理的关键在于将SQL语句分解为逻辑块,并明确规定数据应该什么时候回退,什么时候不回退。保证事务的ACID是事务管理的重要任务。
begin transaction // 开始事务 commit // 结束事务(提交事务的全部操做,将事务中全部对DB的更新写回到磁盘上的物理DB中,事务正常结束) rollback // 结束事务(回滚。事务在运行过程当中发生了某种故障,事务不能正常执行,系统将事务中对DB的全部已经完成的操做所有撤销,回滚到事务开始的状态。)
for eaxample: mysql语句使用rollback来回退/撤销 mysql语句。
select * from orderitems; start transaction; delete from orderitems; rollback; select * from orderitems;
当系统运行过程当中发生故障,利用数据库后备副本
和日志文件
就能够将数据库恢复到故障以前的某个一致性状态。
利用日志
技术进行DB恢复时候,恢复子系统必须搜索日志,肯定哪些事务须要REDO,哪些须要UNDO。(正向扫描日志文件,找出故障发生前已经提交的事务(these transactions both have "begin transaction" and "commit"), 将其事务标识记入重作REDO队列;同时找出故障发生时还没有完成的事务(these transactions just have "begin transaction" not "commit")将其事务标识记入撤销UNDO队列)。
搜索整个日志须要大量时间 --- 具备检查点
的恢复技术。
多用户数据库系统。当多个用户并发地存取数据库时就会产生多个事务同时存取同一个数据的状况。弱对并发操做不加控制就可能会存取和存储不正确的数据,破坏事务的一致性
和数据库的一致性
。 -- 因此引入并发控制。
事务ACID特性可能遭到破坏的缘由之一是多个事务对数据库并发操做形成的。为了保证事务的隔离性
和一致性
,DBMS须要对并发操做进行正确调度。
并发操做带来的不一致性主要包括丢失修改,不可重复读和读脏数据。
并发控制的主要技术:封锁,时间戳,乐观控制法。
确保数据的安全和完整 -- 访问控制, 即建立和管理用户帐号。
MYSQL服务器的安全基础是:用户应该对他们须要的数据具备适当的访问权,既不能多也不能少。
mysqlcreate user USERNAME identified by 'password';
mysqldrop user USERNAME;
建立用户帐号后,必须接着分配访问权限。新建立的用户帐号没有访问权限,它们只能登陆mysql,可是看不到数据,不能执行任何数据库操做
查看用户的权限:
show grants for USERNAME;
GRANT
给出信息
- 要授予的权限
- 被授予访问权限的数据库或表
- 用户名
grant容许用户在数据库creatdb.*的全部表上使用select
REVOKE
,撤销特定的权限。
数据库管理员而不是开发者使用这些语句。
mysqlANALYZE TABLE CHECK TABLE CHECKSUM TABLE OPTIMIZE TABLE REPAIR TABLE
首先保证全部数据都被写到了磁盘,须要备份前刷新未写数据
mysqlflush table
备份命令
- mysqldump
, 备份数据库到外部文件
- mysqlhotcopy
从一个数据库复制全部数据, 比mysldump快可是不被InnoDB支持。
- nysql的backup table
或者 select into outfile
转储全部数据到某个外部文件。
1. 对表进行优化 (优化表主要做用是消除删除或者更新形成的空间浪费) 2. 对表进行分析(分析关键字的分布, 分析并存储 MyISAM 和 BDB 表中键的分布) 3. 对表进行检查(检查表的错误,而且为 MyISAM 更新键的统计内容) 4. 对表进行修复(修复被破坏的 MyISAM 表)
对表的按期分析能够改善性能,且应该成为常规维护工做的一部分。由于经过更新表的索引信息对表进行分析,可改善数据库性能。
分析关键字的分布, 分析并存储 MyISAM 和 BDB 表中键的分布
mysql 使用analyze table TABLENAME
来分析
Table:表示表的名称;
Op:表示执行的操做。analyze 表示进行分析操做。check 表示进行检查查找。optimize 表示进行优化操做;
Msg_type:表示信息类型,其显示的值一般是状态、警告、错误和信息这四者之一;
Msg_text:显示信息。
检查表和优化表以后也会出现这 4 列信息。
mysql 使用check table TABLENAME
来检查,该语句能检查InnoDB和MyISAM类型的表是否存在错误。并且能够检查视图是否存在错误。
为何优化?随着 MySQL 的使用,包括 BLOB 和 VARCHAR 字节的表将变得比较繁冗,由于这些字段长度不一样,对记录进行插入、更新或删除时,会占有不一样大小的空间,记录就会变成碎片,且留下空闲的空间。像具备碎片的磁盘,会下降性能,须要整理,所以要优化。
三种优化的方式
1. mysql 使用optimize table TABLENAME
来检查
2. 利用mysqlcheck
对表进行优化
3. 利用myisamchk
对表进行优化
想更一进步的支持我,请扫描下方的二维码,你懂的~