Mysql基础2-多表查询和视图

约束

完整性约束

  • 为防止不规范数据进入数据库中,在用户对数据进行插入,修改,删除操作时,MySQL提供了一种机制来检查数据库中的数据是否满足规定的条件
约束条件 约束描述
PRIMARY KEY 主键约束
NOT NULL 非空约束,字段不能为空
UNIQUE 唯一约束,字段值唯一
CHECK 检查约束,检查取值范围
DEFAULT 默认值约束,提供默认值
AUTO_INCREMENT 自动增加约束,约束字段的值自动递增
FOREIGN KEY 外键约束,约束表与表之间关系
  • 列级约束
CREATE TABLE t_student(
sno INT(4) PRIMARY KEY AUTO_INCREMENT,
sname VARCHAR(5) NOT NULL,
sex CHAR(1) DEFAULT '男' CHECK(sex="男" || sex="女"),
eamil VARCHAR(15) UNIQUE
);
  • 表级约束
CREATE TABLE t_student(
sno INT(4),
sname VARCHAR(5),
sex CHAR(1),
eamil VARCHAR(15),
CONSTRAINT pk_stu PRIMARY KEY (sno),
CONSTRAINT ck_stu_sex CHECK (sex='男'||sex='女'),
);

外键约束

  • 外键约束是用来实现数据库表的参照完整性的,可以使两张表紧密结合起来,特别是针对修改或者删除的级联操作时,会保证数据的完整性
  • 外键是指表中某个字段的值依赖于另一张表中某个字段值,而被依赖的值必须具有主键约束或者唯一约束。被依赖的表称为父表或者主表,设置外键约束的表称为子表或者从表
-- 创建主表
CREATE TABLE t_class(
cno INT(4) PRIMARY KEY auto_increment,
cname VARCHAR(10) NOT NULL,
room CHAR(4)
);
-- 创建子表
CREATE TABLE t_student(
cno INT(4) PRIMARY KEY auto_increment,
sname VARCHAR(5) NOT NULL,
classno int(4)
)
-- 设置外键约束 可以在创建表约束也可以后面添加
CREATE TABLE t_student(
cno INT(4) PRIMARY KEY auto_increment,
sname VARCHAR(5) NOT NULL,
classno int(4),
CONSTRAINT fk_stu_classno FOREIGN KEY (classno) REFERENCES t_class (cno)
)
ALTER TABLE t_student ADD CONSTRAINT fk_stu_classno FOREIGN KEY (classno) REFERENCES t_class (cno)

外键策略

  • no action 不允许操作
-- 先将对应键改为null
UPDATE t_student set classno = NULL WHERE classno = 2
-- 再删除从表
DELETE FROM t_class WHERE cno =2
  • cascade级联操作,操作主表影响从表的外键信息
-- 删除已有的约束
ALTER TABLE t_student DROP FOREIGN KEY fk_stu_classno;
-- 添加新的,再删除或者更改时将已有的置为null
ALTER TABLE t_student ADD CONSISTENT fk_stu_classno FOREIGN KEY (classno) REFERENCES t_class (cno) on UPDATE CASCADE ON DELETE CASCADE
  • set null置空操作
-- 删除已有的约束
ALTER TABLE t_student DROP FOREIGN KEY fk_stu_classno;
-- 置新添加外键约束
ALTER TABLE t_student ADD CONSTRAINT fk_stu_classno FOREIGN KEY (classno) REFERENCES t_class (cno) ON UPDATE CASCADE ON DELETE CASCADE;

函数

MySQL中提供了大量的函数来简化用户对数据库的操作,比如字符串处理,日期的运算,数值的运算

单行函数

  • 单行函数是指对每一条记录输入值进行运算,并得到相应的计算结果,然后返回给用户,也就是说,每条记录作为参数传递,计算得到每条记录返回值
SELECT empno,ename,LOWER(ename),UPPER(iob) FROM emp;
-- 转换大小写
  • 常用单行函数主要包括字段串函数,数值函数,日期与时间函数,流程函数以及其他函数

多行函数

SELECT MAX(empno),MIN(empno),COUNT(empno),SUM(empno),AVG(empno) FROM emp;
-- 计算出总共的数据结果

多表查询

  • 需要对多张表进行查询,而这多张表需要使用外键和主键关联在一起,然后使用连接查询来查询多-张表中满足的要求
  • 连接查询类型 cross natural using on
-- 交叉连接
SELECT * FROM emp CROSS JOIN dept;
-- 缺点没有指定字段所属表,效率低

-- 指定来自哪个表
SELECT e.DEPTNO,e.IOB,d.LOC
FROM emp e
NATURAL JOIN dept d;

-- 自然连接 natural join 缺点:自动匹配表中所有同名列
-- 解决:USING
SELECT *
FROM emp e
INNER JOIN dept d
USING(DEPTNO)

