内容有点长,建议配合右边的目录。。。
本篇博客更多是展示SQL语言操作MySQL,和较少的概念。
这里并不能保证能够列出所以的操作,只能尽可能的保证写出博主当前了解的。
MySQL支持命令大小写,应该说大写更规范,但是没有小写容易阅读,所以下面操作使用小写。
确保你已经安装了MySQL。
如果使用MySQL数据库,第一步就是登陆MySQL:
mysql -uroot -p -P3306 -h127.0.0.1
-u:用户名
-p:密码,这里隐藏密码,也可以直接在后面跟上密码
-P:端口,默认3306
-h:登陆的主机
一般来说,使用最简单的登陆方式,使用默认配置:
查询MySQL版本:
查询当前时间:
查看系统使用的编码格式:
如果你没有修改过任何配置,可能会出现gbk,这在以后的操作可能会出现中文乱码,百度如何修改编码格式即可。
修改命令提示符:
修改命令结束符:
默认结束符是 ; ,但是在后面操作(函数等)会使用到修改结束符。
查看当前已有的数据库:
创建数据库 test2:
if not exists:如果不存在则创建
test2 :数据库名
charset:指定编码格式 - utf8、gbk
collate:指导字符集编码格式 - 最简单的区不区分大小写
一定要选择数据库:use test2;
查看当前数据库已有的表:
创建表 table1: 关键字 create
int、varchar都是MySQL支持的数据类型。int默认11位,int(1)指定使用1位。varchar(20)动态字符串类型,最长支持20位字符,存储的字符是多长就动态占用多少空间,相对应char(20)占用空间=20。
not null-非空约束(数据不能为空),default默认约束(数据为空时,使用默认数据)。
primary key是主键约束(主键一定不能为空,代码中显式的写出了not null,可以不写,默认为not null),能够唯一确定一条记录,一张表只能有一个主键。
auto_increment自增长,能够自动从1、2、3开始增长,必须配合主键约束使用。
engine指定数据表的数据引擎,还有如MyISAM、Archive等。
charset指定表的编码格式。
查询创建表语句:
查看表结构:关键字 describe
缩写:desc table1;
插入数据:关键字 insert
下面会以几种格式展示插入数据:
有多少字段就插入多少数据:
字段有默认值,可以使用defalut代替:
指定插入的字段(前提是必须指定所有不能为空或默认值的字段),如table1中,id有自增长,gender有默认值就可以不用指定:
一次性插入多条数据:
insert into table1(name, gender) values('rose', 1), ('alex', 0), ('david', 0);
查看表数据:关键字 select
*代表所有字段
指定查询的字段:
修改数据:
比如 jack 一般为男性,这里需要修改为0
这里使用了where 关键字,表示要修改匹配的记录,如果不加where,会将表中所有的gender修改为0。
删除数据:
where表示删除指定数据,不加则删除表中所有数据。
如果,这时再添加一条数据,你认为id =1 还是4呢?
如果学习过MySQL的,会很肯定的知道id=4,但是如果说为什么,查看如下:
或许你还记得,刚创建表时执行这条语句是没有AUTO_INCREMENT这行的。
所以,再插入一条数据,id=4:
清空数据:
前面提到了 delete from table1; 可以清空所有数据,还有一条效率更高的命令:truncate :
删除表:
删除数据库:
或许在创建表之后需要更改字段的类型、约束、增加、删除字段等。
增加字段,增加一个年龄字段,关键字 alter:
可能你发现字段名、字段类型都是错误的,如何修改?
修改字段类型 modify:
现在,字段类型已经修改,如果只需要修改类型,已经成功了。但是,还需要修改字段名。modify显然做不到,只能使用更加强大的change:
可以看到,默认添加是添加在最后,使用* 查询的是按字段顺序横向排列。另外还可以指定添加字段的位置:
指定位置使用after 字段(还有其他的first等),这里添加了唯一索引(记录中不允许出现重复,如学生学号)。
应该说,外键是使用频率很高的一个约束。
简单描述:
就是先设置表1的字段m 参照表2的字段n,在向表1的字段m 插入数据时,插入的数据只能是表2中字段n 已有的数据,不能凭空而来。
能够设置外键的前提:字段m 的类型必须与字段n 完全相同,数据引擎=InnoDB。
创建表1:
–(空格) 注释内容
创建表2:constraint key_name foreign key (字段) references 表(字段)
查看创建表语句(constraint 后面+索引名称,博主尝试过,但是名称依然是默认名称,你可以尝试一下):
向表2插入数据:
这里会报错,大致意思就是上面说到的,表1中的s_id 没有数据,插入表2的不能凭空而来。
先在表1插入:
再在表2插入:
或许,这里你会想到,如果现在更新、删除表1中的’101’会产生生么结果呢?
试试:
发现删除不了。。。
这里就有了外键约束模式:
有三种:
district:严格模式(默认),父表(表1)不能删除子表(表2)已经引用了的数据(101).
cascade:级联模式,父表的操作级联更新子表,如删除101后,子表唯一 一条数据也将被删除。
set null:置空模式,父表操作后,字表相应字段置空(NULL)
表2创建语句修改为:
学习资料中说:一般采用 删除置空,级联更新,不过代码不能通过。
只好使用级联删除、更新
测试:
插入数据:
更新:
删除:
为了方便测试后面的语句,这里创建四张表:
class:班级表-存放班级id
students:学生表-存放学生信息,并且外键到班级表
class:课程表-存放课程信息
choose:选课表,存放学生选课信息
可以不用关注表的具体实现,直接复制粘贴到mysql中即可。。。
依然使用前面的test2 数据库
use test2;
-- 注意顺序
drop table if exists choose;
drop table if exists course;
drop table if exists students;
drop table if exists class;
-- 班级表
create table if not exists class(
id int not null primary key auto_increment,
class_id char(3) not null unique key
)engine=InnoDB default charset=utf8;
-- 学生表
create table if not exists students(
id int not null primary key auto_increment,
class_id char(3) not null,
student_id char(3) not null unique key,
student_name varchar(20) not null,
gender int(1) default 0,
age int(2),
key cid_key (class_id),
foreign key (class_id) references class(class_id) on delete cascade on update cascade
)engine=InnoDB default charset=utf8;
-- 课程表
create table if not exists course(
id int not null primary key auto_increment,
course_id char(3) not null unique key,
course_name varchar(20) not null
)engine=InnoDB default charset=utf8;
-- 选课表
create table if not exists choose(
id int not null primary key auto_increment,
student_id char(3) not null,
course_id char(3) not null,
key key1 (student_id),
key key2 (course_id),
foreign key (student_id) references students(student_id) on delete cascade on update cascade,
foreign key (course_id) references course(course_id) on delete cascade on update cascade
)engine=InnoDB default charset=utf8;
-- 测试数据
insert into class values(default, 'c01'),
(default, 'c02'),
(default, 'c03');
insert into students values(default, 'c02', 's01', 'tom', 0, 19),
(default, 'c02', 's02', 'jack', 0, 17),
(default, 'c01', 's03', 'rose', 1, 25),
(default, 'c03', 's04', 'alex', 0, 23),
(default, 'c01', 's05', 'david', 0, 28),
(default, 'c02', 's06', 'tyler', 1, 18),
(default, 'c02', 's07', 'lucy', 1, 18);
insert into course values(default, 'cc1', 'chinese'),
(default, 'cc2', 'math'),
(default, 'cc3', 'english');
insert into choose values(default, 's02', 'cc1'),
(default, 's03', 'cc2'),
(default, 's01', 'cc3'),
(default, 's04', 'cc2'),
(default, 's05', 'cc2'),
(default, 's02', 'cc3'),
(default, 's03', 'cc1'),
(default, 's06', 'cc1'),
(default, 's01', 'cc2'),
(default, 's07', 'cc1');
顾名思义,将多个结果联合起来。。。
关键字 union
从上图中,可以看出和单个查询没有什么区别。。。这里就要提到联合查询的两个选项:
all:保留所有记录
distinct:(默认)去重
再试试all 选项:
使用联合查询的小例子,将学生按照男女分组,并且男生按年龄升序排序,女生按年龄降序排序:
order by用于排序,asc 升序(默认) ,desc降序
limit 限制查询的记录数(你可以试试不加limt 时,结果有什么不同?)
最重要的一点:使用order by 和union 的同时,需要加上括号。(不加括号报错)
提到了 order by,就不得不提group by:
group by 用于分组,但是只能显示分组的第一条数据:
可以使用count(*) 看出分组数量:
也可以按照多字段分组,根据分组字段的顺序:
或许你会疑问上面创建的表需要四张表这么多吗?完全可以一张表容纳所有的数据。。。
因为,数据库表的设计需要符合范式(六范式)。。。
按照基本满足前三层范式,就需要将能单独划分为一张表的就划分为一张表。。。(范式具体内容百度)
现在,划分了多张表肯定没有一张表好查询,所以出现了子查询。
子查询可以分为两类:按位置分类、按结果分类
前面子查询的操作基本上也是只查询了一张表的内容,那如何将多张表的内容连接到一起,组成一张表呢?
连接查询可分为:
内连接、外连接、自然连接和交叉连接
为了更加直观的显示,这里添加一条课程记录:
3. 交叉连接
笛卡儿积 - 表1 的记录 x 表2 的记录
4. 自然连接
自然连接是自动匹配相同的字段。
下面的结果博主目前没有能力解释。。。详情请百度。
查询选课表时,结果是学生id 和 课程id ,如果你知道那个学生选了那门课程,就还需要去对照查询学生表和课程表。这很麻烦。。。
所以可以使用连接查询:
第一步,显示课程名
第二步,显示学生名
再排下序:
连接上所有表:
视图和表的操作有很多相似之处,不同的是视图不存放数据,只是对sql 语句的封装,这对数据有很大的安全性保证。
比如,如果直接给了表的权限,可能会对数据造成不可预计的损坏。而视图则规定了你只能操作什么。
创建视图:
查看视图:
可以从某种意思上说视图是一张虚拟的表,所以很多操作和表类似
视图意义:
节省SQL语句,如需要多次执行的SQL,完全可以写成一个视图
数据安全:给出什么样的视图就只能做什么样的操作
。。。
还有一个很重要的就是如何使用视图操作原表的数据?
视图可以操作数据,但是有很多限制。。。
这里就不再详细演示了,有兴趣可以百度。
视图也可以指定视图算法,简单来说就是查询语句的先后执行顺序,详细内容请百度。
这篇博客就先介绍到这里吧。。。
# 3. 数据库操作
create database if not exists test2 charset utf8 collate utf8_general_ci;
show create database test2;
desc test2;
select database();
##########################################################################
# 4. 表操作
use test2;
show tables;
create table if not exists table1(
id int not null primary key auto_increment,
name varchar(20) not null,
gender int(1) default 1
)engine=InnoDB default charset=utf8;
show create table table1;
insert into table1 values(1, 'tom', 0);
insert into table1 values(default, 'jack', default);
insert into table1(name) values('lucy');
select * from table1;
select name, gender from table1;
update table1 set gender=0 where id=2;
delete from table1 where id=1;
show create table table1;
insert into table1(name, gender) values('tom', 0);
select * from table1;
##########################################################################
### 5. 字段操作
alter table table1 add agc varchar(2);
alter table table1 modify agc int(2);
alter table table1 change agc age int(2);
alter table table1 add s_id varchar(11) not null unique key after id;
alter table table1 drop age;
##########################################################################
### 6.外键
-- 表1
create table if not exists table1(
id int not null primary key auto_increment,
s_id char(3) not null unique key,
name varchar(20) not null,
gender int(1) default 1
)engine=InnoDB default charset=utf8;
-- 表2
create table if not exists table2(
id int not null primary key auto_increment,
s_id char(3) not null unique key,
class_name varchar(20) not null,
key sid_key (s_id),
foreign key (s_id) references table1(s_id)
)engine=InnoDB default charset=utf8;
show create table table2;
insert into table2 values(default, '101', 'chinese');
insert into table1 values(default, '101', 'tom', 0),
(default, '102', 'rose', 1);
insert into table2 values(default, '101', 'chinese');
-- 级联删除-级联更新
-- 表2
create table if not exists table2(
id int not null primary key auto_increment,
s_id char(3) not null unique key,
class_name varchar(20) not null,
key sid_key (s_id),
foreign key (s_id) references table1(s_id) on delete cascade on update cascade
)engine=InnoDB default charset=utf8;
insert into table1 values(default, '101', 'tom', 0),
(default, '102', 'rose', 1);
insert into table2 values(default, '101', 'chinese');
update table1 set s_id='103' where id=1;
delete from table1 where s_id='103';
##########################################################################
# 7 联合查询
use test2;
-- 注意顺序
drop table if exists choose;
drop table if exists course;
drop table if exists students;
drop table if exists class;
-- 班级表
create table if not exists class(
id int not null primary key auto_increment,
class_id char(3) not null unique key
)engine=InnoDB default charset=utf8;
-- 学生表
create table if not exists students(
id int not null primary key auto_increment,
class_id char(3) not null,
student_id char(3) not null unique key,
student_name varchar(20) not null,
gender int(1) default 0,
age int(2),
key cid_key (class_id),
foreign key (class_id) references class(class_id) on delete cascade on update cascade
)engine=InnoDB default charset=utf8;
-- 课程表
create table if not exists course(
id int not null primary key auto_increment,
course_id char(3) not null unique key,
course_name varchar(20) not null
)engine=InnoDB default charset=utf8;
-- 选课表
create table if not exists choose(
id int not null primary key auto_increment,
student_id char(3) not null,
course_id char(3) not null,
key key1 (student_id),
key key2 (course_id),
foreign key (student_id) references students(student_id) on delete cascade on update cascade,
foreign key (course_id) references course(course_id) on delete cascade on update cascade
)engine=InnoDB default charset=utf8;
-- 测试数据
insert into class values(default, 'c01'),
(default, 'c02'),
(default, 'c03');
insert into students values(default, 'c02', 's01', 'tom', 0, 19),
(default, 'c02', 's02', 'jack', 0, 17),
(default, 'c01', 's03', 'rose', 1, 25),
(default, 'c03', 's04', 'alex', 0, 23),
(default, 'c01', 's05', 'david', 0, 28),
(default, 'c02', 's06', 'tyler', 1, 18),
(default, 'c02', 's07', 'lucy', 1, 18);
insert into course values(default, 'cc1', 'chinese'),
(default, 'cc2', 'math'),
(default, 'cc3', 'english');
insert into choose values(default, 's02', 'cc1'),
(default, 's03', 'cc2'),
(default, 's01', 'cc3'),
(default, 's04', 'cc2'),
(default, 's05', 'cc2'),
(default, 's02', 'cc3'),
(default, 's03', 'cc1'),
(default, 's06', 'cc1'),
(default, 's01', 'cc2'),
(default, 's07', 'cc1');
-- 联合查询
select * from class
union
select * from class;
select * from class
union all
select * from class;
(select * from students where gender=0 order by age asc limit 99999)
union
(select * from students where gender=1 order by age desc limit 99999);
select * from students group by gender;
select *,count(*) from students group by gender;
select *,count(*) from students group by class_id,gender;
select * from students where student_id = (
select student_id from choose where id = 1);
select * from students where student_id in (
select student_id from choose where course_id = 'cc2');
select * from students where (age,gender) = (
select max(age),gender from students where gender = 0);
select * from (select * from students order by age desc) as s1
group by class_id;
select * from students where
exists(select * from choose where course_id = 'cc3');
##########################################################################
# 9. 连接查询
select * from class c inner join students s on c.class_id=s.class_id;
insert into course values(default, 'cc4', 'physics');
select * from course c left join choose cc on c.course_id=cc.course_id;
select * from class cross join students;
select * from course natural join choose using course_id;
-- 使用示例
select c.id,c.student_id,cc.course_name
from choose c left join course cc
on c.course_id=cc.course_id;
select c.id,s.student_name,cc.course_name
from choose c left join course cc
on c.course_id=cc.course_id
left join students s
on c.student_id=s.student_id;
select c.id,s.student_name,cc.course_name
from choose c left join course cc
on c.course_id=cc.course_id
left join students s
on c.student_id=s.student_id
order by c.id;
select c.id,cs.class_id,s.student_id,s.student_name,cc.course_name
from choose c left join course cc
on c.course_id=cc.course_id
left join students s
on c.student_id=s.student_id
left join class cs
on s.class_id=cs.class_id
order by c.id;
##########################################################################
# 10. 视图
create view get_class as
select * from class;
show create view get_class;
show create table get_class;
desc get_class;
select * from get_class;
alter view get_class as
select class_id from class;
drop view get_class;