MySQL

MySQL

在Git Bash中使用mysql

//进入数据库管理
winpty mysql -u root -p

//查看所有的数据库
show databases;				

//选中某个数据库
use ***				

//退出数据库管理
exit、quit、\q			

//创建一个名叫test的数据库
create database test;			

//查看数据库中的所有数据表
show tables;			

//创建pet数据表
create table pet(
name varchar(20),
owner varchar(20));		

//查看pet数据表的结构
describe(desc) pet;		

/*
增删改查
*/
//往pet数据表中添加数据
insert into pet
values('LuAng','zyf');		

//查询pet表中的数据
select * from pet;				

//删除testtype表中number=123的数据
delete from testtype where number = 123;	
//删除所有行:
Delete From 表名称 或者 Truncate Table  表名称
//删除表:
Drop Table 表名称

//修改pet表中owner='zyf'的数据的name项为'XiaoAng'
update pet set name = 'XiaoAng' where owner = 'zyf';

//创建表后修改字段,往user表中添加一个age字段
alter table user add (age int);

数据库的四种语言

DCL:授权

DDL:操作数据库,表

DQL:查询表中的数据

DML:增删改表中的数据

约束

主键约束

它能够唯一确定一张表中的一条记录,也就是我们通过给某个字段添加约束,就可以使得该字段不重复且不为空。

//id 后面 primary key  即id字段不重复且不为空
create table user(
	id int primary key,
	name varchar(20)
);

//创建表后添加主键约束,删除则将add改为drop后面不用选择字段
alter table user2 add (modify) primary key(id);

/*
	复合主键
*/

create table user2(
	id int,
    name varchar(20),
    password varchar(20),
    //相当于 或 ,两个加起来不相等即可
    primary key(id,name)
);

自增约束

/*
	自增约束auto_increment搭配主键约束可自动管理id字段
*/
create table user3(
	id int primary key auto_increment,
	name varchar(20)
);

//只插入name字段的值,id字段会自动生成 null或者0
insert into user3 values(null,'xiaoang');

唯一约束

约束修饰的字段的值不可以重复

//id字段不可以重复
create table user2(
	id int unique,
	name varchar(20)
);

//若是unique(id,name)则是id+name不重复即可

//删除唯一约束,删除id的唯一约束
alter table user2 drop index id;

非空约束

约束修饰的字段的值不可以为空

//id字段不能为空
create table user2(
	id int not null,
	name varchar(20)
);

默认约束

当我们插入字段值的时候,如果没有传值,就会使用默认值

//如果age没有传值,则为默认值18
create table user(
	id int,
	name varchar(20),
	age int default 18
);

外键约束

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

 //班级表,父表即主表
 create table classes(
 	id int primary key,
 	name varchar(20)
 );
 
 //学生表,子表即副表
 create table students(
 	id int primary key,
 	name varchar(20),
 	class_id int,
    
     //外键约束指向classes表中的id字段
 	foreign key(class_id) references classes(id)
 );
 
 /*
 	主表classes中没有的数据值,在副表中是不可以使用的
 	主表中的纪录被附表引用是不可以被删除的
 */

数据库的三大设计范式

第一范式(1NF)

数据表中的所有字段都是不可分割的原子值

字段值若是还可以继续拆分,就不满足第一范式

第二范式(2NF)

1NF+除主键外的每一列都要完全依赖于主键,

不完全依赖也就是出现了复合主键

若不是完全依赖于主键则要拆表

//订单表
//不满足第二范式,要拆分
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)
);

第三范式(3NF)

2NF+除开主键列的其他列之间不能有传递依赖关系

create table myorder(
	order_id int primary key,
    product_id int,
    customer_id int,
    /*
    ×××不能这样,customer_phone可通过customer_id找到即依赖于customer_id
    customer_phone varchar(15)		
    */
);

//应写到下面
create table customer(
	id int primary key,
    name varchar(20)
	phone varchar(15)
);

数据库创建

