观b站数据库入门视频笔记

目录

  • 登录
  • 查询
  • 创建
  • MySQL建表约束
    • 主键约束
    • 自增约束
    • 唯一约束
    • 非空约束
    • 默认约束
    • 外键约束
  • 三大设计范式
  • MySQL查询练习
    • 添加表
    • 向表中添加数据
    • 查询练习
    • 四种连接查询
  • MySQL事务

登录

mysql -u root -p

查询

  • 查看所有数据库
    SHOW databases;
    选择数据库
    USE 数据库名;
  • 查看数据库中有哪些表
    SHOW tables
    查询表中数据(上节)
    SELECT * FROM 表名

创建

  • 创建数据库
    CREATE DATABASE 数据库名
    创建数据表
    CREATE TABLE students(name VARCHAR(20),id VARCHAR(20),sex CHAR(1),grade INT);
  • 查看数据表架构
    DESCRIBE students
  • 向表中添加数据
    INSERT INTO 表名
    VALUES('内容1','内容2');

常用数据类型

  1. 数值:TINYINT SMALLINT MEDIUMINT INT或INTEGER BIGINT FLOAT DOUBLE
  2. 日期/时间:DATE(YYYY-MM-DD) TIME(HH:MM:SS) YEAR(YYYY) DATETIME(YYYY-MM-DD- HH:MM:SS) TIMESTAMP(时间戳,YYYYMMDD HHMMSS)
  3. 字符串:CHAR VARCHAR YINYBLOB TINYTEXT BLOB(二进制形式的长文本数据) TEXT(长文本数据) MEDIUMBLOB MEDIUMTEXT LONGBLOB LONGTEXT
  • 删除数据
    DELETE FROM 表名 WHERE 条件
  • 修改数据
    UPDATE SET 改前='改后' WHERE 条件
  • 总结:增删改查——INSERT、DELETE、UPDATE、SELECT

MySQL建表约束

主键约束

它能够唯一确定一张表中的一条记录。使得该字段不重复且不为空。
添加单条约束:

CREATE TABLE user
(
	id INT PRIMARY KEY,--这里id不为空、不重复
	name VARCHAR(20)
);

添加联合约束:

CREATE TABLE user2
(
	id INT,
	name VARCHAR(20)
	password VARCHAR(20)
	PRIMARY KEY(id,name)--这里id和name都不能为空,不能同时重复
);

自增约束

CREATE TABLE user3
(
	id INT PRIMARY AUTO_INCREMENT,
	name varchar(20)
);
INSERT INTO user3(name) VALUES('张三');--没有设定id,但id按加入顺序从1开始自增
  • 如果创建表的时候没有添加主键约束:
    ALTER TABLE user4 ADD PRIMARY KEY(id);
  • 删除约束
    ALTER TABLE user4 DROP PRIMARY KEY;
  • 修改约束
    ALTER TABLE user4 MODIFY id INT PRIMARY KEY;

唯一约束

在建表时设置唯一约束:
格式一:这种格式可以同时设置多个

CREATE TABLE user5
(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20);
	UNIQUE(id,name);
--id和name都设置,此时不同时重复就可以添加,类似联合主键
)

格式二:

CREATE TABLE user6
(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20) UNIQUE//只设置name
);

建表后再添加唯一约束

CREATE TABLE user7
(
	id INT PRIMARY KEY AUTO_INCREMENT,
	name VARCHAR(20);
)
ALTER TABLE user4 ADD UNIQUE(name);//新增name为唯一约束
  • 删除唯一约束
    ALTER TABLE user7 DROP INDEX name;
  • modify添加唯一约束
    ALTER TABLE user7 MODIFY name VARCHAR(20) UNIQUE;

总结:

  1. 建表的时候可以添加约束
  2. 使用ALTER…ADD…
  3. ALTER…MODIFY…
  4. 删除ALTER…DROP…

非空约束

修饰的字段不能为null

CREATE TABLE user9
(
	name VARCHAR(20) NOT NULL;
)

默认约束

如果没有传值使用默认值

CREATE TABLE user10
(
	id INT,
	name VARCHAR(20),
	age INT DEFAULT 10
);

外键约束

涉及到两个表:父表,子表
或 主表,副表

