一、初识MySql
数据库:按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享 的、统一管理的大量数据的集合;
OLTP:联机事务处理,主要是对数据库的增删改查。 OLTP 主要用来记录某类业务事件的发生,数据会以增删改的方式在数据库中进行数据的更新处理 操作,要求实时性高、稳定性强、确保数据及时更新成功;
OLAP:联机分析处理,主要是对数据库的查询。 当数据积累到一定的程度,我们需要对过去发生的事情做一个总结分析时,就需要把过去一段时间内产生的数据拿出来进行统计分析,从中获取我们想要的信息。
二、SQL语句
定义:结构化查询语言(Structured Query Language) 简称 SQL,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。SQL 是关系数据库 系统的标准语言。 关系型数据库包括:MySQL, SQL Server, Oracle, Sybase, postgreSQL 以及 MS Access等; SQL 命令包括:DQL、DML、DDL、DCL以及TCL;
DQL:数据查询语言,只包含select :从一个或者多个表中检索特定的记录;
DML:数据操作语言:包含 insert :插入记录; update :更新记录; delete :删除记录;
DDL:数据定义语言:包含 create :创建一个新的表、表的视图、或者在数据库中的对象; alter :修改现有的数据库对象,例如修改表的属性或者字段; drop :删除表、数据库对象或者视图;
DCL:数据控制语言:包含 grant :授予用户权限; revoke :收回用户权限;
TCL:事务控制语言:包含 commit :事务提交; rollback :事务回滚;
三、数据库术语
数据库:数据库是一些关联表的集合;
数据表:表是数据的矩阵;
列:一列包含相同类型的数据;
行:记录的是一组相关数据;
主键:主键是唯一的,一个数据表只能包含一个主键;
外键:外键用来关联两个表,来保证参照完整性;MyISAM 存储引擎本身并不支持外键,只起到注释作用;而 innoDB 完整支持外键;
复合键:或称组合键,将多个列作为一个索引键;
索引:用于快速访问数据表的数据,索引是对表中的一列或者多列的值进行排序的一种结构;
四、MySql的体系结构
其中包含连接池组件、管理服务和工具组件、SQL 接口组件、查询分析器组件、优化器组件、缓冲组件、插件式存储引擎、物理文件等。
MySql内部连接池:管理缓冲用户连接、用户名、密码、权限校验、线程处理等需要缓存的需求。需要注意的是,它并未使用Reactor模型而是采用了IO多路复用的select + 阻塞的IO。并且他的命令处理是多线程并发处理的;
管理服务和工具组件:系统管理和控制工具,例如备份恢复、MySQL 复制、集群等;
SQL 接口组件:将 SQL 语句解析生成相应对象;DML,DDL,存储过程,视图,触发器等;
查询分析器组件:将 SQL 对象交由解析器验证和解析,并生成语法树;
优化器组件:SQL 语句执行前使用查询优化器进行优化;
缓冲组件:当数据库进行读取页的操作的时候,他会将磁盘中读取到的页,存放到内存中,这样当下次再读取相同的页,首先会检查内存中有没有这个页,如果没有再重新读取。但是由于并未提升很大的效率,后面8.0版本已经删除。
五、数据库设计的三范式
为了建立冗余较小、结构合理的数据库,设计数据库时必须遵循一定的规则。在关系型数据库中这种规则就称为范式。范式是符合某一种设计要求的总结。要想设计一个结构合理的关系型数据库, 必须满足一定的范式。因此三范式是为了减少空间占用。
范式一:确保每列保持原子性,数据库表中的所有字段都是不可分解的原子值;
范式二:满足范式一的基础上,确保表中的每列都和主键完全依赖,而不能只与主键的某一部分依赖(组合索引);
范式三:满足范式二的基础上,确保每列都和主键直接相关,而不是间接相关;减少数据冗余;
但是对于特殊情况下,没有必要做三范式,可能会导致数据库业务涉及的表变多,并且造成更多的联表查询,将导致整个系统的性能降低;因此基于性能考虑,可能需要进行反范式设计;
六、具体命令
1、五大约束:
not null:非空约束
auto_increment:自增约束
unique:唯一约束
primary:主键约束,非空且唯一
foreig:外键约束
2、删除数据:
drop(DDL):速度快,删除整张表结构和表数据,包括索引,约束,触发器等。但是删除后不能回滚,会进行释放空间。
truncate(DDL):速度比较快,会删除表数据,其他字段会保留(自增字段置为1),但是也不能回滚,会释放空间,以页单位进行删除。
delete(DML):速度慢,删除部分字段或者全部字段,其他保留,他是一个条件删除,可以进行回滚,是标记删除(实际并未删除),可以进行逐行删除。
3、去重:
我们可以根据具体的命令进行去重,操作包括:group by column,select distinct column。
4、条件判断:
首先条件判断有where,group by ... having , ... join ... on ...。这三种都可以。
# 创建数据库
CREATE DATABASE `数据库名` DEFAULT CHARACTER SET utf8; # 字符集设置为 utf8
# 删除数据库
DROP DATABASE `数据库名`;
# 选择数据库
USE `数据库名`;
# 创建表
CREATE TABLE `table_name` (column_name column_type);
CREATE TABLE IF NOT EXISTS `0voice_tbl` (
`id` INT UNSIGNED AUTO_INCREMENT COMMENT '编号',
`course` VARCHAR(100) NOT NULL COMMENT '课程',
`teacher` VARCHAR(40) NOT NULL COMMENT '讲师',
`price` DECIMAL(8,2) NOT NULL COMMENT '价格',
PRIMARY KEY ( `id` ), ## not null unique
)ENGINE=innoDB DEFAULT CHARSET=utf8 COMMENT = '课程表';
# 删除表
DROP TABLE `table_name`; # 把数据和表都删除
# 清空数据列
TRUNCATE TABLE `table_name`; -- 截断表 以页为单位(至少有两行数据),有自增索引的话,从初始值开始累加
DELETE TABLE `table_name`; -- 逐行删除,有自增索引的话,从之前值继续累加
# 增
INSERT INTO `table_name`(`field1`, `field2`, ..., `fieldn`) VALUES (value1,value2, ..., valuen);
INSERT INTO `0voice_tbl` (`course`, `teacher`, `price`) VALUES ('C/C++Linux服务器开发/高级架构师', 'Mark', 7580.0);
# 删
DELETE FROM `table_name` [WHERE Clause];
DELETE FROM `0voice_tbl` WHERE id = 3;
# 改
UPDATE table_name SET field1=new_value1, field2=new_value2 [, fieldn=new_valuen]
UPDATE `0voice_tbl` SET `teacher` = 'Mark' WHERE id = 2;
-- 累加
UPDATE `0Voice_tbl` set `age` = `age` + 1 WHERE id = 2;
# 查
SELECT field1, field2,...fieldN FROM table_name [WHERE Clause]
七、高级查询
1、分组聚合
sum():计算某列的总和
avg():计算某列的平均值
max():计算某列的最大值
min():计算某列的最小值
count():计算某列的行数
-- 分组加group_concat
SELECT `gender`, group_concat(`age`) as ages FROM `student` GROUP BY `gender`;
-- 可以把查询出来的结果根据某个条件来分组显示
SELECT `gender` FROM `student` GROUP BY `gender`;
-- 分组加聚合
SELECT `gender`, count(*) as num FROM `student` GROUP BY `gender`;
-- 分组加条件
SELECT `gender`, count(*) as num FROM `student` GROUP BY `gender` HAVING num > 6;
2、联表查询
INNER JOIN:只取两张表有对应关系的记录。
SELECT
cid
FROM
`course`
INNER JOIN `teacher` ON course.teacher_id = teacher.tid;
LEFT JOIN:在内连接的基础上保留左表没有对应关系的记录。
SELECT
course.cid
FROM
`course`
LEFT JOIN `teacher` ON course.teacher_id = teacher.tid;
REIGHT JOIN:
SELECT
course.cid
FROM
`course`
RIGHT JOIN `teacher` ON course.teacher_id = teacher.tid;
3、子查询
IN 关键字:运算符可以检测结果集中是否存在某个特定的值,如果检测成功就执行外部的查询。
EXISTS 关键字:内层查询语句不返回查询的记录。而是返回一个真假值。如果内层查询语句查询 到满足条件的记录,就返回一个真值( true ),否则,将返回一个假值( false )。当返回的值 为 true 时,外层查询语句将进行查询;当返回的为 false 时,外层查询语句不进行查询或者查 询不出任何记录。
ALL 关键字:表示满足所有条件。使用 ALL 关键字时,只有满足内层查询语句返回的所有结果,才 可以执行外层查询语句。
ANY 关键字:允许创建一个表达式,对子查询的返回值列表,进行比较,只要满足内层子查询中 的,任意一个比较条件,就返回一个结果作为外层查询条件。
在 FROM 子句中使用子查询:子查询出现在 from 子句中,这种情况下将子查询当做一个临时表 使用。
select * from student where class_id in (select cid from course where teacher_id= 2);
select * from student where exists(select cid from course where cid = 5);
SELECT
student_id,
sname
FROM
(SELECT * FROM score WHERE course_id = 1 OR course_id = 2) AS A
LEFT JOIN student ON A.student_id = student.sid;
八、视图和触发器
1、视图
定义:视图( view )是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。其内容由查询定义。 基表:用来创建视图的表叫做基表; 通过视图,可以展现基表的部分数据;视图数据来自定义视图的查询中使用的表,使用视图动态生成;
简单:使用视图的用户完全不需要关心后面对应的表的结构、关联条件和筛选条件,对用户来说已经是过滤好的复合条件的结果集。
安全:使用视图的用户只能访问他们被允许查询的结果集,对表的权限管理并不能限制到某个行某个列,但是通过视图就可以简单的实现。
数据独立:一旦视图的结构确定了,可以屏蔽表结构变化对用户的影响,源表增加列对视图没有影响;源表修改列名,则可以通过修改视图来解决,不会造成对访问者的影响。
CREATE VIEW view_test1 AS SELECT
A.student_id
FROM
(
SELECT
student_id,
num
FROM
score
WHERE
course_id = 1
) AS A
LEFT JOIN (
SELECT
student_id,
num
FROM
score
WHERE
course_id = 2
) AS B
ON A.student_id = B.student_id
WHERE
A.num >
IF (isnull(B.num), 0, B.num);
作用:可复用,减少重复语句书写;类似程序中函数的作用; 重构利器 假如因为某种需求,需要将 user 拆成表 usera 和表 userb;如果应用程序使用 sql 语句: select * from user 那就会提示该表不存在;若此时创建视图 create view user as select a.name,a.age,b.sex from usera as a, userb as b where a.name=b.name; ,则只需要更改数据库结构,而不需要更改应用程序; 逻辑更清晰,屏蔽查询细节,关注数据返回; 权限控制,某些表对用户屏蔽,但是可以给该用户通过视图来对该表操作;
2、触发器
定义:触发器(trigger)是 MySQL 提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比 如当对一个表进行 DML 操作( insert , delete , update )时就会激活它执行。
监视对象: table
监视事件: insert 、 update 、 delete
触发时间: before , after
触发事件: insert 、 update 、 delete
CREATE TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body -- 此处写执行语句
-- mysql c/c++ function udf 动态库
-- trigger_body: 可以一个语句,也可以是多个语句;多个语句写在 BEGIN ... END 间
-- trigger_time: { BEFORE | AFTER }
-- trigger_event: { INSERT | UPDATE | DELETE }
-- trigger_order: { FOLLOWS | PRECEDES } other_trigger_name
NEW和OLD:在 INSERT 型触发器中, NEW 用来表示将要( BEFORE )或已经( AFTER )插入的新数据; 在 DELETE 型触发器中, OLD 用来表示将要或已经被删除的原数据;在 UPDATE 型触发器中, OLD 用来表示将要或已经被修改的原数据, NEW 用来表示将要或已经修 改为的新数据;
NEW.columnName (columnName为相应数据表某一列名)
OLD.columnName (columnName为相应数据表某一列名)
感谢大家的收看!0voice · GitHub