为什么要学数据库?
数据的保存:大量程序产生的数据在程序运行时和程序结束运行后
数据的完整性:数据和数据之间的结构关系, 数据和程序之间的依赖关系
数据的读取:普通的文本文档在写数据时 虽然方便,但是在读取数据时则比较麻烦,需要根据各 种形式去做转化
数据的安全性:防止数据因为硬件故障、 断电、死机、人为的误操作、 程序缺陷、病毒或黑客等造成的丢失
结构化:数据在数据库中的存储可以依靠二维表结构来逻辑的存储数据,可以参考数据原有的依赖关系和结构关系去存储数据。
共享性:多个用户可以共同分享计算机数据库中的数据资源,同一数据可以同时被多人使用,从而实现了数据的高效共享性。
独立性:存储在数据库的数据和应用程序之间相互独立, 互不影响。数据在磁盘上怎样存储由数据库管理而不依赖于应用程序,这样当数据的物理存储改变了,应用程序不用改变。
安全性:数据库在安全性的控制上也有很多措施,比如访问数据库时对用户的口令,用户的权限进行限制,再比如对数据的存储进行限制。
数据库(Database,简称DB)概念:长期存放在计算机内,有组织、可共享的大量数据的集合,是一个 数据“仓库”。作用:存放、管理数据。
数据库分为:
关系型数据库:Mysql,Oracle,PostgreSQL
非关系型数据库:redis,mongoDB
MySQL数据库的特点 :
开源免费,小巧但功能齐全
可在Windows和Linux系统上运行
操作方便,适用于中小型甚至大型网站应用
DDL(数据定义语言):定义和管理数据对象,如数据库,表等
DDL语句操作数据库:
创建一个库:create database 库名;
删除一个库:drop database 库名;
使用库:use 库名;
查看数据库:show databases;注意s不要省略
DDL创建数据库表:
查看库中所有的表:show tables;
建表:create table 表名 (
字段名 类型 [属性] [索引] [注释],
字段名 类型 [属性] [索引] [注释],
字段名 类型 [属性] [索引] [注释]
);
查看表结构:
方式一:describe 表名;方式二:show create table 表名;
DDL修改和删除数据库表:
改变字段的属性:
alter table 表名 modify 字段名 要修改的属性;
alter table 表名 change 旧的字段名 新的字段名 要修改的属性;
添加字段:alter table 表名 add 字段名 类型 属性;
删除字段(危险操作):alter table 表名 drop 字段名;
修改表名:alter table 旧表名 rename as 新表名;
删除表(危险操作):drop table 表名;
DML语句(数据操作语言):用于操作数据库对象中所包含的数据
新增语法:insert into 表名(字段名,字段名...字段名)values (值,值...值);
修改语法:update 表名 set 字段名=值,字段名=值...where字句;
删除语法:delete from 表名 where字句;
清空表:truncate 表名;
DQL语句(数据查询语言):用于查询数据库数据
查询:
select * from student;
select sid,sname,birthday,ssex,classid from student;
字段起别名:
select sname as '姓名', birthday '生日',ssex 性别 from student;
去除重复:distinct
select distinct ssex,classid,sid from student;
带条件的查询 where字句:
select * from student where ssex='男' and classid=1;
生日大于1990-1-1的学生:
select * from student where birthday<'1990-1-1';
模糊查询:
模糊符号% 任意多的任意字符
模糊符合_一个任意字符
select * from student where sname like '%王%';
select * from student where sname like '王_';
in在特定范围内查找:
select * from student where sid in (2,5,6,9);
is是对null的判断:
select * from student where birthday is null;
select * from student where birthday is not null;
聚合函数
count(字段) -- 统计个数
-- 数字
avg(字段) -- 平均值
sum(字段) -- 总和
max(字段) -- 最大值
min(字段) -- 最小值
-- count() 不统计null:
select count(birthday) from student;
分组: group by 字段
每个学生的成绩信息
select sid,avg(score) 平均分,sum(score) 总分,count(*) 次数,max(score) 最高分,min(score) 最低分 from sc group by sid;
分组
-- where 是对聚合(分组)前的每一条数据的筛选
-- having 是对聚合(分组)后的每一条数据的筛选
-- having 不能单独出现,必须要有group by
select sid,avg(score) from sc group by sid having avg(score) >80 ;
select sid,avg(score) from sc where sc <60 group by sid;
排序 order by
-- 升序 ASC
-- 降序 DESC
select * from student order by sid;
-- 多排序规则按照 order by 后面的字段 先写先排后写后排
select * from sc order by score desc, sid desc;
分页 limit
-- 一页看3个学生
-- (页码-1)*步长,步长
select * from student limit 6, 3;
成绩表中及格的成绩的总成绩是第二名的学生编号和平均分
select sid,avg(score) from sc group by sid having sum(score) >=60 order by sum(score) desc limit 1,1
多表联查
-- 非等值查询:SELECT * FROM 表1,表2
-- 笛卡尔积
select * from student, class
-- 等值查询:SELECT * FROM 表1,表2 WHERE 表1.字段1 = 表2.字段2...
-- 内联数据
select *from student, class where student.classid = class.classid
连接查询:
语法:SELECT * FROM 表1 LEFT|right|INNER JOIN 表2 ON 条件
left jion:从左表(表1)中返回所有的记录,即便在右 (表2)中没有匹配的行。
right jion:从右表(table_2)中返回所有的记录,即便 在左(table_1)中没有匹配 的行。
inner jion:在表中至少一个匹配时,则返回记录。
-- 外联查询
-- left join on 左外联
select * from student left join class on student.classid = class.classid
-- right join on 右外联
select * from class right join student on student.classid = class.classid
左表独有的数据: select * from t1 left join t2 on t1.id = t2.id where t2.id is null;
右表独有的数据: select * from t1 right join t2 on t1.id = t2.id where t1.id is null;
union是求两个查询的并集。 union合并的是结果集,不区分来自于哪一张表,所以可以 合并多张表查询出来的数据。
union 会去除重复的数据(DISTINCT 一致)
union all 不会去重
注意: 1列名不一致时,会以第一张表的表头为准,并对其栏目。
2会将重复的行过滤掉。
3如果查询的表的列数量不相等时,会报错。
4在每个子句中的排序是没有意义的,mysql在进行合并的时候会忽略掉。
5如果子句中的排序和limit进行结合是有意义的。
6可以对合并后的整表进行排序
子查询:子查询,又叫内部查询
1. where 型子查询:
-- 查询id最大的一个学生
select * from student order by sid desc limit 1;
- 查询id最大的一个学生(子查询)
select * from student where sid = (select max(sid) from student);
2 from型子查询:
把内层的查询结果当成临时表,供外层sql再次查询。查询结果集可以当成表看 待。 临时表要使用一个别名。
-- 查询大于5人的班级名称和人数
select classname,count(*) from student
left join class on student.classid = class.classid
group by class.classid
-- from 子查询
select classname,a 人数 from class
left join (select classid, count(*) a from student group by classid)t1
on class.classid = t1.classid
3 exists型子查询:
把外层sql的结果,拿到内层sql去测试,如果内层的sql成立,则该行取出。内层查 询是exists后的查询。
-- 从学生表中取出学生的信息,(如果该性别下没有男学生则不显示)
select * from student where exists (select * from student where ssex='男')
4 any, some, all子查询:
(1) any 子查询 表示满足其中任意一个条件 假设any内部的查询语句返回的结果个 数是三个, 如:result1,result2,result3,那么, select ...from ... where a > any(...);
->相当于: select ...from ... where a > result1 or a > result2 or a > result3;
some 是 any的别名,所以用法是一样的,可以替代使用
-- 查询出一班成绩比二班最低成绩高的学生
select * from student inner join sc on student.sid = sc.sid
where classid = 1 and score > any(select score from student inner join sc on student.sid = sc.sid where classid = 2);
(2)all 子查询 表示满足其中所有条件条件,ALL关键字与any关键字类似,只不 过上面的or改成and。 假设any内部的查询语句返回的结果个数是三个,
select ...from ... where a > all(...);
-> select ...from ... where a > result1 and a > result2 and a > result3;
--查询出一班成绩比二班最高成绩高的学生
select * from student inner join sc on student.sid = sc.sid where classid = 1 and score > all(select score from student inner join sc on student.sid = sc.sid where classid = 2)
控制sql语句
if(v,v1,v2)
v 逻辑表达式 Boolean值
如果真 显示v1
如果假 显示v2
select tid,tname,if(tsex=1,'男','女'),tbirthday from teacher
ifnull(v,v1)
v 字段
v1 如果字段的值是一个null v1就显示
select sid,sname,ifnull(birthday,'1900-1-1') birthday,ssex,ifnull(classid,3) classid from student
Case具有两种格式。简单Case函数和Case搜索函数。
-- 简单case
select tid,tname,
case tsex
when 1 then '男'
when 0 then '女'
else '未知'
end tsex,
tbirthday, taddress from teacher
-- 搜索case
select tid,tname,
case
when tsex > 1 then '未知'
when tsex = 1 then '男'
when tsex < 1 then '女'
else '不能出现情况'
end ,
tbirthday,taddress from teacher