常见的数据库有:甲骨文(Oracle),MySQL,DB2,Microsoft SQL Server
初始化:mysqld --initialize --console
安装mysql:mysqld --install [服务名]
存储过程和函数概念
无参存储过程
存储过程和函数是事先经过编译并存储在数据库中的一段SQL语句的集合【流程】,可以通过调用执行这些存储过程和
函数,可以简化应用开发人员的很多工作,减少数据在数据库和应用服务器之间的传输,对于提高数据处理的效率是
有好处的。
(1). 定义方式稍微不同,函数关键词是FUNCTION,存储过程是PROCEDURE
(2). 存储过程是无返回值,函数是有返回值
(3). 调用方式不同,存储过程是"call 存储过程名()"调用,函数是在sql语句通过"函数名()"调用
DELIMITER <自定义分隔符,一般用&&,可以自己改>
CREATE PROCEDURE <自定义存储过程名>(<形参列表>)
BEGIN
/*存储过程内容*/
END<自定义分隔符,一般用&&,和上面的DELIMITER 后定义的相同>
DELIMITER ; /*将分隔符换回 ';' */
DELIMITER $$
-- 创建一个mmyprocedure01的存储过程,参数目前无参数
CREATE PROCEDURE myprocedure01()
有参存储过程
查看存储过程
删除存储过程
3.2.4 存储函数的操作
创建存储函数
-- 存储过程从此处开始
BEGIN
# 定义你的存储过程流程,就是一堆语句
SELECT * from emp1;
SELECT * from dept1;
-- 存储过程在此处结束
END $$
-- 将结束符换回来
DELIMITER ;
-- 调用存储过程
call myprocedure01();
DELIMITER $$
-- 创建一个mmyprocedure01的存储过程,参数目前无参数
CREATE PROCEDURE myprocedure02(IN sename VARCHAR(50), sdname VARCHAR(14))
-- 存储过程从此处开始
BEGIN
#定义你的存储过程流程,就是一堆语句
SELECT * from emp1 where ename = sename;
SELECT * from dept1 where dname = sdname;
-- 存储过程在此处结束
END $$
-- 将结束符换回来
DELIMITER ;
-- 调用存储过程 实际参数
call myprocedure02('张三','服务部');
-- 查询存储过程的状态信息,可以配合where语句使用
SHOW PROCEDURE STATUS;
-- 查询某个存储过程的定义
SHOW CREATE PROCEDURE 存储过程名;
-- 建议加 if exists 是验证是否存在,如果存在才会执行删除,不存在不会报错
DROP PROCEDURE IF EXISTS 存储过程名
这里有一个关键点:
DELIMITER <自定义分隔符,一般用&&,可以自己改>
CREATE FUNCTION <函数名>(<参数列表>)
RETURNS <定义返回值类型【INT,VARCHAR...】>
BEGIN
...
RETURN <具体的数据,类型要与RETURNS后定义的相匹配>
END<自定义分隔符,一般用&&,和上面的DELIMITER 后定义的相同>
DELIMITER ; /*将分隔符换回 ';' */
-- 存储函数 外层DELIMITER可有可没有
DELIMITER $$
CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT
DETERMINISTIC
BEGIN
DECLARE result INT;
SET result = a + b;
RETURN result;
END $$
DELIMITER;
或者
CREATE FUNCTION add_numbers(a INT, b INT) RETURNS INT
DETERMINISTIC
BEGIN
DECLARE result INT;
SET result = a + b;
RETURN result;
END;
-- 调用存储函数
select add_numbers(1,2);
DETERMINISTIC(确定性): 这个参数指示函数是否是确定性的。确定性函数意味着对于给定的输入,函数总是产生相同的输出,而不考虑调用时的上下文或环境。换句话说,如果函数对于相同的参数输入,总是返回相同的结果,则可以将其定义为确定性函数。这对于结果的缓存和查询优化非常有用。如果不确定函数是否满足这个条件,最好不要将其标记为 DETERMINISTIC。
NO SQL(无 SQL): 这个参数指示函数是否访问数据库。如果函数没有在执行期间访问数据库,就可以将其标记为NO SQL。这包括不仅限于不对数据库进行写操作,也不执行查询操作。例如,一些数学函数或字符串处理函数可能不需要访问数据库。
READS SQL DATA(读取 SQL 数据): 这个参数指示函数是否读取数据库中的数据。如果函数执行期间会读取数据库中的数据,但不进行写操作,就可以将其标记为 READS SQL DATA。这意味着函数在执行期间只读取数据,而不修改数据。例如,一个只执行 SELECT 查询的函数就可以被定义为 READS SQL DATA
存储引擎 事务
存储引擎
1、MySQL中的数据用各种不同的技术存储在文件中,每一种技术都使用不同的存储机制、索引技巧、锁定水平并最终提供不同的功能和能力,这些不同的技术以及配套的功能在MySQL中称为存储引擎。
2、存储引擎是MySQ将数据存储在文件系统中的存储方式或者存储格式。
3、存储引擎是MySQL数据库中的组件,负责执行实际的数据I/O操作。
4、MySQL系统中,存储引擎处于文件系统之上,在数据保存到数据文件之前会传输到存储引擎,之后按照各个存储引擎的存储格式进行存储。
常用的存储引擎有MylSAM ,InnoDB(mysql默认存储引擎)
MylSAM介绍
1、MylSAM不支持事务,也不支持外键约束,只支持全文索引,数据文件和索引文件是分开保存的。
2、访问速度快,对事务完整性没有要求。
3、MylSAM适合查询、插入为主的应用。
4、 MylSAM在磁盘.上存储成三个文件,文件名和表名都相同,但是扩展名分别为:frm文件存储表结构的定义,数据文件的扩展名为.MYD (MYData),索引文件的扩展名是.MYI (MYIndex)
MylSAM的特点
1、表级锁定形式,数据在更新时锁定整个表。
2、数据库在读写过程中相互阻塞:会在数据写入的过程阻塞用户数据的读取也会在数据读取的过程中阻塞用户的数据写入
3、数据单独写入或读取,速度过程较快且占用资源相对少。
MyISAM表支持3种不同的存储格式
(1)静态(固定长度)表
静态表是默认的存储格式。静态表中的字段都是非可变字段,这样每个记录都是固定长度的,这种存储方式的优点是存储非常迅速,容易缓存,出现故障容易恢复;缺点是占用的空间通常比动态表多。
(2)动态表
动态表包含可变字段,记录不是固定长度的,这样存储的优点是占用空间较少,但是频繁的更新、删除记录会产生碎片,需要定期执行OPTIMIZE TABLE语句或myisamchk-r命令来改善性能,并且出现故障的时候恢复相对比较困难(因为会产生磁盘碎片,而且存储空间不是连续的)。
(3)压缩表
压缩表由 myisamchk 工具创建,占据非常小的空间,因为每条记录都是被单独压缩的,所以只有非常小的访问开支。(压缩的过程中会占用CPU性能)
MyISAM使用的生产场景举例公司业务不需要事务的支持 单方面读取或写入数据比较多的业务 MylSAM存储引擎数据读写都比较频繁场景不适合(因为读写是互相阻塞的) 使用读写并发访问相对较低的业务 数据修改相对较少的业务 对数据业务-致性要求不是非常高的业务 服务器硬件资源相对比较差(MyISAM占用资源相对少)
InnoDB介绍
1、支持事务,支持4个事务隔离级别
2、MySQL从5.5.5版本开始,默认的存储引擎为InnoDB
3、读写阻塞与事务隔离级别相关
4、能非常高效的缓存索引和数据
5、表与主键以簇的方式存储 BTREE
6、支持分区、表空间,类似oracle数据库
7、支持外键约束,5.5前不支持全文索引,5.5后支持全文索引
8、对硬件资源要求还是比较高的场合
9、行级锁定,但是全表扫描仍然会是表级锁定,如
update table set a=1 where user like '%zhang%';
小贴士:
使用like进行模糊查询时,会进行全表扫描,锁定整个表。
对没有创建索引的字段进行查询,也会进行全表扫描锁定整个表。
使用索引进行查询,则是行级锁定。
InnoDB的特点
InnoDB中不保存表的行数,如 select count() from table; 时,InnoDB需要扫描一遍整个表来计算有多少行,但MyISAM只要简单的读出保存好的行数即可。需要注意的是当count()语句包含where条件时MyISAM也需要扫描整个表。
对于自增长的字段,InnoDB 中必须包含只有该字段的索引,但是在MyISAM表中可以和其他字段一起建立组合索引。
delete清空整个表时,InnoDB 是一行一行的删除,效率非常慢。MyISAM则会重建表。
InnoDB适用生产场景分析
业务需要事务的支持。
行级锁定对高并发有很好的适应能力,但需确保查询是通过索引来完成。
业务数据更新较为频繁的场景。
如:论坛,微博等。业务数据一致性要求较高。
如:银行业务。 硬件设备内存较大,利用InnoDB较好的缓存能力来提高内存利用率,减少磁盘IO的压力。
MyISAM和InnoDB的区别:
MyISAM:不支持事务和外键约束,占用空间较小,访问速度快,表级锁定,适用于不需要事务处理、单独写入或查询的应用场景。(写入和查询不一起使用的场景)
InnoDB:支持事务处理、外键约束、占用空间比MyISAM 大,支持行级锁定,读写开发能力较好,适用于需要事务处理、读写频繁的应用场景。
企业选择存储引擎依据
1、需要考虑每个存储引擎提供了哪些不同的核心功能及应用场景。
2、支持的字段和数据类型
所有引擎都支持通用的数据类型 但不是所有的弓|擎都支持其它的字段类型,如二进制对象. 3、锁定类型:不同的存储引擎支持不同级别的锁定
表锁定:MyISAM 支持
行锁定:InnoDB 支持
小贴士:
在 MySQL 中,存储引擎的锁定类型指的是该存储引擎用于管理并发访问的锁定机制。锁定是数据库管理系统用来控制对数据的访问的一种机制,在多个并发用户同时访问数据库时确保数据的一致性和完整性。
1. MyISAM: MyISAM 存储引擎使用表级锁定(Table-level Locking)。这意味着当一个用户对表执行写操作时,会锁定整个表,导致其他用户无法同时对同一表进行写操作,但允许其他用户进行读操作。这可能会导致并发性能瓶颈,特别是在具有高并发写入操作的环境中。
2. InnoDB: InnoDB 存储引擎使用行级锁定(Row-level Locking)。这意味着它可以更细粒度地控制对数据的访问,只锁定需要修改的行,而不是整个表。这种机制允许多个用户同时对同一表进行读写操作,提高了并发性能和吞吐量。此外,InnoDB 还支持事务(Transactions)和行级锁定的事务隔离级别(Transaction Isolation Levels),从而提供了更高的数据完整性和一致性。
3. Memory(或 Heap): Memory 存储引擎将数据存储在内存中,它使用表级锁定。与 MyISAM 类似,当一个用户对表执行写操作时,会锁定整个表。这种存储引擎适用于需要快速读写速度和临时数据存储的场景,但不适用于大型数据或长期存储。
4. 其他存储引擎: 其他存储引擎如 Archive、CSV、Blackhole 等也可能采用不同的锁定类型,具体取决于存储引擎的设计和实现。
事务概念
事务(Transaction)指的是一个操作序列,该操作序列中的多个操作要么都做,要么都不做,是一个不可分割的工作单位,是数据库环境中的逻辑工作单位,由DBMS(数据库管理系统)中的事务管理子系统负责事务的处理。
目前常用的存储引擎有InnoDB(MySQL5.5以后默认的存储引擎)和MyISAM(MySQL5.5之前默认的存储引擎),其中InnoDB支持事务处理机制,而MyISAM不支持。
事务特性
事务处理可以确保除非事务性序列内的所有操作都成功完成,否则不会永久更新面向数据的资源。通过将一组相关操作组合为一个要么全部成功要么全部失败的序列,可以简化错误恢复并使应用程序更加可靠。 但并不是所有的操作序列都可以称为事务,这是因为一个操作序列要成为事务,必须满足事务的原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这四个特性简称为ACID特性。
(1)原子性:原子是自然界最小的颗粒,具有不可再分的特性。事务中的所有操作可以看做一个原子,事务是应用中不可再分的最小的逻辑执行体。 使用事务对数据进行修改的操作序列,要么全部执行,要么全不执行。通常,某个事务中的操作都具有共同的目标,并且是相互依赖的。如果数据库系统只执行这些操作中的一部分,则可能会破坏事务的总体目标,而原子性消除了系统只处理部分操作的可能性。
(2)一致性:一致性是指事务执行的结果必须使数据库从一个一致性状态,变到另一个一致性状态。当数据库中只包含事务成功提交的结果时,数据库处于一致性状态。一致性是通过原子性来保证的。 例如:在转账时,只有保证转出和转入的金额一致才能构成事务。也就是说事务发生前和发生后,数据的总额依然匹配。
(3)隔离性:隔离性是指各个事务的执行互不干扰,任意一个事务的内部操作对其他并发的事务,都是隔离的。也就是说:并发执行的事务之间既不能看到对方的中间状态,也不能相互影响。
(4)持久性 持久性指事务一旦提交,对数据所做的任何改变,都要记录到永久存储器中,通常是保存进物理数据库,即使数据库出现故障,提交的数据也应该能够恢复。但如果是由于外部原因导致的数据库故障,如硬盘被损坏,那么之前提交的数据则有可能会丢失。
事务并发问题
1.脏读(Dirty read)
当一个事务正在访问数据并且对数据进行了修改,而这种修改还没有提交到数据库中,这时另外一个事务也访问了这个数据,然后使用了这个数据。因为这个数据是还没有提交的数据,那么另外一个事务读到的这个数据是“脏数据”,依据“脏数据”所做的操作可能是不正确的。
2.不可重复读 (Unrepeatableread)
指在一个事务内多次读同一数据。在这个事务还没有结束时,另一个事务也访问该数据。那么,在第一个事务中的两次读数据之间,由于第二个事务的修改导致第一个事务两次读取的数据可能不太一样。这就发生了在一个事务内两次读到的数据是不一样的情况,因此称为不可重复读。
- 幻读 (Phantom read)
- 幻读与不可重复读类似。它发生在一个事务(T1)读取了几行数据,接着另一个并发事务(T2)插入了一些数据时。在随后的查询中,第一个事务(T1)就会发现多了一些原本不存在的记录,就好像发生了幻觉一样,所以称为幻读。
事务隔离级别
事务的隔离级别用于决定如何控制并发用户读写数据的操作。数据库是允许多用户并发访问的,如果多个用户同时
开启事务并对同一数据进行读写操作的话,有可能会出现脏读、不可重复读和幻读问题,所以MySQL中提供了四种隔离级别来解决上述问题。
事务的隔离级别从低到高依次为READ UNCOMMITTED、READ COMMITTED、REPEATABLE READ以及SERIALIZABLE,隔离级别越低,越能支持高并发的数据库操作。
事务总结
在MySQL中,事务通常用于以下场景:
1、订单处理:当用户下订单时,我们需要确保库存数量、金额等信息的正确性。如果出现错误,我们需要回滚订单,撤销库存的更改。
2、银行转账:当进行银行转账操作时,我们需要确保账户余额的正确性。如果出现错误,我们需要回滚转账操作,撤销资金的更改。
3、数据更新:当我们需要更新多个表中的数据时,我们可以使用事务来确保数据的一致性。例如,我们先更新一个表中的数据,然后再更新另一个表中的数据。如果在这个过程中出现了错误,我们可以回滚整个事务,撤销所有的更改。