创建表

 //创建学生表 学号,姓名,性别,生日,班级号
 create table student(
 	sno varchar(20) primary key,
 	sname varchar(20) not null,
 	ssex varchar(10) not null,
 	sbirthday datetime,
 	class varchar(20)
 );

//创建教师表 教师号,教师名字,性别,生日,职称,所在部门
create table teacher(
tno 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(
cno varchar(20) primary key,
cname varchar(20) not null,
tno varchar(20) not null,
foreign key(tno) references teacher(tno)
);

//创建成绩表 学号,课程号,成绩
create table score(
sno varchar(20) not null,
cno varchar(20) not null,
degree decimal,
foreign key(sno) references student(sno),
foreign key(cno) references course(cno),
primary key(sno,cno)
);

//创建成绩等级表
create table grade(
low int(3),
upp int(3),
grade char(1)
);


添加数据


//添加学生信息
insert into student values('101','曾华','男','1977-09-07','95033');
insert into student values('102','匡明','男','1975-04-01','95033');
insert into student values('103','王丽','女','1979-06-02','95031');
insert into student values('104','李俊','女','1977-08-03','95033');
insert into student values('105','王芳','女','1973-01-04','95031');
insert into student values('106','陆军','男','1974-03-05','95033');
insert into student values('107','王璐','女','1978-09-06','95031');
insert into student values('108','张锋','男','1971-07-07','95033');
insert into student values('109','李森','男','1970-02-08','95031');

//添加教师信息
insert into teacher values('804','李成','男','1957-12-06','副教授','计算机系');
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('105','计算机导论','825');
insert into course values('245','操作系统','804');
insert into course values('166','数字电路','856');
insert into course values('888','高等数学','831');

//添加成绩信息
insert into score values('103','245','86');
insert into score values('105','245','75');
insert into score values('109','245','68');
insert into score values('103','105','92');
insert into score values('105','105','88');
insert into score values('109','105','76');
insert into score values('103','166','85');
insert into score values('105','166','79');
insert into score values('109','166','81');
insert into score values('101','166','82');
insert into score values('102','166','83');

//添加成绩等级
insert into grade values(90,100,'A');
insert into grade values(80,89,'B');
insert into grade values(70,79,'C');
insert into grade values(60,69,'D');
insert into grade values(0,59,'E');

数据表

student:
+-----+-------+------+---------------------+-------+
| sno | sname | ssex | sbirthday           | class |
+-----+-------+------+---------------------+-------+
| 101 | 曾华  | 男   | 1977-09-07 00:00:00 | 95033 |
| 102 | 匡明  | 男   | 1975-04-01 00:00:00 | 95033 |
| 103 | 王丽  | 女   | 1979-06-02 00:00:00 | 95031 |
| 104 | 李俊  | 女   | 1977-08-03 00:00:00 | 95033 |
| 105 | 王芳  | 女   | 1973-01-04 00:00:00 | 95031 |
| 106 | 陆军  | 男   | 1974-03-05 00:00:00 | 95033 |
| 107 | 王璐  | 女   | 1978-09-06 00:00:00 | 95031 |
| 108 | 张锋  | 男   | 1971-07-07 00:00:00 | 95033 |
| 109 | 李森  | 男   | 1970-02-08 00:00:00 | 95031 |
+-----+-------+------+---------------------+-------+

teacher:
+-----+-------+------+---------------------+--------+------------+
| tno | tname | tsex | tbirthday           | prof   | depart     |
+-----+-------+------+---------------------+--------+------------+
| 804 | 李成  | 男   | 1957-12-06 00:00:00 | 副教授 | 计算机系   |
| 825 | 王萍  | 女   | 1972-05-05 00:00:00 | 助教   | 计算机系   |
| 831 | 刘冰  | 女   | 1977-08-14 00:00:00 | 助教   | 电子工程系 |
| 856 | 张勋  | 男   | 1969-03-12 00:00:00 | 讲师   | 电子工程系 |
+-----+-------+------+---------------------+--------+------------+

course:
+-----+------------+-----+
| cno | cname      | tno |
+-----+------------+-----+
| 105 | 计算机导论 | 825 |
| 166 | 数字电路   | 856 |
| 245 | 操作系统   | 804 |
| 888 | 高等数学   | 831 |
+-----+------------+-----+

score:
+-----+-----+--------+
| sno | cno | degree |
+-----+-----+--------+
| 101 | 166 |     82 |
| 102 | 166 |     83 |
| 103 | 105 |     92 |
| 103 | 166 |     85 |
| 103 | 245 |     86 |
| 105 | 105 |     88 |
| 105 | 166 |     79 |
| 105 | 245 |     75 |
| 109 | 105 |     76 |
| 109 | 166 |     81 |
| 109 | 245 |     68 |
+-----+-----+--------+

grade:
+------+------+-------+
| low  | upp  | grade |
+------+------+-------+
|   90 |  100 | A     |
|   80 |   89 | B     |
|   70 |   79 | C     |
|   60 |   69 | D     |
|    0 |   59 | E     |
+------+------+-------+

数据库名词解释

distinct 不重复
表示或者关系的查询 in
or 表示或者
order by...desc 以...降序   asc 升序
count(*) 统计个数
max(degree)  degree的最大值
avg(degree) 平均数
group by 分组
having筛选分组之后的数据
where筛选分组之前的数据
like '1%' 模糊查询 像以1开头的的数据
not like 模糊查询取反
student.sno=score.sno  = 相当于对两个表自然连接
year(日期)  可获得日期中的年份
now() 获取当前系统时间
union 求并集    not in 不在其中
any 至少一个     所有 
as 重命名
max() min() 获取当前列的最大值最小值

数据库查询练习

/*
	查询练习
*/
//1.查询student表的所有记录
select * from student;

//2.查询student表中的所有记录的sname、ssex和class列
select sname,ssex,class from student;

//3.查询教师所有的单位即不重复的depart列			/*distinct 不重复*/
select distinct depart from teacher;

//4.查询score表中成绩在60到80之间的所有记录 	 /*1.查询区间,2.使用运算符*/
select * from score where degree between 60 and 80;
select * from score where degree > 60 and degree < 80;

//5.查询score表中成绩为85,86或88的记录		/*表示或者关系的查询 in*/
select * from score where degree in(85,86,88);

//6.查询student表中‘95031’班或性别为‘女’的同学记录		/*or 表示或者*/
select * from student where class = '95031' or ssex = '女';

//7.以sno降序查询student表中的所有记录	/*order by...desc 以...降序*/
select * from student order by sno desc;

//8.以cno升序、degree降序查询score表的所有记录	/*asc 升序*/
select * from score order by cno asc,degree desc;

//9.查询‘95031’班的学生人数		/*count(*) 统计个数*/
select count(*) from student where class = '95031';

//10.查询score表中的最高分的学生学号和课程号(子查询或者排序)	
/*max(degree)  degree的最大值 select返回的是记录,从中再查询*/
select sno,cno from score where degree=(select max(degree) from score);

//11.查询每门课的平均成绩		/*avg(degree) 平均数*/
select avg(degree) from score where cno = '245';
/*group by 分组*/
select cno,avg(degree) from score group by cno;

//12.查询score表中至少有两名学生选修的并以1开头的课程号
/*分组后用having筛选 count(*)是个数 like '1%' 像以1开头的的数据
  where筛选分组之前的数据,having筛选分组之后的*/
select cno from score group by cno 
having count(*)>=2 and cno like '1%';

//13.查询分数大于70,小于90的sno列
select sno,degree from score where degree>70 and degree<90;

//14.查询所有学生的sname,cno和degree列
/*多表查询 条件是student.sno=score.sno  = 相当于对两个表自然连接 */
select sname,cno,degree from student,score where student.sno = score.sno;

//15.查询所有学生的sno,cname和degree列
select sno,cname,degree from course,score where course.cno=score.cno;

//16.查询所有学生的sname,cname和degree列		/*三表关联查询*/
select sname,cname,degree from student,course,score where student.sno=score.sno and course.cno=score.cno;

//17.查询‘95031’班学生的每门课的平均分
/*
子查询:查询95031班的sno
select sno from student where class='95031';
分组:查询每个课程的分数
select cno from score where... group by cno;
子查询加分组 
*/
select cno,avg(degree)
from score 
where sno in (select sno from student where class='95031') 
group by cno;

//18.查询选修‘105’课程的成绩高于‘109’号同学‘105’课程成绩的所有同学的记录
/* 子查询 
查询所cno=105且成绩大于某个数的所有记录
select * from score where cno = '105' and degree>...;
查询109号同学的105号课程的成绩
select degree from score where sno = '109' and cno = '105';
*/
select * from score where cno = '105' and degree>(select degree from score where sno = '109' and cno = '105');

//19.查询成绩高于学号为‘109’,课程号为‘105’的成绩的所有记录
select degree from score where degree>(select degree from score where sno = '109' and cno = '105');

//20.查询和学号为108,101的同学同年出生的所有同学的sno,sname,sbirthday列
/*year(日期)  可获得日期中的年份*/
select sno,sname,sbirthday from student where year(sbirthday) in (select year(sbirthday) from student where sno in(108,101)); 

//21.查询‘李成’教师任课的学生成绩
/*	多层嵌套子查询
1.select tno from teacher where tname = '李成';
2.select cno from course where tno = (...);
3.select * from score where cno = (...);
*/
select * from score where cno = (select cno from course where tno = (select tno from teacher where tname = '李成'));

//22.查询选修某课程的同学人数不少于5人的教师姓名
/*
select cno from score group by cno having count(*)>=5;
select tno from course where cno=(...)
select tname from teacher where tno=(...)
*/
select tname from teacher where tno=(select tno from course where cno=(select cno from score group by cno having count(*)>=5));

//23.查询存在有85分以上成绩的课程cno
select distinct cno from score where degree > 85;

//24.查询出‘计算机系’教师所教的课程的成绩表
/*
select tno from teacher where depart = '计算机系';
select cno from course where tno in (...);
select * from score where cno in (...);
*/
select * from score where cno in (select cno from course where tno in (select tno from teacher where depart = '计算机系'));

//25.查询‘计算机系’与‘电子工程系’不同职称的教师的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 = '计算机系');


//26.查询105课程的成绩大于至少一个245课程的成绩的cno,sno,degree,并按degree从高到低排序
/* any 至少一个      all 所有 */
select * from score 
where cno = '105' 
and degree > any(select degree from score where cno = '245') 
order by degree desc;

//27.查询所有教师和同学的name,sex,birthday
/* as 重命名 */
select tname as name,tsex as sex,tbirthday as birthday from teacher
union
select sname,ssex,sbirthday from student;

//28.查询成绩比该课程平均成绩低的同学的成绩表
/*复制表数据做条件查询*/
select * from score a where degree<(select avg(degree) from score b where a.cno=b.cno);

//29.查询至少有两名男生的班号
/*分组加条件筛选*/
select class from student where ssex='男' group by class having count(*) >= 2;

//30.查询student表中不姓‘王’的同学记录
/*not like 模糊查询取反*/
select * from student where sname not like '王%';

//31.查询student表中每个学生的姓名和年龄
/*year() 获取年份   now() 获取当前系统时间 	不存在的列 要有as*/
select sname,year(now())-year(sbirthday) as '年龄' from student;

//32.查询student表中最大和最小的sbirthday日期值
/*max() min() 获取当前列的最大值最小值*/
select max(sbirthday) as '最大',min(sbirthday) as '最小' from student;

33.查询所有同学的sno,cno,grade列,并按ABCDE顺序排列
/*按等级查询*/
select sno,cno,grade from score,grade where degree between low and upp order by grade;

SQL的四种连接查询

//创建person表
create table person(
id int,
name varchar(20),
cardId int
);

//创建card表
create table card(
id int,
name varchar(20)
);

//添加数据
insert into person values(1,'张三',1);
insert into person values(2,'李四',3);
insert into person values(3,'王五',6);

insert into card values(1,'饭卡');
insert into card values(2,'建行卡');
insert into card values(3,'农行卡');
insert into card values(4,'工商卡');
insert into card values(5,'邮政卡');

//数据表
person:
+------+------+--------+
| id   | name | cardId |
+------+------+--------+
|    1 | 张三 |      1 |
|    2 | 李四 |      3 |
|    3 | 王五 |      6 |
+------+------+--------+

card:
+------+--------+
| id   | name   |
+------+--------+
|    1 | 饭卡   |
|    2 | 建行卡 |
|    3 | 农行卡 |
|    4 | 工商卡 |
|    5 | 邮政卡 |
+------+--------+

内连接

join 或者inner join

内联查询:就是两张表的数据,通过某个人字段相对,查询出相关记录数据

select * from person join card on person.cardId=card.id; 

外连接

左连接

left join 或者 left outer join

左外连接:会把左边表里面的所有数据取出来,而右边表中的数据,如果有相等的就显示出来,如果没有就会补NULL==

select * from person left join card on person.cardId=card.id;

右连接

right join 或者 right outer join

右外连接:会把右边表里面的所有数据取出来,而左边表中的数据,如果有相等的就显示出来,如果没有就会补NULL

select * from person right join card on person.cardId=card.id;

完全外连接

full join 或者 full outer join(mysql不支持)

select * from person left join card on person.cardId=card.id
union
select * from person right join card on person.cardId=card.id;

事务

mysql是默认开启事务自动提交的

事务给我们提供了一个返回的机会

/*autocommit为1则为自动提交*/
select @@autocommit;

/*rollback 事务回滚,即撤销上一步操作 	而自动提交是不允许事务回滚的*/
rollback;

/*设置自动提交为false 即autocommit为0*/
set autocommit = 0;

/*不是自动提交的情况下 commit手动提交 提交后则不能事务回滚*/
commit;


/*在autocommit为1的情况下 可手动开启一个不自动提交的事务 可进行事务回滚 */
/*在执行语句前*/
begin; /*或者*/ start transaction;
/*commit前都可rollback*/

事务的四大特征(ACID)

  1. A 原子性:事务是最小的单位,不可以再分割
  2. C 一致性:事务要求,同一事务中的sql语句,必须保证同时成功或者同时失败
  3. I 隔离性:事务1和事务2之间是具有隔离性的
  4. D 持久性:事务一旦结束(commit,rollback),就不可以返回

事物的隔离性

read uncommitted; 读未提交的
a事务对数据进行操作,在操作的过程中事务没有被提交,但是b可以看见a操作的结果

/*查看数据库的隔离级别*/
<系统级别的>
select @@global.transaction_isolation;
<会话级别的>
select @@transaction_isolation;

/*修改隔离级别*/
set global transaction isolation level read uncommitted;

/*脏读:一个事务读到了另外一个事务没有提交的数据,就叫脏读, 实际开发不允许脏读*/
read committed; 读已经提交的

可能出现问题:读取同一个表的数据,发现前后不一致

repeatable read; 可以重复读

可能出现幻读:事务a和事务b (都开启事务了) 同时操作一张表,事务a提交的数据,也不能被事务b读到

serializable; 串行化

可能出现串行化:当user表被事务a操作时,其他事务里面的写操作是不可以进行的,已经开始的也会进入排队状态(串行化),直到事务a执行commit操作,其他事务的写操作才可以执行(在没有等待超时的情况下)

DCL管理权限

-- 使用mysql数据库
use mysql;

-- 查询用户表
select * from user;

-- 创建用户 localhost 代表本机  % 代表所有主机
create user 'kilig'@'%' identified by 'qepwq';

-- 删除用户
drop user 'kilig'@'%';

-- 修改密码
update user set password = password('新密码') where user = 'kilig';

-- 查询权限
show grants for 'kilig'@'%';

-- 授予权限		all 所有权限  *.* 所有数据库的所有权限
grant all on *.* to 'kilig'@'%';

-- 撤销权限
revoke all on *.* from ''@'';

你可能感兴趣的:(Mysql)