CREATE TABLE classes--班级表
(
	id INT PRIMARY KEY,
	name VARCHAR(20)
);
CREATE TABLE students--学生表
(
	id INT PRIMARY KEY,
	name VARCHAR(20),
	class_id INT,
	FOREIGN KEY(class_id) REFERENCES classes(id)
);
  1. 主表classes中没有的数据值,在副表中是不可以使用的。
  2. 主表中的记录被副表引用,是不可以被删除的。
    例如:
INSERT INTO classes VALUES(1,'一班');
INSERT INTO classes VALUES(2,'二班');
INSERT INTO classes VALUES(3,'三班');
INSERT INTO classes VALUES(4,'四班');

INSERT INTO students VALUES(1005,'王五',5);--是错误的
DELETE FROM classes WHERE id=4;--错误

三大设计范式

范式,设计得越详细,对某些实际操作可能更好,但是不一定都是好的。

  • 第一范式:可以继续拆分,不满足第一范式
  • 第二范式:满足第一范式的条件下,除主键外的每一列都必须完全依赖于主键。如果出现不完全依赖,只可能发生在联合主键的情况下。
CREATE TABLE myorder
(
	product_id INT,
	customer_id INT,
	product_name VARCHAR(20),
	customer_name VARCHAR(20),
	PRIMARY KEY(product_id,customer_id)
);--不满足第二范式
CREATE TABLE myorder
(
	order_id INT PRIMARY KEY
	product_id INT,
	customer_id INT,
);
CREATE TABLE product
(
	id INT PRIMARY KEY;
	name VARCHAR(20)
);
CREATE TABLE customer
(
	id INT PRIMARY KEY;
	name VARCHAR(20)
);--分成三个表满足第二范式
  • 第三范式:满足第二范式的条件下,除开主键列的其他列之间不能有传递依赖关系。
CREATE TABLE myorder
(
	order_id INT PRIMARY KEY,
	product_id INT,
	customer_id INT,
	customer_phone VARCHAR(15)
);--customer_phone可以通过customer_id找到,不满足第三范式
CREATE TABLE myorder
(
	order_id INT PRIMARY KEY,
	product_id INT,
	customer_id INT
);
CREATE TABLE customer
(
	id INT PRIMARY KEY,
	name VARCHAR(20),
	phone VARCHAR(15)
);--满足第三范式

MySQL查询练习

添加表

学生表:
学号
姓名
性别
生日
班级

CREATE TABLE student
(
	snum VARCHAR(20) PRIMARY KEY,
	sname VARCHAR(20) not null,
	ssex VARCHAR(10) not null,
	sbirthday DATETIME,
	class VARCHAR(20)
);

教师表:
教师编号
教师名字
教师性别
教师生日
职称
所在部门

CREATE TABLE teacher
(
	tnum VARCHAR(20) PRIMARY KEY,
	tname VARCHAR(20) NOT NULL,
	tsex VARCHAR(10) NOT NULL,
	tbirthday DATETIME,
	prof VARCHAR(20) NOT NULL,
	depart VARCHAR(20) NOT NULL
);

课程表:
课程号
课程名
教师编号

CREATE TABLE course
(
	cnum VARCHAR(20) PRIMARY KEY,
	cname VARCHAR(20) NOT NULL,
	tnum VARCHAR(20) NOT NULL,
	FOREIGN KEY(tnum) REFERENCES teacher(tnum)
);

成绩表:
学号
课程号
成绩

CREATE TABLE score
(
	snum VARCHAR(20) NOT NULL,
	cnum VARCHAR(20) NOT NULL,
	degree DECIMAL,
	FOREIGN KEY(snum) REFERENCES student(snum),
	FOREIGN KEY(cnum) REFERENCES course(cnum),
	PRIMARY KEY(snum,cnum)
);

向表中添加数据

学生表:

INSERT INTO student VALUES('101','曾华','男','1977-09-01','95033');
INSERT INTO student VALUES('102','匡明','男','1975-10-02','95031');
INSERT INTO student VALUES('103','王丽','女','1976-01-23','95033');
INSERT INTO student VALUES('104','李军','男','1976-02-20','95033');
INSERT INTO student VALUES('105','王芳','女','1975-02-10','95031');
INSERT INTO student VALUES('106','陆军','男','1974-06-03','95031');
INSERT INTO student VALUES('107','王尼玛','男','1976-02-20','95033');
INSERT INTO student VALUES('108','张全蛋','男','1975-02-10','95031');
INSERT INTO student VALUES('109','赵铁柱','男','1974-06-03','95031');

