如今互联网的主流关系型数据库是mysql,掌握其基本的增、删、改、查是每个测试人员必备的技能。 html
一、DDL语句(数据库定义语言): 数据库、表、视图、索引、存储过程,例如:CREATE、DROP、ALTER python
二、DML语句(数据库操纵语言): 插入数据INSERT、删除数据DELETE、更新数据UPDATE、查询数据SELECT mysql
三、DCL语句(数据库控制语言): 控制用户的访问权限GRANT、REVOKE sql
咱们能够把库看作是文件夹。数据库
mysql自带的库:性能优化
information_schema: 虚拟库,不占用磁盘空间,存储的是数据库启动后的一些参数,如用户表信息、列信息、权限信息、字符信息等服务器
performance_schema: MySQL 5.5开始新增一个数据库:主要用于收集数据库服务器性能参数,记录处理查询请求时发生的各类事件、锁等现象函数
mysql: 受权库,主要存储系统用户的权限信息性能
test: MySQL数据库系统自动建立的测试数据库测试
链接数据库,查看已有的数据库,show databases;
展现了已有的全部库(包含了我本身建立的数据库),若是只看到部分数据库,解决方案参考:http://www.javashuo.com/article/p-xlchatlo-hs.html
建立库,指定编码,create database qzcsbj charset utf8;
库的存放位置
show create database qzcsbj;
show databases;
查看当前所在的库
select database();
修改编码,alter database qzcsbj charset gbk;
drop database qzcsbj;
咱们能够把表看作是文件
切换数据库(文件夹):use qzcsbj ;
查看当前所在数据库(文件夹):select database();
create table 表名( 字段名1 类型[(宽度) 约束条件], 字段名2 类型[(宽度) 约束条件], 字段名3 类型[(宽度) 约束条件] );
增长前,只有一个opt文件
create table test(id int, name varchar(255));
增长后,多了一个frm文件,frm是表结构
show create table test \G; # \G表示按行显示表的详细结构
show tables;
desc test; # 等价于describe test;
insert test(id,name) values(1,'qzcsbj1'),(2,'qzcsbj2'),(3,'qzcsbj3');
复制表结构+记录:
create table test2 select * from test;
只复制表结构:
create table test3 select * from test where 1=2;
或者:
create table test4 like test;
ALTER TABLE 表名 # 修改表名 RENAME 新表名; # 增长字段 ADD 字段名 数据类型 [完整性约束条件…]; ADD 字段名 数据类型 [完整性约束条件…] FIRST; # 添加到第一个字段 ADD 字段名 数据类型 [完整性约束条件…] AFTER 字段名; # 添加到某个字段以后 # 删除字典 DROP 字段名; # 修改字段 MODIFY 字段名 数据类型 [完整性约束条件…]; CHANGE 旧字段名 新字段名 旧数据类型 [完整性约束条件…]; CHANGE 旧字段名 新字段名 新数据类型 [完整性约束条件…];
MODIFY,能够改字段属性
CHANGE,能够改字段名、字段属性
alter table test modify name varchar(256);
desc test;
alter table test change name NAME varchar(257);
desc test;
drop table test;
show tables;
记录能够看作文件夹中文件的内容
全字段插入
INSERT INTO 表名(字段1,字段2,字段3…字段n) VALUES(值1,值2,值3…值n); # into能够省略
多条数据逗号分隔
INSERT INTO 表名 VALUES (值1,值2,值3…值n), (值1,值2,值3…值n), (值1,值2,值3…值n);
指定字段插入
INSERT INTO 表名(字段1,字段2,字段3…) VALUES (值1,值2,值3…);
插入查询结果
INSERT INTO 表名(字段1,字段2,字段3…字段n) SELECT (字段1,字段2,字段3…字段n) FROM 表2 WHERE …;
create table test(id int, name varchar(255));
insert test(id,name) values(1,'qzcsbj1'),(2,'qzcsbj2'),(3,'qzcsbj3');
select * from test;
若是在其它库查test,表前必须加库做为前缀。
select * from qzcsbj.test;
UPDATE 表名 SET 字段1=值1 WHERE 约束条件;
update test set name='qzcsbj' where id=2;
delete from test where id=3;
delete,用于删除数据,自增加字段的值未重置
truncate,用于清空表,自增加字段的值也被重置
注意:delete不能给表取别名
参考:https://www.runoob.com/mysql/mysql-data-types.html
年:year
年月日:date
时分秒:time
年月日时分秒:datetime
create table student( id int, name char(6), # 最大存储6个字符 born_year year, # 年 birth_date date, # 年月日 class_time time, # 时分秒 reg_time datetime # 年月日时分秒 );
插入数据
insert into student values(1,'jack',now(),now(),now(),now()); insert into student values(2,'tom',"2017","2017-12-12","12:12:12","2017-12-12 12:12:12");
now()是mysql提供的函数
# 宽度指的是字符的个数 create table test(name char(5)); create table test(name varchar(5));
char:按指定长度存,存取速度快,可是当存的数据的长度小于字段定义的长度时浪费空间
varchar:存数据更精简,更加节省空间(是在存的数据的长度小于字段定义的长度时;不然必char浪费空间,由于多少了头,要花1个byte),缺点,存取速度慢,要先存头,再存数据;先取头,再取数据;
现现在,存储空间已经不是限制了,要追求存取速度,大部分用char,与查询无关的用varchar
建表的时候,定长的数据往前放,变长的日后放,并且,一张表中,不要char和varchar混用
enum 单选,只能在给定的范围内选一个值,如性别
sex enum('male','female','other'),
set 多选,在给定的范围内能够选择一个或一个以上的值(爱好1,爱好2,爱好3...)
hobbies set('play','music','read','run')
drop table test;
create table test( id int, name char(16), sex enum('male','female','other'), hobbies set('play','music','read','run') );
插入
insert into test values(1,'jack','male','music,read'); # 集合多个值用逗号分隔
分类
一、InnoDB 存储引擎 二、MyISAM 存储引擎 三、NDB 存储引擎 四、Memory 存储引擎 五、Infobright 存储引擎 六、NTSE 存储引擎 七、BLACKHOLE
详见mysql性能调优篇。
做用:保证数据的完整性和一致性
分类
PRIMARY KEY (PK),标识该字段为该表的主键,能够惟一的标识记录 FOREIGN KEY (FK),标识该字段为该表的外键 NOT NULL,标识该字段不能为空 UNIQUE KEY (UK),标识该字段的值是惟一的 AUTO_INCREMENT, 标识该字段的值自动增加(整数类型,并且为主键) DEFAULT, 为该字段设置默认值
#方法一:在某一个字段后用primary key
drop table test; create table test( id int primary key, name char(255) );
#方法二:not null+unique
建立表时未指定主键,会找不为空且惟一的字段做为主键
drop table test; create table test( id int not null unique, name char(255) );
#方法三:在全部字段后单独定义primary key
drop table test; create table test( id int, name varchar(255), constraint pk_name primary key(id) );
创建表之间的关系
create table student( id int primary key, name char(255), age int ); # 关联的表 create table class( id int primary key, name char(255), stu_id int, foreign key(stu_id) references student(id) on delete cascade # 删除同步 on update cascade # 修改同步 );
drop table test;
create table test( id int, name char(255), sex enum('male','female') not null default 'male' );
单列惟一:方式一
drop table test; create table test( id int unique, name char(255) unique );
单列惟一:方式二
drop table test; create table test( id int, name char(255), unique(id), unique(name) );
联合惟一
drop table test; create table test( id int, name char(255), unique(id,name) );
复合主键
drop table test; create table test( id int, name char(255), primary key(id, name) );
约束字段为自动增加,增加字段必须设置为key,primary key,unique key
drop table test; create table test( id int primary key auto_increment, name char(255) );
一对一:身份证号与姓名
一对多:一个班级有多个学生
多对多:一个老师给多个班级授课,一个班级有多位授课老师
一个单表复杂且完整的sql格式是以下的样子,若是是多表,加个join及链接条件就能够了,很简单。
select distinct 字段1,字段2,字段3 # 要查询的字段或者分组字段聚合函数 from 库.表 # 从哪一个表查,若是当前所在的库不是这个表所在的库,表的前面须要加上库名 where # 约束条件 group by # 分组 having # 过滤 order by # 排序 limit # 限制条数
select distinct 字段1,字段2,字段3 # 要查询的字段或者分组字段聚合函数
去重
from 库.表 # 从哪一个表查,若是当前所在的库不是这个表所在的库,表的前面须要加上库名
where是分组以前过滤,后面是普通条件
1.比较运算符:><>= <= <> != 2.逻辑运算符:在多个条件直接可使用逻辑运算符 and or not 3.between 10 and 100 值在10到100之间 4.in(80,90) 值是80或90 5.like 'qzcsbj%',除了%还能够_,%表示任意多字符,_表示一个字符
通常来讲,“每”这个字后面的字段,就是咱们分组的字段
having是分组以后过滤,后面是聚合条件
聚合函数(以组为单位进行统计)
max,最大
min,最小
avg,平均
sum,和
count,数量
默认升序,asc
降序,desc
也能够先按某个字段升序,再按某个字段降序,例如:select * from test order by id asc, name desc;
limit n,默认初始位置为0,从1开始取,取n条,若是不足n条记录,那么有多少条就取多少条
limit m,n,表示位置m,从m+1开始取,取n条记录,若是不足n条记录,那么有多少条就取多少条
5 select
6 distinct 1 from 库.表 2 where 3 group by 4 having 7 order by 8 limit
咱们不可能把数据都存在一个表中,而是存多个表中,这就涉及到多表查询了
生成笛卡尔积,不适用任何匹配条件。
只取两张表的共同部分,join on
显示左表所有记录,在内链接的基础上增长左边有右边没有的结果,left join on
显示右表所有记录,在内链接的基础上增长右边有左边没有的结果,right join on
显示左右两个表所有记录,在内链接的基础上增长左边有右边没有的和右边有左边没有的结果,
union,其与union all的区别是,union会去掉相同的纪录,另外,mysql不支持full join on
建立新用户:CREATE USER 'test'@'localhost' IDENTIFIED BY '123456';
新用户受权:GRANT ALL PRIVILEGES ON *.* TO 'test'@'%'IDENTIFIED BY '123456' WITH GRANT OPTION;
受权(只能root操做) *.* # 全部库下的全部表(以及表下的全部字段)都有权限 qzcsbj.* # test库下的全部表(qzcsbj数据库下全部表,以及表下的全部字段) qzcsbj.test # qzcsbj库下test表(某一张表,以及该表下的全部字段) columns_priv字段:id,name # 字段(某一个或几个字段),grant select(id,name),update(name) on qzcsbj.test to 'test'@'localhost'; 收回权限 revoke select on qzcsbj.test from 'test'@'localhost';
刷新受权:flush privileges;
(待补充)
数值函数
字符串函数
日期时间函数
流程控制函数
系统信息函数
见性能优化篇
参考:http://www.javashuo.com/article/p-mwptzawp-cx.html
表关系: 下面每一个表的第一个字段是主键,未创建外键,使用逻辑外键
班级表
DROP TABLE IF EXISTS `class`; CREATE TABLE `class` ( `cid` int(11) NOT NULL AUTO_INCREMENT, `caption` varchar(255) NOT NULL, `grade_id` int(11) NOT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB AUTO_INCREMENT=16 DEFAULT CHARSET=utf8;
年级表
DROP TABLE IF EXISTS `class_grade`; CREATE TABLE `class_grade` ( `gid` int(11) NOT NULL AUTO_INCREMENT, `gname` varchar(255) NOT NULL, PRIMARY KEY (`gid`) ) ENGINE=InnoDB AUTO_INCREMENT=7 DEFAULT CHARSET=utf8;
课程表
DROP TABLE IF EXISTS `course`; CREATE TABLE `course` ( `cid` int(11) NOT NULL, `cname` varchar(255) NOT NULL, `teacher_id` int(11) NOT NULL, PRIMARY KEY (`cid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
成绩表
DROP TABLE IF EXISTS `score`; CREATE TABLE `score` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `student_id` int(11) NOT NULL, `course_id` int(11) NOT NULL, `score` varchar(255) DEFAULT NULL, PRIMARY KEY (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=20 DEFAULT CHARSET=utf8;
学生表
DROP TABLE IF EXISTS `student`; CREATE TABLE `student` ( `sid` int(11) NOT NULL AUTO_INCREMENT, `sname` varchar(255) NOT NULL, `gender` enum('女','男') NOT NULL DEFAULT '男', `class_id` int(11) NOT NULL, PRIMARY KEY (`sid`) ) ENGINE=InnoDB AUTO_INCREMENT=17 DEFAULT CHARSET=utf8;
老师表
DROP TABLE IF EXISTS `teacher`; CREATE TABLE `teacher` ( `tid` int(11) NOT NULL, `tname` varchar(255) DEFAULT NULL, PRIMARY KEY (`tid`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
班级任职表
DROP TABLE IF EXISTS `teacher2cls`; CREATE TABLE `teacher2cls` ( `tcid` int(11) NOT NULL AUTO_INCREMENT, `tid` int(11) NOT NULL, `cid` int(11) NOT NULL, PRIMARY KEY (`tcid`) ) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;
你们本身完成,这样能够熟悉表关系。
1.查询“生物”课程和“物理”课程成绩都及格的学生id和姓名;
2.查询每一个年级的班级数,取出班级数最多的前三个年级;
3.查询每位学生的学号,姓名,选课数,平均成绩;
4.查询每一个年级的学生人数;
(文末加群获取参考答案)