上一篇:数据库系统原理【二】
存储过程是一组为了完成某项特定功能的SQL语句集,其实质就是一段存储在数据库中的代码。
它可以由声明式的sql语句和过程式语句组成
存储过程是一组为了完成某项特定功能的SQL语句集,其实质就是一段存储在数据库中的代码。
DELIMITER $$
// 示例:将MySQL结束符修改为俩个感叹号"!!"
DELIMITER !!
// 示例:回到";"结束
DELIMITER ;
// 示例:在test中创建一个存储过程,用于实现给定表customers中一个客户id号即可修改表customers中改客户的性别为一个指定的性别
USE test;
DELIMITER $$
CREATE PROCEDURE update_sex(IN cid INT,IN csex CHAR(4))
BEGIN
UPDATE customers
SET sex=csex
WHERE id=cid;
END $$
// 调用数据库test中的存储过程update_sex,将客户id号为909的客户性别修改为“M”
CALL update_sex(99,'M'); // 如果你之前改了结束符,请改回;号,或者使用你改了的结束符进行结束语句
DROP PROCEDURE update_sex;
DECLARE var_name[,...] type [DEFAULT value]
// 例子
// 声明一个整型局部变量cid
DECLARE cid INT(10);
1、只能在存储过程体的BEGIN。。。END语句块中声明;
2、必须在存储过程的开头处声明;
3、作用范围仅限于声明它的BEGIN。。。END语句块;
4、不同于用户变量;
1、局部变量声明时,在其前面没有@符号,并且它只能被声明它的BEGIN、、、END语句块中的语句所使用;
2、用户变量在声明时,会在其名称前面使用@符号,同时已声明的用户变量存在于整个会话之中。
SET var_name=1;
存储函数与存储过程一样,是由SQL语句和过程式语句组成的代码片段。
CREATE FUNCTION sp_name([func_parameter[,...]])
RETURNS type
routine_body
存储函数与存储过程一样,是由SQL语句和过程式语句组成的代码片段
// 使用SELECT关键字调用存储函数
// func_parameter是函数参数
SELECT sp_name(func_parameter[,...])
// 使用DROP关键字删除存储函数
// sp_name是要删除的存储函数的名字
DROP FUNCTION [IF EXISTS] sp_name;
数据库完整性是指数据库中数据的正确性和相容性。
在MySQL中,实体完整性约束是通过主键约束和候选键约束实现的。
候选键约束也可以使用 CREATE UNIQUE INDEX创建
在MySQL中,参照完整性约束是通过外键声明实现的。
// tbl_name -- 指定外键所参照的表名
// field_name -- 指定被参照的列名
// reference_option -- 约束策略
REFERENCES tbl_name(field_name,...)
[ON DELETE reference_option]
[ON UPDATE reference_option]
约束策略
1.RESTRICT - - 限制策略 【默认策略】
2.CASCADE - - 级联策略
3.SET NULL - - 置空策略
4.NO ACTION - - 不采取实施策略
// symbol -- 指定的约束名字【唯一的】
// 只能给基于表的完整性约束指定名字
// 无法给基于列的完整性约束指定名字
// 如果没有命名,数据库会自动创建一个唯一名字
CONSTRAINT[symbol]
使用ALTER TABLE语句更新与列或表有关的各种约束。
是用户定义在关系表上的一类由时间驱动的数据对象。
也是一种保证数据完整性的方法。
小拓展:在触发器的创建中,每个表每个事件每次只允许一个触发器,因此每个表最多支持的触发器是6个。
// 使用CREATE TRIGGER语句创建触发器
// trigger_name 触发器名字
// trigger_time 指定触发的时刻
// trigger_event 指定触发的事件
// tbl_name 指定与触发器相关联的表名
// FOR EACH ROW 指定对于受触发事件影响的每一行都要激活触发器的动作
// trigger_body 指定触发器的动作主体
CREATE TRIGGER
trigger_name
trigger_time
trigger_event
ON tbl_name
FOR EACH ROW
trigger_body;
// 示例:在数据库mysql_test的表customers中
// 创建一个触发器customers_insert_trigger
// 用于每次向表customers插入一行数据时
// 将用户变量str的值设置为one customer added!
USE mysql_test
CREATE TRIGGER
customers_insert_trigger
AFTER
INSERT
ON customers
FOR EACH ROW
SET @str='one customer added!';
// 查看用户变量
select @str;
DROP TRIGGER [IF EXISTS] trigger_name;
// 示例:删除数据库test中的触发器insert_trigger;
DROP TRIGGER IF EXISTS test.insert_trigger;
在INSERT触发器代码内,可引用一个名为NEW(不区分大小写)的虚拟表,来访问被插入的行。
在BEFORE INSERT触发器中,NEW中的值可以被更新。
// 示例:在数据库test中重新创建触发器insert
// 用于每次向表customers插入一行数据时,将用户变量str的值设置为新插入客户的id号。
CREATE TRIGGER test.insert
AFTER INSERT
ON test.customers
FOR EACH ROW
set @str=new.id;
在DELETE触发器代码内,可引用一个名为OLD(不区分大小写)的虚拟表,来访问被删除的行。
OLD中的值全部是只读的,不能被更新。
在UPDATE触发器代码内,可引用一个名为OLD(不区分大小写)的虚拟表,来访问UPDATE语句执行前的值,也可以引用一个名为NEW(不区分大小写)的虚拟表来访问更新后的值。
// 在数据库test的表customers中创建一个触发器update_trigger
// 用于每次更新表customers时
// 将该表中address列的值设置为contact列的值。
CREATE TRIGGER test.customers.update_trigger
BEFORE UPDATE
ON test.customers
FOR EACH ROW
SET NEW.address=OLD.contact;
数据库的安全性是指保护数据库以防止不合法的使用而造成数据泄露、更改或破坏,所以安全性对于任何一个DBMS来说都是至关重要的。
// 查看数据库的用户
select user from mysql.user;
使用CREATE USER语句创建MySQL账户。
// 创建用户账号格式:'user_name'@'host_name'
// 默认主机名%
// IDENTIFIED BY:可选性,指定用户账号对应的口令
// PASSWORD:可选性,指定散列口令
CREATE USER user[IDENTIFIED BY [PASSWORD]'password']
// 示例:在服务器中添加俩个新用户,其用户名分别为zhangsan和lisi,他们的主机名均为localhost,zhangsan的口令为123,用户lisi的口令为对明文456使用PASSWORD()函数加密返回的散列值。
SELECT md5('456');
// 5.5版本的话是SELECT PASSWORD(456);
// 把这个值去写到下面xxx的位置
CREATE USER 'zhangsan'@'localhost'
IDENTIFIED BY '123',
CREATE USER 'lisi'@'localhost'
IDENTIFIED BY PASSWORD'xxx';
使用DROP USER语句删除用户账号
// 注意要加主机的名字
DROP USER user[,user]...;
// 示例:删除lisi用户
DROP USER 'lisi'@'localhost';
// 修改名字
RENAME USER old_user TO new_user[,old_user TO new_user]...;
// 示例:将zhangsan改成wangwu
RENAME USER 'zhangsan'@'localhost'
TO 'wangwu'@'localhost';
使用SET PASSWORD语句修改用户登录口令
// FOR user:可选性,指定想修改的用户账号
SET PASSWORD[FOR user] =
{
PASSWORD('new_password')
| 'encrypted password'
}
// 示例:
SET PASSWORD FOR 'username'@'localhost' = PASSWORD('pass');
priv_type:用于指定权限的名称
column_list:用于指定权限要授予给表中哪些具体的列
object_type:用于指定权限授予的对象和级别
user_specification:用于设定用户的口令,以及指定被授予权限的用户user
WITH GRANT OPTION:可选性,用于实现权限的转移或限制
// 示例:授予用户zhangsan在数据库mysql_test的表customers上
// 用于对列cust_id和列cust_name的SELECT权限。
GRANT SELECT (cust_id, cust_name)
ON mysql_test.customers
TO 'zhangsan'@'localhost';
// 示例:授予当前系统中一个不存在的用户liming和用户huang,
// 要求创建这俩个用户,并设置对应的系统登录命令,
// 同时授予他们在数据库mysql_test的表customers上拥有SELECT和UPDATE的权限。
GRANT SELECT,UPDATE
ON mysql_test.customers
TO 'liming'@'localhost' IDENTIFIED BY 'abc',
'huang'@'localhost' IDENTIFIED BY 'cba';
GRANT ALL
ON mysql_test.*
TO 'wangwu'@'localhost';
GRANT CREATE USER
ON *.*
TO 'wangwu'@'localhost';
GRANT SELECT,UPDATE
ON mysql_test.customers
TO 'zhou'@'localhost' IDENTIFIED BY 'abc'
WITH GRANT OPTIONS;
使用REVOKE语句撤销用户权限
REVOKE priv_type[(column_list)][,priv_type[(column_list)]]...
ON [object_type] priv_level
FROM user[user]...;
REVOKE SELECT
ON mysql.test.customers
FROM 'zhow'@'localhost';
所谓事物是用户定义的一个数据操作序列,这些操作可作为一个完整的工作单元,要么全部执行,要么全部不执行,是一个不可分割的工作单位。事务中的操作一般是对数据的更新操作,包括:增、删、改。
以BEGIN TRANSACTION语句开始
以 COMMIT【提交】 语句或 ROLLBACL【回滚】 语句结束
事物是不可分割的最小单位,所包含的这些操作是一个整体。
事物必须满足数据库的完整性约束,且事务执行完毕后将数据库由一个一致性状态转变到另一个一致性状态。
事务是彼此独立的、隔离的,即一个事务的执行不能被其他事务所干扰。
也叫永久性,是指一个事务一旦提交,它对数据库中数据的改变就应该是永久性的,且接下来的其他操作或故障对其执行结果无影响。
一个锁实质上就是允许或阻止一个事务对一个数据对象的存取特权。
基本的封锁类型:
封锁的工作原理:
- 若事物T对数据D加了X锁,则所有别的事务对数据D的锁请求都必须等待直到事务T释放锁。
- 若事务T对数据D加了S锁,则别的事务还可对数据D请求S锁,而对数据D的X锁请求必须等待直到事务T释放锁。
- 事务执行数据库操作时都要先请求相应的锁,即对读请求S锁,对更新(插入、删除、修改)请求X锁。这个过程一般是由DBMS在执行操作时自动隐含地进行。
- 事务一直占有获得的锁直到结束(COMMIT 或 ROLLBACK)时释放。
我们通常以粒度来描述封锁的数据单元的大小
DBMS可以决定不同粒度的锁
粒度 越细 ,并发性就 越大 ,但软件复杂性和系统开销也就 越大 。
并发量指的是同时支持的事务数量。
封锁的级别又称为一致性级别或隔离度。
一组事务的一个调度就是它们的基本操作的一种排序。
在数据库系统中,可串行性就是并发执行的正确性准则,即当且当一组事务的并发执行调度是可串行化的,才认为它们是正确的。
FIELDS和LINES - - 决定数据行在备份文件中存储的格式
TERMINATED BY - - 指定字段值之间的符号
DUMPFILE - - 导出的备份文件里面所有的数据行都会彼此紧挨着放置