教师表:

INSERT INTO teacher VALUES('804','李诚','男','1958-12-02','副教授','计算机系');
INSERT INTO teacher VALUES('856','张旭','男','1969-03-12','讲师','电子工程系');
INSERT INTO teacher VALUES('825','王萍','女','1972-05-05','助教','计算机系');
INSERT INTO teacher VALUES('831','刘冰','女','1977-08-14','助教','电子工程系');

课程表:

INSERT INTO course VALUES('3-105','计算机导论','825');
INSERT INTO course VALUES('3-245','操作系统','804');
INSERT INTO course VALUES('6-166','数字电路','856');
INSERT INTO course VALUES('9-888','高等数学','831');

成绩表:

INSERT INTO score VALUES('103','3-245','86');
INSERT INTO score VALUES('105','3-245','75');
INSERT INTO score VALUES('109','3-245','68');
INSERT INTO score VALUES('103','3-105','92');

INSERT INTO score VALUES('105','3-105','88');
INSERT INTO score VALUES('109','3-105','76');
INSERT INTO score VALUES('103','6-166','85');

INSERT INTO score VALUES('105','6-166','79');
INSERT INTO score VALUES('109','6-166','81');

查询练习

  1. 查询student表中学生所有信息
    SELECT * FROM student;
  2. 查询student表中学生名字和性别
    SELECT sname,ssex FROM student;
  3. 查询teacher表中教师所有单位即不重复的depart列,使用DISTINCT
    SELECT DISTINCT depart FROM teacher;
  4. 查询score表中成绩在60到80的记录
    SELECT * FROM score WHERE degree BETWEEN 60 AND 80;
    或者
    SELECT * FROM score WHERE degree>60 AND degree<80;
  5. 查询score表中成绩为85,86或88的记录
    SELECT * FROM score WHERE degree IN(85,86,88);
  6. 查询student表中班级为95031,或者性别为女的同学记录
    SELECT * FROM student WHERE class='95031' OR ssex='女';
  7. 以class降序查询student表中所有记录
    SELECT * FROM student ORDER BY class DESC;
  8. 以cnum升序、degree降序查询score表
    SELECT * FROM score ORDER BY cnum ASC,degree DESC;
  9. 查询951031班的学生人数
    SELECT COUNT(*) FROM student WHERE class='95031';
  10. 查询score表中的最高分的学生学号和课程号
    子查询:
    SELECT snum,cnum FROM score WHERE degree=(SELECT MAX(degree) FROM score);
    排序:(有多个最高分时有问题)
    SELECT snum,cnum,degree FROM score ORDER BY degree DESC LIMIT 0,1;(LIMIT x,y表示从x条数据开始,查询y条)
  11. 查询每门课的平均成绩
    SELECT AVG(degree) FROM score WHERE cnum=''3-105';–某门课
    SELECT AVG(degree) FROM score GROUP BY cnum;–GROUP BY分组
  12. 查询score表中至少有两名学生选修并以3开头的课程的平均分数
    SELECT cnum FROM score GROUP BY cnum HAVING COUNT(cnum)>=2 AND cnum LIKE '3%';
  13. 查询所有学生的sname,cnum,degree列(多表联查,信息来自两张表)
SELECT sname,cnum,degree FROM student,score 
WHERE student.snum=score.snum;
  1. 查询所有学生的sname,cname,degree列(多表联查,信息来自三张表)
SELECT sname,cname,degree FROM student,course,score 
WHERE student.snum=score.snum AND course.cnum=score.cnum;
  1. 查询95031班学生每门课平均分
SELECT cnum,avg(degree) FROM score 
WHERE snum IN(SELECT snum FROM student WHERE class='95031') 
GROUP BY cnum;
  1. 查询3-105课程中所有成绩高于109号同学的记录
SELECT * FROM score
WHERE cnum='3-105'
AND degree>(SELECT degree FROM score
WHERE snum='109' AND cnum='3-105');
  1. 查询和学号108、101的同学同年出生的所有学生的snum、sname和sbirthday列
SELECT snum,sname,sbirthday FROM student
WHERE YEAR(sbirthday) IN (SELECT YEAR(sbirthday) FROM student
WHERE snum IN(108,101));
--注意两个灵性的IN
  1. 查询“张旭”教师任课的学生成绩(套娃)
