diff --git "a/02 \346\236\227\351\221\253/20231024\345\244\215\344\271\240.md" "b/02 \346\236\227\351\221\253/20231024\345\244\215\344\271\240.md" new file mode 100644 index 0000000000000000000000000000000000000000..80238564352812a241a625232aaf7d214f908d7c --- /dev/null +++ "b/02 \346\236\227\351\221\253/20231024\345\244\215\344\271\240.md" @@ -0,0 +1,418 @@ +1.visio + +Visio的用法,在创建数据库之前可以用Visio先建立一个框架,让建立数据库的模型变得简单。 + + + +2.数据库中表与表之间的关系 + +一对一的关系,任意一个表的主键放在另一个表中当外键 一对多的关系,将一的主键放在多的表里当外键 + +多对多的关系,第三张表将前面两张表的主键放在第三张表当外键 + + + +3.数据库的三大范式 + +第一范式:要求每个字段(属性)都分割至不可在分割 第二范式:在第一字段的基础上,_非主键字段要依赖于主键_(有联合主键时,非主键要同时完全依赖于这两个主键,不能部分依赖) 第三范式:在第二范式的基础上,非主键字段要直接依赖主键 + + + +4.RABC的基础概念 + +用户通过角色和权限进行关联,一个用户拥有多个角色,一个角色拥有多个权限,都是多对多的关系。 + +SPU是标准产品单位,SPU 描述一个产品的各种特性。 + +SKU 库存进出计量的单位 + +要用中间表将产品的属性属性值产生关系 + + + +5.视图 + +语法:create view 视图名 as select*from...... 一般不能进行增删改 + +使用视图:select *from 视图名 可以直接当表使用 + +修改视图:1.CREATE OR REPLACE VIEW 视图名 AS 查询。。。。; + +ALTER VIEW 视图名 AS 查询。。。。。; + +删除视图:DROP VIEW 视图名 , 视图名; + +查看视图结构:desc 视图名; + +```sql + +使用表emps创建视图employee_vu, +#其中包括姓名(LAST_NAME),员工号(EMPLOYEE_ID),部门号(DEPARTMENT_ID) + +CREATE view employee_vu(姓名,员工号,部门号) AS +SELECT LAST_NAME,EMPLOYEE_ID,DEPARTMENT_ID FROM employees; + +要求将视图 emp_v1 修改为查询电话号码以‘011’开头的并且邮箱中包含 e 字符 +#的员工姓名和邮箱、电话号码 +CREATE or REPLACE view emp_v1(员工姓名,工资,邮箱,电话号码) AS +SELECT LAST_NAME,salary,email,phone_number FROM employees WHERE phone_number like '011%' and email like '%e%'; +``` + +6.函数 + +rand() 生成随机数; length() 返回字符数; concat() 拼接字符串; 变种,concat_ws + +replace(str,a,b) 将b替换成a; + +upper() 将小写字母替换成大写,lower()相反; + +left()从左边开始截取,righ()相反; + +截取字符串,substr(),substring(),mid() + +substr(123456,3,3)从第3位开始,截取3位,MySQL中索引从第一位数开始; + +去除空格 + +左右都去,trim;左边,ltrim;右边,rtrim; +select curdate(); -- 返回当前日期 +select curtime(); -- 返回当前时间 +select now(); -- 返回当前日期和时间 + +select year('2012-12-2'); -- 提取当前年份(需保证时间准确性) +select month('2012-12-2'); -- 提取当前月份(需保证时间准确性) +select day('2012-12-2'); -- 提取当前日期(需保证时间准确性) + +SELECT DATE_ADD(NOW(), interval 20 year/month/day); -- 返回当前时间经过20年/月/日的时间 + +select datediff('2022-12-2','2022-1-2'); -- 返回两个时间之间的天数 + + + +7.存储 + +创建存储的语句create procedure 名称()begin.........end; +调用call test(); +删除 DROP PROCEDURE [ IF EXISTS ] 存储过程名称; + + + + +8.流程控制 + +if分支结构 + +语法 + +if 条件 then sql语句 + +elseif 条件2 then 语句2 + +。。。。。。 + +else 语句 + +end if + +不能在select后面 + +case分支结构 + +语法 + +case when 条件 then 结果或语句 + +。。。。。 + +then后面写语句要加;,直接写结果不用加; + +case 表达式 + +when 值1 then 结果或语句 + +。。。。。 + +。。。。 + +else 。。。。 + +end case; + +```sql +题目 +创建函数test_if_case(),实现传入成绩,如果成绩>90,返回A,如果成绩>80,返回B,如果成绩>60,返回C,否则返回D-- #要求:分别使用if结构和case结构实现 +CREATE DATABASE a charset utf8; +use a; +#方式1:if +delimiter // +CREATE PROCEDURE test_if_case(in score int) +BEGIN if score>90 then SELECT 'A'; +ELSEIF score>80 then SELECT 'B'; +ELSEIF score>60 then SELECT 'C'; +else SELECT 'D'; +END if; +END // +delimiter + +call test_if_case(100); + +#方式2: +case when ...DROP PROCEDURE test_if_case; +delimiter // +CREATE PROCEDURE test_if_case(in score int) +BEGIN case when score>90 then SELECT 'A'; + when score>80 then SELECT 'B'; +when score>60 then SELECT 'C'; +ELSE SELECT 'D'; + end case; +end // +delimiter + +call test_if_case(100); +``` + +9.循环过程 + +loop 可以用其来实现简单的死循环 + +语法 + +[loop:label] loop + +循环执行的语句 + +end [loop:label] + +while 先判定条件,如果条件为true,则执行,否则不执行 + +语法 + +WHILE 条件 DO 循环执行的语句 + +END WHILE; + +repeat 先执行一次逻辑,然后判定UNTIL条件是否满足,如果满足,则退出。如果不满足,则继续下一次循环 + +语法 REPEAT 循环执行的语句 + +UNTIL 条件 END REPEAT; + +leave 可以用在loop while repeat 这些循环里 ,也可以直接在begin end之间,但不论在哪里,都要跟上标识符 + +interate 相当于contion + +```sql +题目 +-- 写一个存储过程,可以输入一个整数,输入小于或等于0时,提示非法输入,并中止这个存储过程, +-- -- 否则先判断这个数和是不是大于5,如果大于5就从1循环到这个数,并找出所有的偶数)。小于等于5就提示数太小了,并退出。 +-- 要求,循环部分,要用三种语法分别做一遍 +CREATE DATABASE hhh charset utf8; +use hhh; +drop PROCEDURE a +delimiter // +CREATE PROCEDURE a(in num int) +BEGIN +DECLARE i int DEFAULT 1; + if num<=0 then SELECT '非法输入'; + elseif num<=5 then SELECT '太小了'; + else + a:loop + if i%2=0 then SELECT i; + end if; + set i =i+1; + if numnum end REPEAT; + end if; +end // +delimiter; +call a(7); +``` + +10.存储函数和游标 + +存储函数的使用 + +function + +语法 + +create function 函数名 (参数名 参数类型) 函数没有模式 + +........ + +begin + +    函数体,当中肯定有return语句 可以写变量,循环,判断 + +end + +游标 + +定义游标 + +declare ub cursor for ...... + +打开游标 + +open ub + +使用游标 + +fetch ub into xx; 从游标里取值赋值给变量,有几个值就要有几个变量 + + + + + +11.触发器 + +```sql +CREATE TRIGGER 触发器名称 +{BEFORE|AFTER} {INSERT|UPDATE|DELETE} ON 表名 +FOR EACH ROW +触发器执行的语句块; + + +DELIMITER // + +CREATE TRIGGER before_insert_test_tri +BEFORE INSERT ON test_trigger +FOR EACH ROW +BEGIN + INSERT INTO test_trigger_log(t_log) + VALUES('before insert...'); +END // + +DELIMITER ; + + +查看当前数据库的所有触发器的定义 +SHOW TRIGGERS; + +查看当前数据库中某个触发器的定义 +SHOW CREATE TRIGGER salary_check_trigger; + + +删除触发器 +DROP TRIGGER IF EXISTS after_insert_test_tri; +``` + +12.窗口函数 + +```sql +窗口函数名称(参数) over(partition by ... order by... 窗口大小) + +开窗聚合函数 +sum()|avg()|min()|max()|count()| over (partition by ... order by...) +前后函数 +select lag(deptno,1) over() from dept; -- 返回当前行前一行的值 +select lead(deptno,1) over() from dept; -- 返回当前行前一行的值 +头尾函数 +select first_value(deptno) over() from dept; -- 返回当前列的第一个值 +select last_value(deptno) over() from dept; -- 返回当前列的最后一个值 +``` + +普通公用表表达式 WITH CTE名称 AS (子查询) SELECT|DELETE|UPDATE 语句; + +递归公用表表达式 WITH RECURSIVE CTE名称 AS (子查询) SELECT|DELETE|UPDATE 语句; + +13.索引 + +```sql +索引的分类 +主键索引:primary key +设定为主键后,数据库自动建立索引,InnoDB为聚簇索引,主键索引列值不能为空(Null)。 +唯一索引: +索引列的值必须唯一,但允许有空值(Null),但只允许有一个空值(Null)。 +复合索引: +一个索引可以包含多个列,多个列共同构成一个复合索引。 +全文索引: +全文索引类型为FULLTEXT,在定义索引的列上支持值的全文查找允许在这些索引列中插入重复值和空值。全文索引可以在Char、VarChar 上创建。 + + +#建表时,主键默认为索引 +create table user( + id varchar(11) primary key, + name varchar(20), + age int +) +#查看user表中的索引 +show index from user +#创建单列索引,只能包含一个字段 +create index name_index on user(name) +#创建唯一索引,只能有一个列 +create unique index age_index on user(age); +#复合索引 +create index name_age_index on user(name,age); +explain 执行计划 +可用于查看某个查询语句的执行详细情况 +语法: + + explain select ... from ...... +索引的使用 +如果使用了联合索引,要遵守最左前缀法则。 +``` + +14.事务 + +```sql +事务的特性 +原子性 一致性 隔离性 持久性 +事务分为隐式事务和显式事务 +## 方法1:通过set autocommit = 0关闭事务自动提交 +# 查询是否开启事务自动提交,1:事务自动提交;2:事务不自动提交 +SELECT @@autocommit; +# 关闭事务自动提交 +SET autocommit = 0; +## 方法2: START TRANSACTION命令 +# 开启一个事务,使用这个命令之后,事务要使用commit或者commit work命令才会提交 +START TRANSACTION; +只读事务 +start transaction read only; + +savepoint关键字 +可以将一大批操作分为几个部分,然后指定回滚某个部分。可以使用savepoin来实现 + +隔离级别分为4种: +读未提交:READ-UNCOMMITTED +读已提交:READ-COMMITTED +可重复读:REPEATABLE-READ +串行:SERIALIZABLE +```