一、引言
一个应用是怎样调用数据库的呢?答案如下图
数据库通常分为: 层次式数据库; 网络式数据库; 关系式数据库三种类型
可以看出对数据库的学习关注点集中在数据库引擎和数据库操作(存储、查找删除等)上
二、数据库引擎
1、作用:
数据库中的存储引擎其实是对使用了该引擎的表进行某种设置,数据库中的表设定了什么存储引擎,那么该表在数据存储方式、数据更新方式、数据查询性能以及是否支持索引等方面就会有不同的“效果”。
2、MySQL数据库引擎介绍:
(ISAM、MyISAM、HEAP(也称为MEMORY)、CSV、BLACKHOLE、ARCHIVE、PERFORMANCE_SCHEMA、InnoDB、Berkeley、Merge、Federated和Cluster/NDB等,除此以外我们也可以参照MySQL++ API创建自己的数据库引擎)
ISAM:一个定义明确且历经时间考验的数据表格管理方法,它在设计之时就考虑到 数据库被查询的次数要远大于更新的次数。因此,ISAM执行读取操作的速度很快,而且不占用大量的内存和存储资源。ISAM的两个主要不足之处在于,它不 支持事务处理,也不能够容错
MyISAM:是为了查和增加,效率高。所有功能都围绕这这个,如果表的读操作远远多于写操作且不需要数据库事务的支持,那么MyIASM也是很好的选择。
Innodb:引擎功能更强(事务等)效率低一些。支持事务和行级锁
Innodb引擎提供了对数据库ACID事务的支持,并且实现了SQL标准的四种隔离级别,关于数据库事务与其隔离级别的内容请见数据库事务与其隔离级别这篇文章。该引擎还提供了行级锁和外键约束,它的设计目标是处理大容量数据库系统,它本身其实就是基于MySQL后台的完整数据库系统,MySQL运行时Innodb会在内存中建立缓冲池,用于缓冲数据和索引。但是该引擎不支持FULLTEXT类型的索引,而且它没有保存表的行数,当SELECT COUNT(*) FROM TABLE时需要扫描全表。当需要使用数据库事务时,该引擎当然是首选。由于锁的粒度更小,写操作不会锁定全表,所以在并发较高时,使用Innodb引擎会提升效率。但是使用行级锁也不是绝对的,如果在执行一个SQL语句时MySQL不能确定要扫描的范围,InnoDB表同样会锁全表。
3、MyISAM与InnoDB的选择 -推荐参考-详细
MyISAM:默认表类型,它是基于传统的ISAM类型,ISAM是Indexed Sequential Access Method (有索引的顺序访问方法) 的缩写,它是存储记录和文件的标准方法。不是事务安全的,而且不支持外键,如果执行大量的select,insert MyISAM比较适合。
InnoDB:支持事务安全的引擎,支持外键、行锁、事务是他的最大特点。如果有大量的update和insert,建议使用InnoDB,特别是针对多个并发和QPS较高的情况。
三、数据库存储
1、存储过程:
将常用的或很复杂的工作,预先用SQL语句写好并用一个指定的名称存储起来, 那么以后要叫数据库提供与已定义好的存储过程的功能相同的服务时,只需调用execute,即可自动完成命令。——属于自定义操作避免反复操作
2、使用存储过程优点
以后在执行不用重编译,提高执行速度——可重复性
进行复杂操作时,可将复杂操作封装起来与数据库提供的事物处理结合起来一起使用——简化
可设定某个用户对指定存储过程的使用权——安全性高
具体存储过程语法,参看以下两个链接:
四、数据库索引(参考链接)
1、简介:
索引是对记录按照多个字段进行排序的一种方式。对表中的某个字段建立索引会创建另一种数据结构,其中保存着字段的值,每个值又指向与它相关的记录。这种索引的数据结构是经过排序的,因而可以对其执行二分查找。
缺点是占用额外的磁盘空间
2、数据结构:
假如有一亿条数据,常规查找算法复杂度是O(n),且一亿次的匹配大量消耗磁盘的IO和CPU
如果把表转换成平衡树结构,假设数有10层,只需10次就可以找到所需数据,算法的复杂度就是O(log n)
常用的数据机构有:b tree或者 b+ tree(平衡树)、哈希桶建立索引
以下是两种索引聚焦索引和非聚焦索引查找过程:
通过聚集索引可以查到需要查找的数据, 而通过非聚集索引可以查到记录对应的主键值 , 再使用主键的值通过聚集索引查找到需要的数据
例子:
//建立索引
create indexindex_birthdayonuser_info(birthday);
//查询生日在1991年11月1日出生用户的用户名
select user_name from
user_info where birthday = '1991-11-1'
这句SQL语句的执行过程如下
首先,通过非聚集索引index_birthday查找birthday等于1991-11-1的所有记录的主键ID值
然后,通过得到的主键ID值执行聚集索引查找,找到主键ID值对就的真实数据(数据行)存储的位置
最后, 从得到的真实数据中取得user_name字段的值返回, 也就是取得最终的结果
我们把birthday字段上的索引改成双字段的覆盖索引
create index
index_birthday_and_user_name on user_info(birthday, user_name);
这句SQL语句的执行过程就会变为
通过非聚集索引index_birthday_and_user_name查找birthday等于1991-11-1的叶节点的内容,然而, 叶节点中除了有user_name表主键ID的值以外, user_name字段的值也在里面, 因此不需要通过主键ID值的查找数据行的真实所在, 直接取得叶节点中user_name的值返回即可。
五、数据库优化
对于mysql数据库来说,索引的使用是很巧妙的。它设置的好可以提高速度,设置的不好不光无法提高速度,还会造成浪费内存空间。在优化方面
1、分区-硬件上除了本身性能
分区将数据在物理上分隔开,不同分区的数据可以制定保存在处于不同磁盘上的数据文件里。这样,当对这个表进行查询时,只需要在表分区中进行扫描,而不必进行全表扫描,明显缩短了查询时间,另外处于不同磁盘的分区也将对这个表的数据传输分散在不同的磁盘I/O,做到硬盘之间I/O负载均衡
2、索引-数据库设计
对一个大型表进行分区之后,可以根据相应的分区建立分区索引。但是个人觉得不是所有的表都需要建立索引,只针对大数据量的表建立索引。应尽量避免全表扫描,首先应考虑在 where 及 order by ,group by 涉及的列上建立索引。
3、别名的使用-小的优化
别名是大型数据库的应用技巧,就是表名、列名在查询中以一个字母为别名,查询速度要比建连接表快1.5倍。
4、优化语句-自身
查询尽可能使用 limit 减少返回的行数,减少数据传输时间和带宽浪费;任何地方都不要使用 select * from table ,用具体的字段列表代替“*”,不要返回用不到的任何字段。