-- using缺点,关联的字段必须是同名的
-- 解决 内连接 ON
SELECT *
FROM emp e
INNER JOIN dept d
ON (e.deptno = d.deptno)

-- 内连接缺点:只显示匹配信息
-- 外连接:可以显示不匹配信息
-- 左外连接 左边全展示
SELECT *
FROM emp e
LEFT OUTER JOIN dept d
ON e.deptno = d.deptno
-- 右外连接 右边全展示
SELECT *
FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno
-- 全外连接 全部展示,MySQL 不支持
SELECT *
FROM emp e
FULL OUTER JOIN dept d
ON e.deptno = d.deptno
-- 解决全外连接
SELECT *
FROM emp e
LEFT OUTER JOIN dept d
ON e.deptno = d.deptno
UNION
SELECT *
FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno

SELECT *
FROM emp e
RIGHT OUTER JOIN dept d
ON e.deptno = d.deptno
INNER JOIN salgrade s
ON e.sal BETWEEN s.losal AND s.hisal;

子查询

单行子查询

  • 执行多条select语句
-- 先执行括号里的,在执行外面的
SELECT * FROM emp WHERE sal > (SELECT sal FROM emp WHERE eanme = 'jack')

多行子查询

-- 查询deptno = 20里的job 在deptno =10里面有的数据
SELECT * FROM emp
WHERE deptno = 20
AND job in (SELECT job FROM emp WHERE deptno =10)

-- 查询任意一个都小
SELECT * 
FROM emp
WHERE sal < ANY(SELECT sal FROM emp WHERE job = 'clerk')
AND job != 'clerk';

事务

事务是用来维护数据库完整性的,它能够保证一系列MySQL操作要么全执行,要么全不执行

CREATE TABLE account(
id INT PRIMARY KEY auto_increment,
uname VARCHAR(10) NOT NULL,
balance DOUBLE
)

SELECT * FROM account;

INSERT INTO account VALUES (null,'小明',2000),(NULL,'丽丽',3000);

-- 丽丽向小明转200
UPDATE account SET balance = balance - 200 WHERE id = 1; 
UPDATE account SET balance = balance + 200 WHERE id = 2;

-- 手动开启事务
START TRANSACTION;
UPDATE account SET balance = balance - 200 WHERE id = 1;
UPDATE account SET balance = balance + 200 WHERE id = 2;
-- 手动回滚 刚才操作回滚
ROLLBACK;
-- 手动提交
COMMIT;

脏读

当一个事务正在访问数据并且对数据进行了修改,而这种修改还没提交到数据库中,这时另一个事务也访问了这个数据,因为这个数据还没提交,另一个事务访问到的是脏数据,依据脏数据做的操作时不正确的

不可重复读

指在一个事务内多次读同一数据,在这个事务还没结束时,另一个事务也访问了数据,在第一个事务多次读数据之间,第二个的修改导致第一个事务两次读取不一样,因此称为不可重复读

幻读

幻读与不可重复读类似,它发生在一个事务读取了几行数据,另一个事务插入一些数据时。在随后的查询中,第一个事务就会发现多了一些原本不存在的记录

事务隔离

解决脏读,不可重复读,幻读问题

隔离级别 脏读 不可重读读 幻读
READ UNCOMMITTED
READ COMMITTED ×
REPEATABLE READ × ×
SERIALIZABLE × × ×
-- 查看默认事务隔离级别
SELECT @@transaction_isolation;

-- 设置隔离级别
SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED;
SET SESSION TRANSACTION ISOLATION LEVEL REPEATABLE READ;

视图

将多个表整合到一个视图中,这样只用关注数据结构而不用关注表之间联系

-- 创建视图 可以修改表中数据
CREATE VIEW myView01
AS
SELECT * FROM emp WHERE deptno =20;
-- 查看视图
SELECT * FROM myView01;

-- 创建/替换多表视图 不能修改表中数据
CREATE OR REPLACE VIEW myView02
AS
SELECT * FROM emp JOIN dept on emp.DEPTNO = dept.DEPTNO
WHERE sal > 2000

存储过程

将存储语句封装起来,需要时调用

CREATE PROCEDURE myPro1(name VARCHAR(10))
BEGIN
	if name IS NULL OR name = '' THEN
		SELECT * FROM emp;
	ELSE
		SELECT * FROM emp WHERE ename LIKE CONCAT('%',name,'%');
	END IF;
END;		
-- 删除存储过程
DROP PROCEDURE myPro1;
-- 调用存储过程
CALL myPro1('R')

-- FOUND_ROWS() 内置函数,返回查询的条数
CREATE PROCEDURE myPro1(in name VARCHAR(10),out num INT(3))
BEGIN
	if name IS NULL OR name = '' THEN
		SELECT * FROM emp;
	ELSE
		SELECT * FROM emp WHERE ename LIKE CONCAT('%',name,'%');
	END IF;
	SELECT FOUND_ROWS() INTO num;
END;		

你可能感兴趣的:(mysql,数据库)