services.msc //打开windows服务窗口
net start mysql //启动mysql服务
net stop mysql //停止mysql服务
netstat -aon //显示端口列表
cmd窗口显示中文乱码问题
切换为UTF-8:chcp 65001
切换回GBK:chcp 936
CMD登录数据库的操作步骤
mysql -uroot -proot [-P](-P用来设置端口号,默认连接3306端口)
注:如果-p之后不写密码,会提示输入密文密码,这样更安全
mysql -h127.0.0.1 -uroot -proot -P3306
第二种方式:写全称
mysql --host=ip --user=root --password=root
退出数据库的命令:
quit 退出数据库
exit; 关闭cmd
DDL(数据定义语句)
——操作数据库和表
CRUD:分别对用四种操作
操作数据库
Create 创建数据库
create database db1;
create database if not exists db1; -- 先判断再创建
create database db2 character set gbk; -- 创建时指定字符集
create database if not exists db3 character set gbk; -- 综合使用
Rtrieve 显示数据库
show databases;show tables;
show create database mysql; -- 查看某个数据库的创建语句(包含字符集信息)
Update 更改数据库
alter database db1 character set utf8; -- 注意不加中划线
Delete 删除数据库
drop database db1;
drop database if exists db1; -- 先判断再删除
使用数据库
查询当前正在使用的数据库名称
select database();
use db1;
操作表
Create 创建表
create table table1(
列名1 数据类型1,
列名2 数据类型2,
...
列名3 数据类型3);
数据类型
整数 int
小数 double(5,2) -- 最多5位,小数点后保留2位
日期 date -- 只包含年月日,格式为 yyyy-MM-dd
datatime -- 包含年月日时分秒,格式为 yyyy-MM-dd HH:ss:mm
timestamp -- 特点:如果不赋值,则默认使用添加记录时系统时间自动赋值
字符串 varchar(20) -- 最大20个字符
create table stu like student; -- 克隆student表
Rtrieve 显示表
show tables; -- 查询某个数据库中所有表名称
desc table1; -- 查询某个表结构 description
Delete 删除表
drop table t1;
drop table if exists t1;
Update 修改表
alter table t1 rename to t2; -- 修改表名
show create table t2;
alter table t1 character set gbk; -- 修改表的字符集
修改列
alter table t1 add gender varchar(10); -- 添加一列
alter table t1 change gender sex varchar(10); -- 修改列名
alter table t1 modify sex varchar(20); -- 篡改列的类型
alter table t1 drop sex; -- 删除列
DML(数据操作语句)
——增删改表中数据
添加数据
insert into student(id,name,gender) values(1,'张无忌','男');
注意事项:列名和值要一一对应,值类型也要对应
如果不写列名,默认给所有字段添加值
不想赋值的列,可以用NULL代替
除了数字类型,其他类型需要使用引号(单双都行)
日期使用 '1994-04-05'的格式赋值
更新数据
update student set age=19,set score=90 where id=1; -- 多个记录用逗号隔开
删除数据
delete from student; -- 删除所有数据,效率低,一条一条地删除,但是有日志记录,有可能找回来
delete from student where id=1; -- 删除表中id为1的数据
truncate table student; -- 删除表,然后再创建一个一模一样的空表,效率更高,推荐使用,不过这种删除的更彻底,找不回来
DQL(数据查询语句)
——查询表中数据
例如:select * from student;
语法格式:
select 字段列表
from 表明列表
where 条件列表
group by 分组字段
having 分组之后的条件
order by排序
limit 分页限定
多个字段查询 用逗号隔开
select name,age,score from 表名;
去重
select distinct address from student;
计算
select name ,math,english,math+english from student;
如果算式中包含null,则结果也为null
select name ,math,ifnull(english,0) ,math+english from student;
如果english为null,则替换成0
注意 IFNULL 方法不用来修饰原始列,而是用来修饰结果列
起别名
select name ,math,ifnull(english,0) ,math+english [as] 总分 from student;
select name ,math,ifnull(english,0) ,math+english 总分 from student;
逻辑运算符
> < = <> != >= <=
between ... and ...
AND &&
OR ||
IN关键字
例如:where math IN (88,90,99) -- math在其中
模糊查询
使用LIKE关键字
% 任意个任意字符
_ 单个任意字符
判断空值
IS NULL
IS NOT NULL
第二天
1、DQL
排序
order by 排序字段 [排序方式] [,排序字段 排序方式]
排序方式
ASC 升序(默认)
DESC 降序
聚合函数
将一列数据作为一个整体,进行纵向运算
count -- 计算个数
max -- 计算最大值
min -- 计算最小值
sum -- 求和
avg -- 计算平均值
案例
select sum(name) from student3;
注意,聚合函数的运算会忽略NULL值
解决方式
①避免计算包含null的列(选择主键计算)
②select count(ifnull(english,0)) from student3;
③select count(*) from student3; -- 只要有数据就会计算
分组计算查询(和聚合函数搭配使用)
group by 分组字段
注意,1 分组之后查询的字段:分组字段或聚合函数,其他字段没意义
select sex,avg(math) from student3 group by sex;-- 按照性别分组,分别求男、女平均分
select sex,avg(math), count(id) from student3 group by sex;-- 按照性别分组,分别求男、女平均分
分组计算前的条件限定
select sex,avg(math) from student3 where math>70 group by sex; --不满足条件不参与分组
having 关键字
分组计算后的条件限定
select sex,avg(math) from student3 group by sex having count(id)>2;
关键字having是以组为最小单位做判断,判断的内容必须和组有关系
注意where和having的区别:
where在分组前对单条数据筛选,后面不可以跟聚合函数
having在分组后对组筛选,后面可以跟聚合函数
自动增长
如果某一列是数值类型,使用auto_increment关键字完成自动增长
语法: primary key auto_increment
删除时,使用alter修改表,字段部分直接不写
注意,只能有一个字段被设置成自增
2、非空约束 not null
①创建表时添加约束
关键字 not null
②创建后修改表的字段时添加约束
删除约束时,直接不写约束就行
3、唯一约束 unique
关键字 unique
注意,添加约束时,不能有重复元素
mysql中唯一约束的值可以有多条null
注意,删除的时候需要特别语句 drop index 字段名
例如:alter table student drop index phone;
4、外键约束 foreign key
——在一张表中记录另一张表的主键信息,减少冗余
[constrant 外键名] foreign key (外键列名) references 主表 (列名)
注意,上述外键名只是索引名,要先添加外键列再添加外键约束
数据冗余 拆分表
删除外键约束
alter table employee drop foreign key 外键名
创建后再添加外键约束
alter table employee add constrant 外键名 foreign key (外键列名) references 主表 (列名)
注意,外键列不一定是主键,只要是唯一属性的都可以作为外键
外键可重复也可以为null,但不能是主表不存在的值
学习如何用工具操作
级联操作
级联更新
需要在添加外键的同时,设置级联
on update cascade
级联删除 (危险操作!慎用!)
on delete cascade
3、多表关系
1、一对一
人 - 身份证
如何实现?
任意一方设置外键关联对方的主键,并且让其外键唯一
2、一对多(多对一)重要
部门 - 员工
3、多对多
学生 - 课程(至少出现三张表) 需要设计学生-课程关系表
关系表建议设置联合主键
4、范式
——设计数据库时需要遵循的规范
第次规范
第一范式、第二范式、第三范式
冗余度随级别升高而减少
第一范式(1NF):每一列都是不可分割的原子数据项
第二范式 (2NF):在1F的基础上,消除非主属性对码的部分依赖(不完全依赖)
函数依赖 A -> B 如果通过A能确定B,则成B依赖于A
学号 -> 姓名 姓名依赖于学号
属性组(学号,课程) -> 分数
完全函数依赖 A -> B 如果A是一个属性组,则B的属性值确定完全依赖与A属性组
不完全依赖 A -> B 如果A是一个属性组,则B的属性值确定只依赖于A的部分属性
传递函数依赖 A -> B && B-> C => A -> C 称:C传递依赖于A
学号 -> 系别 系别 -> 系主任
码: 在一张表中,一个属性或属性组被其他所有属性所依赖
属性组(学号+课程名称)为一个码
第三范式 (3NF):消除传递依赖
5、数据库备份还原
数据库管理员的工作
1、命令行
备份:
mysqldump -u用户名 -p密码 数据库名称> 保存的路径(以sql的形式保存) 还原:
注意,还原之前要保证MySql中存在一个空的同名数据库
use 数据库名称; source sql路径名;
2、图形化工具
点点鼠标
第三天
1、多表查询
笛卡尔积:有两个集合A ,B ,取这两个集合的所有组合情况
笛卡尔积就是多表连接查询
select * from emp,dept
因此要消除笛卡尔积中无用的数据
多表查询的分类
1、内连接查询
1、隐式内连接
使用where语句
select * from emp,dept where emp.dept_id=dept.id
给字段起别名
select...
from emp t1,emp t2 -- 起别名
where...
(sql语句建议竖着写,方便加注释)
2、显式内连接
语法:select 字段 from 表名1 [inner] join 表名2 on 条件
select * from emp inner join dept on emp.dept_id=dept.id;
select * from emp inner dept on emp.dept_id=dept.id;
2、外连接查询
1、左外连接
语法:select 字段列表 from 表名1 left [outer] join 表名2 on 条件
select * from emp left outer join dept on emp.dept_id=dept.id;
select * from emp left join dept on emp.dept_id=dept.id;
以左表为主,查询左表所有信息,根据连接条件显示出对应的右表的信息
2、右外连接
语法:select 字段列表 from 表名1 right [outer] join 表名2 on 条件
select * from emp right outer join dept on emp.dept_id=dept.id;
select * from emp right join dept on emp.dept_id=dept.id;
以右表为主,查询右表所有信息,根据连接条件显示出对应的左表的信息
注意:左外连接和右外连接可以相互转换,只是一个相对的概念,一般使用左外连接即可
3、子查询
——查询中嵌套查询,称为子查询
前两种查询都是将上一个查询语句的结果作为下一个查询的条件
子查询是虚拟表作为查询的目标
1、子查询的结果是单行单列
子查询结果作为条件,使用逻辑运算符 = > < 去判断
-- 查询工资小于平均工资的人
select * from emp where salary < (select AVG(salary) from emp)
2、子查询的结果是多行单列
子查询结果作为条件,由于条件是一个集合,使用逻辑运算符 IN 去判断
-- 查询财务部和销售部所有员工的信息
select * from emp where dept_id in (select id from dept where name='财务部' or name='销售部' )
3、子查询的结果是多行多列
上一个结果作为一个虚拟表作为表的查询,而不是条件
-- 查询入职日期是2011-11-11日之后的员工信息和部门信息
select * from dept t1, (select * from emp where emp.join_date > '2011-11-11') t2 where t1.id = t2.dept_id;
嵌套查询的优缺点
优点:嵌套查询是先筛选再连接,处理的数据量更小,效率更高
缺点:查询的字段只能是父表中的字段,无法获取子查询中的字段,而连接查询 可以查询到多表的任何字段
sql注入 a' or 'a' = 'a
PreparedStatement
预编译:参数使用占位符?替代
sql的参数使用?作为占位符
例如:select * from user where name=? and password=?
setXxx(参数1,参数2)
参数1:?的位置
参数2:?的值