数据库是一种按照数据结构来组织、存储和管理数据的仓库;是一个长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。
关于数据库的工作,主要分为两种:OLTP和OLAP。
OLTP(online transaction processing)翻译为联机事务处理,主要是对数据库进行增删改查。
OLAP(On-Line Analytical Processing)翻译为联机分析处理,组要是对从数据库查询到的数据进行统计分析从中获取我们想要的信息。
SQL:结构化查询语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统。
SQL语言分为:
数据库引擎是表级别的引擎。
MySQL体系结构图如下图所示:
MySQL的组成部分分别是:连接池组件、管理服务和工具组件、SQL接口组件、查询分析器组件、优化器组件、缓冲组件、插件式存储引擎、物理文件。
下面介绍每个组件的用处:
数据库范式就相当于数据库设计领域中的设计模式,是为了设计合理的数据库所遵循的一定的规则。
反范式:
范式可以避免数据冗余,减少数据库的空间和维护数据完整性的麻烦;但是采用数据库范式化设计,可能导致数据库业务涉及的表变多,并且造成更多的联表查询,将导致整个系统的性能降低;因此处于性能考虑,可以适当的违反一下三范式设计原则。
CREATE DATABASE '数据库名' DEFAULT CHARACTER SET utf8;
DROP DATABASE '数据库名';
USE '数据库名'
CREATE TABLE 'table_name' (column_name column_tyjpe);
...
CREATE TABLE IF NOT EXISTS 'runoob_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')
)ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT = '课程表';
DROP TABLE 'table_nanme';
TRUNCATE TABLE 'table_name'; --截断表 以页为单位(至少有两行数据),有自增索引的话,从初始值开始增加
DELETE TABLE 'table_name'; --逐行删除,有自增索引的话,从之前值继续累加
INSERT INTO 'table_name' ('field1','field2',...,'fieldn') VALUES (value1,value2,...,valuen);
INSERT INTO 'Ovoice_tbl' ('course','teacher','price') VALUES ('C/C++Linux服务器开发/高级架构师’, ‘Mark’, 7580.0);
DELETE FROM 'table_name' [WHERE Clause];
DELETE FROM 'Ovoice_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]
查询是使用MySQL的重点,第五部分会详细讲解SQL查询。
先来一道面试题:面试题: 为什么innodb 建议主动创建主键索引,并且以自增的整数作为主键 ?
SELECT * FROM student; -- 全部查询
SELECT ‘sname', 'class_id' FROM student; -- 只查询部分字段
SELECT 'sname' AS '姓名', 'class_id' AS '班级ID' FROM student; -- 别名用法
SELECT DISTINCT ’class_id' FROM student; -- 把查询出来的结果的重复记录去掉
SELECT * FROM 'student' WHERE 'name' = '邓洋洋‘; -- 查询姓名为邓洋洋的学生信息
SELECT * FROM ’student‘ WHERE ‘gender' = '男’ AND 'class_id' = 2; --查询性别为男,并且班级为2的学生的信息
SELECT * FROM 'student' WHERE 'class_id' BETWEEN 1 AND 3; -- 查询班级id1到3的学生的信息
# is null 判断造成索引失效
# 索引 B+ 树
SELECT * FROM 'student' WHERE 'class_id' IS NOT NULL; -- 判断不为空
SELECT * FROM ‘student’ WHERE ’class_id' is NULL; -- 判断为空
SELECT * FROM ‘student’ WHERE ‘gender’ <> ''; -- 判断不为空字符串
SELECT * FROM 'student' WHERE 'gender' = ''; -- 判断为空字符串
-- 使用like关键字,"%"代表任意数量的字符,“_"代表占位符
-- 查询名字为m开头的老师的信息
SELECT * FROM 'teacher' WHERE 'tname' LIKE '谢%';
-- 查询姓名里第二个字为小的老师的信息
SELECT * FROM 'teacher' WHERE 'tname' LIKE '_小%';
-- 分页查询主要用于查看第N条到第M条的信息。通常和排序查询一起用
-- 使用limit关键字,第一个参数表示从几条记录开始显示,第二个参数表示要显示的数目。表中默认第一条记录的参数为0
-- 查询第二条到第三条内容
SELECT * FROM 'student' LIMIT 1,2;
-- 关键字:order by field,asc:升序, desc:将序
SELECT * FROM 'score' ORDER BY 'num' ASC;
-- 按照多个字段排序
SELECT * FROM 'score' ORDER BY 'course_id' DESC, 'num' DESC;
-- 通过聚合函数进行查询
SELECT sum('num') FROM 'score';
SELECT avg('num') FROM 'score';
-- 分组加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;
SELECT
cid
FROM
'course'
INNER JOIN 'teacher' ON course.teacher_id = teacher.tid;
SELECT
course.cid
FROM
'course'
LEFT JOIN 'teacher' ON course.teacher_id = teacher.tid;
SELECT
course.cid
FROM
'course'
RIGHT JOIN 'teacher' ON course.teacher_id = teacher.tid;
当一个查询是另一个查询的条件时,这个查询被称为子查询。
SELECT * FROM 'course' where teacher_id = (SELECT 'tid' FROM 'teacher' WHERE 'tname' = '谢小二老师')
多行子查询,即返回多行记录的子查询
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;
试图(view)是一种虚拟存在的表,是一个逻辑表,本身并不包含数据。其内容由查询定义。
基表是用来创建视图的表。
视图总是显示最新的数据。每当用户查询视图时,数据库引擎通过使用视图的 SQL 语句重建数据。
试图的优点:
CREATE VIEW <试图名> AS <SELECT 语句>
-- 创建视图
-- 查询"C++高级"课程比"音视频"课程成绩高的所有学生的学号;
CREATE VIEW view_test1 AS SELECT
A.student_id
FROM
(
SELECT
student_id,
num
FROM
score
WHERE
course_id = 1
) AS A -- 12
LEFT JOIN (
SELECT
student_id,
num
FROM
score
WHERE
course_id = 2
) AS B -- 11
ON A.student_id = B.student_id
WHERE
A.num >
IF (isnull(B.num), 0, B.num);
IF condition THEN
...
ELSEIF condition THEN
...
ELSE
...
END IF
-- 相当于switch语句
CASE value
WHEN value THEN ...
WHEN value THEN ...
ELSE ...
END CASE
WHILE condition DO
...
END WHILE;
-------------------------
-- LEAVE语句退出循环或程序块,只能和BEGIN ... END,LOOP,REPEAT,WHILE语句配合使用
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE example_leave(OUT sum INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE s INT DEFAULT 0;
while_label:WHILE i<=100 DO
SET s = s+i;
SET i = i+1;
IF i=50 THEN
-- 退出WHILE循环
LEAVE while_label;
END IF;
END WHILE;
SET sum = s;
END
//
DELIMITER;
-- 调用存储过程
CALL example_leave(@sum);
SELECT @sum;
-- 相当于break
LEAVE label;
-- 相当于continue
ITERATE label
-- 相当于while(true) {...}
LOOP
...
END LOOP
-- 可以通过LEAVE语句退出循环
--------------------
-- 创建存储过程
DELIMITER //
CREATE PROCEDURE example_loop(OUT sum INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE s INT DEFAULT 0;
loop_label:LOOP
SET s = s+i;
SET i = i+1;
IF i>100 THEN
-- 退出LOOP循环
LEAVE loop_label;
END IF;
END LOOP;
SET sum = s;
END
//
DELIMITER ;
-- 调用存储过程
CALL example_loop(@sum);
SELECT @sum;
-- 相当于do .. while(condition)
REPEAT
...
UNTIL condition
END REPEAT
--------------------------
DELIMITER //
CREATE PROCEDURE example_repeat(OUT sum INT)
BEGIN
DECLARE i INT DEFAULT 1;
DECLARE s INT DEFAULT 0;
REPEAT
SET s = s+i;
SET i = i+1;
UNTIL i > 100
END REPEAT;
SET sum = s;
END
//
DELIMITER ;
-- 调用存储过程
CALL example_repeat(@sum);
SELECT @sum;
触发器(trigger)是MySQL提供给程序员和数据分析员来保证数据完整性的一种方法,它是与表事件相关的特殊的存储过程,它的执行不是由程序调用,也不是手工启动,而是由事件来触发,比如当对一个表进行DML操作( insert , delete , update )时就会激活它执行。
触发器四要素:
语法:
CREATE TRIGGER trigger_name
trigger_time trigger_event
ON tbl_name FOR EACH ROW
[trigger_order]
trigger_body -- 此处写执行语句
-- trigger_body:可以写一个语句,也可以是多个语句:多个语句写在BEGIN ... END间
-- trigger_time:{BEFORE | AFTER}
-- trigger_event:{INSERT | UPDATE | DELETE}
-- trigger_order:{FOLLOWS | PRECEDES} other_trigger_name
SQL语句需要先编译然后执行,而存储过程(Stored Procedure)是一组为了完成特定功能的SQL语句集,经编译后存储在数据库中,用户通过指定存储过程的名字并给定参数(如果该存储过程带有参数)来调用执行它。存储过程是可编程的函数,在数据库中创建并保存,可以由SQL语句和控制结构组成。当想要在不同的应用程序或平台上执行相同的函数,或者封装特定功能时,存储过程是非常有用的。数据库中
的存储过程可以看做是对编程中面向对象方法的模拟,它允许控制数据的访问方式。
语法:
CREATE PROCEDURE 过程名([[IN|OUT|INOUT] 参数名 数据类型[,[IN|OUT|INOUT] 参数名 数据类型...]]) [特性...] 过程体
存储过程根据需要可能会有输入、输出、输入输出参数,如果有多个参数用","分割开。
MySQL 存储过程的参数用在存储过程的定义,共有三种参数类型 IN , OUT , INOUT 。
IN :参数的值必须在调用存储过程时指定,0在存储过程中修改该参数的值不能被返回,可以设
置默认值
OUT :该值可在存储过程内部被改变,并可返回
INOUT :调用时指定,并且可被改变和返回
过程体的开始与结束使用 BEGIN 与 END 进行标识。
游标相当于迭代器。
游标是针对行操作的,对从数据库中 select 查询得到的结果集的每一行可以进行分开的独立的相同或者不相同的操作。对于取出多行数据集,需要针对每行操作;可以使用游标;游标常用于存储过程、函数、触发器、事件;
语法:
-- 定义游标
DECLARE cursor_name CURSOR FOR select_statement;
-- 打开游标
OPEN cursor_name;
-- 取游标数据
FETCH cursor_name INTO var_name[,var_name,......];
-- 关闭游标
CLOSE curso_name;
-- 释放
DEALLOCATE cursor_name;
-- 设置游标结束标志
DECLARE done INT DEFAULT 0;
DECLARE CONTINUE HANDLER FOR NOT FOUND
SET done = 1; -- done为标记
创建用户的语法:
CREATE USER username@host IDENTIFIED BY password; -- 入果是本地用户,host可以使用localhost
授权:
GRANT privileges ON databasename.tablename TO 'username'@'host' WITH GRANT OPTION;
privileges :用户的操作权限,如SELECT , INSERT , UPDATE 等,如果要授予所的权限则使
用ALL;
databasename.tablename 如果是 . 表示任意数据库以及任意表;
WITH GRANT OPTION 这个选项表示该用户可以将自己拥有的权限授权给别人。注意:经常有人在
创建操作用户的时候不指定 WITH GRANT OPTION 选项导致后来该用户不能使用 GRANT 命令创建
用户或者给其它用户授权。
如果不想这个用户有这个 grant 的权限,则不要加该 WITH GRANT OPTION 选项;