SELECT degree,snum FROM score 
WHERE cnum IN(SELECT cnum FROM course 
WHERE tnum IN (SELECT tnum FROM teacher 
WHERE tname='张旭'))
  1. 查询选修某课程的同学人数多于3人的教师姓名
INSERT INTO score VALUES('107','3-105','80');--手动改下人数。。
SELECT tname FROM teacher WHERE tnum IN
(SELECT tnum FROM course WHERE cnum IN
(SELECT cnum FROM score GROUP BY cnum
HAVING count(*)>3));
--HAVING和GROUP BY配合使用,实现先分组再执行HAVING后条件
  1. 查询计算机系教师所教课程的成绩表
 SELECT * FROM score WHERE cnum IN
 (SELECT cnum FROM course WHERE tnum IN
 (SELECT tnum FROM teacher WHERE depart='J=计算机系'));
  1. 查询计算机系和电子工程系不同职称教师的tname和prof(并集除去交集)(UNION和NOT IN)
SELECT tname,prof FROM teacher WHERE depart='计算机系' 
AND prof NOT IN
(SELECT prof FROM teacher WHERE depart='电子工程系');
UNION--拼接两个表
SELECT tname,prof FROM teacher WHERE depart='电子工程系' 
AND prof NOT IN
(SELECT prof FROM teacher WHERE depart='计算机系');

观b站数据库入门视频笔记_第1张图片

  1. 在3-105课程考的比3-245课程最低分/最高分好的同学信息(ANY和ALL)
SELECT * FROM score WHERE cnum='3-105'
AND degree>ANY(SELECT * FROM score WHERE cnum='3-245')
ORDER BY degree DESC;

SELECT * FROM score WHERE cnum='3-105'
AND degree>ALL(SELECT * FROM score WHERE cnum='3-245')
ORDER BY degree DESC;
  1. 查询所有教师和学生的name,sex,birthday(别名)
--加AS也可
SELECT tname name,tsex sex,tbirthday birthday FROM teacher
UNION
SELECT sname,ssex,sbirthday FROM student;
  1. 查询成绩比该课程平均成绩低的同学的成绩表(复制表作条件查询)
SELECT * FROM score a WHERE degree<
(SELECT AVG(degree) FROM score b 
WHERE a.cnum=b.cnum);
--将表a某条待查的课程号作为条件,
--查询表b中所有该课程号的分数平均值,再与a进行分数比较
  1. 查询至少有两名男生的班号
SELECT class FROM student WHERE
ssex='男' GROUP BY class 
HAVING COUNT(*)>=2;
  1. 查询不姓王的同学记录
SELECT * FROM student WHERE sname
NOT LIKE'王%';
  1. 查询student表中每个学生的姓名和年龄
SELECT sname,YEAR(NOW())-YEAR(sbirthday) age FROM student;
  1. 查询student表中最大和最小sbirthday(MAX和MIN)
SELECT MAX(sbirthday) '最大',MIN(sbirthday) '最小' FROM student; 
  1. 以班号和年龄从大到小的顺序查询student表中的全部记录
SELECT * FROM student ORDER BY class DESC,sbirthday;
  1. 查询选了计算机导论的所有男同学成绩
SELECT * FROM score 
WHERE snum IN(SELECT snum FROM student WHERE ssex='男') 
AND cnum=(SELECT cnum FROM course WHERE cname='计算机导论');
  1. 用ABCD给成绩评级(按等级查询)
CREATE TABLE grade
(
	low INT(3),
	upp INT(3),
	grade CHAR(1)
);
INSERT INTO grade VALUES(90,100,'A');
INSERT INTO grade VALUES(80,90,'B');
INSERT INTO grade VALUES(70,80,'C');
INSERT INTO grade VALUES(60,70,'D');
SELECT snum,cnum,grade FROM score,grade WHERE
degree BETWEEN low AND upp;

观b站数据库入门视频笔记_第2张图片
观b站数据库入门视频笔记_第3张图片

四种连接查询

内连接
INNER JOIN 或者 JOIN

外连接

  1. 左连接 LEFT JOIN 或者 LEFT OUTER JOIN
  2. 右连接 RIGHT JOIN 或者 RIGHT OUTER JOIN
  3. 完全外连接 FULL JOIN 或者 FULL OUTER JOIN
  • 创建数据库testJoin
  • 创建两个表:
    person表:
    id
    name
    cardId
CREATE TABLE person
(
	id INT,
	name VARCHAR(20),
	cardid INT
);

card表:
id
name

CREATE TABLE card
(
	id INT,
	name VARCHAR(20)
);

插入数据:

INSERT INTO card VALUES (1, '饭卡'), (2, '建行卡'), (3, '农行卡'), (4, '工商卡'), (5, '邮政卡');
INSERT INTO person VALUES (1, '张三', 1), (2, '李四', 3), (3, '王五', 6);

观b站数据库入门视频笔记_第4张图片
观b站数据库入门视频笔记_第5张图片

  1. INNER JOIN 查询
    SELECT * FROM person INNER JOIN card ON person.cardid=card.id;
    观b站数据库入门视频笔记_第6张图片
    内联查询,就是两个表中的数据,通过某个字段相对,查询出相关记录
  2. LEFT JOIN 左外连接
    SELECT * FROM person LEFT JOIN card ON person.cardid=card.id;
    观b站数据库入门视频笔记_第7张图片
    左外连接,会把左边表中的数据全部取出来,右边表中的数据,如果有相等的,就显示出来,如果没有,就会补NULL
  3. RIGHT JOIN 右外连接
    和左外连接原理一样
  4. FULL JOIN 全外连接
    左右表中的数据都显示出来,没有的项目补NULL
    MySQL中没有FULL JOIN,用以下方法:
SELECT * FROM person LEFT JOIN card ON person.cardid=card.id
UNION
SELECT * FROM person RIGHT JOIN card ON person.cardid=card.id;

观b站数据库入门视频笔记_第8张图片

MySQL事务

事务是一个最小的不可分割的工作单元,事务能够保证一个业务的完整性。
比如银行转账:必须一方转一方收

  • MySQL中如何控制事务
    1. MySQL是默认开启事务的(自动提交)
      默认事务开启的作用:一个sql语句执行时效果会立刻体现出来,且不能回滚(ROLLBACK)
    2. 设置MySQL自动提交为FALSE
      SET autocommit=0;
      需要进行手动提交,提交后就不能ROLLBACK:COMMIT;
  • 手动开启事务
    当autocommit=1 使用BEGIN或者START TRANSACTION 在事务前面时,该事务可以回滚。事务开启后一旦 COMMIT 代表当前事务结束,不能再回滚。

总结:
事务开启:
1. 修改默认提交 SET autocommit=0;
2. BEGIN; 或者 START TRANSACTION;
事务手动提交:COMMIT;
事务手动回滚:ROLLBACK;

  • 事务的四大特征ACID
    Automatic 原子性:事务是最小的单位,不可以再分割
    Consistant 一致性:事务要求,同一事务中的sql语句,必须保证同时成功或者同时失败
    Isolated 隔离性:事务1和事务2之间具有隔离性
    Durable 持久性:事务一旦结束,就不可返回
  • 事务的隔离性
    1. read uncommitted; 读未提交的
    2. read committed; 读已经提交的
    3. respectable read; 可以重复读
    4. serializable; 串行化
  • 如何查看数据库的隔离级别?
    系统级别的:SELECT @@GLOBAL.TRANSACTION_ISOLATION;
    会话级别的:SELECT @@TRANSACTION_ISOLATION;
    默认隔离级别:READ-UNCOMMITTED
  • 如何修改隔离级别?
    SET global transaction isolation level read uncommited;
  1. read uncommitted
    如果有事务a,事务b
    a事务对数据进行操作,在操作的过程中,事务没有被提交,但是b可以看见a操作的结果。
    脏读:一个事务读到了另外一个事务没有提交的数据。实际开发中是不允许脏读出现的。
  2. read committed
    会出现:读取同一个表数据发现前后不一致,不可重复读现象
  3. repeatable read
    幻读:事务a和事务b同时操作一张表,事务a提交的数据,也不能被事务b读到,就造成幻读。此时如果b要插入相同数据,会提示已经存在,出现错误
  4. serializable
    当表被一个事务操作的时候,其他事务里面的写操作是不能进行的,进入排队状态(串行化),直到前面事务结束后才会执行(在没有超时的情况下)。
    串行化的问题:性能差
    性能:READ-UNCOMMITED>READ-COMMITTED>REPEATABLE-READ>SERIALIZABLE
    隔离级别越高,性能越差。

你可能感兴趣的:(SQL必知必会)