update 表名 set 值=新值 where 列名 in (select 列名 from 表名 where 筛选条件)
删除
delete from 表名 where 筛选条件
插入指定列名
insert [into] 表名(列名1,列名2.。。)values(列值1,列值2.。。);
不指定字段
insert 表名 values (‘1002’,‘李璐0’,null)
插入多行
insert 表名 (列名1,列名2)values (列值1,列值2),(列值1,列值2);
INSERT student (id,name,zz) SELECT id,name,zz from student;
sql语句基本格式:
select<输出字段>from 表1,表2{。。。} where <表1,字段名1><链接谓词><表2.字段2> group by 字·段名 having 条件 order by 字段名 sac/desc limit n,m
select distinct 字段列表 或 函数 或 表达式 as 别名 from 表名 as 别名 where 条件 group by 字段名
Having 条件表达式 order by 字段名 asc,desc limit n,m;
E-R图:1:1 1:多 多:多
数据库设计模型
概念模型:对客观事物的描述
逻辑模型:(层次模型、网状模型、关系模型)反映的是系统分析设计人员对数据存储的观点
物理模型:反映数据在数据库中存储的观点
数据库物理模型:
PDM(物理模型)中涉及到的一些基本概念包括:
·表、列、主键、外部键
·视图、存储过程、触发器
·完整性的检查
MYSQL系统优点:
开源(免费下载)、简单(体积小、便于安装)、性能优越(性能足够与商业数据库媲美)、功能强大(提供的功能足够与商业数据库媲美)
数据完整性约束
常用的约束条件有6种:
主键约束
外键约束
唯一性约束
默认值约束
非空约束
检查约束(MySQL不支持)
数据库的范式(各种范式称帝次规范,越高的范式数据冗余越小)
第一范式的目标是确保每列的原子
第二范式要求每个表只描述一件事情
第三范式:如果一个关系满足2NF,并且除了主键以外的其他列都不传递于主键列
SQL:结构化查询语言
四大类:
1、数据查询语言(DQL):按照指定的组合、条件表达式或排序检索已存在的数据库中的数据,但并不改变数据库中数据
2、数据定义语言(DDL):创建、修改或删除数据库中各种对象,包括表、视图、检索等。
3、数据操纵语言(DML):对以存在的数据库进行记录的插入、删除、修改等操作。
4、数据库控制语言(DCL):用来授予或收回访问数据库的某种特权、数据库事物控制。
SELECT查询:
1、查询全部记录:select * from pet;
2、查询表中birth列的记录:select birth from pet;
3、查询表中birth和name两列记录:select birth,name from pet;
4、select dinstinct address from student。查询学生来自不同的城市,列出城市列表,(去重)
5、select dinstinct address name,city from student。查询学生来自不同的城市且不同姓名,列出城市列表,(去重)
6、select * from pet where name=‘xiaohong’;查询表里所有的列中的xiaohong的信息
7、、select * from pet where birth>‘1990-08-27’;查询表里所有列中大于1990-08-27的信息
8、select birth from pet where name=‘xiaohong’;
9、select birth,name from pet where name=‘xiaohong’;
where语句后的特殊表达式
like 字符匹配操作符
% 通用符,包含0个或多个字符的任意字符串
between and 定义一个区间范围
is{not}null 检测字段值为空或不为空
{not}in 检查一个字段值属于或不属于一个集合
exists 检查某一字段是否存在值
1、查询name字段中包含有鑫字的:select * from tablel where name like“%鑫%”;
2、查询name字段中不以“李”字开头:select * from tablel where name not like“李%”;
between and是定义一个区间的范围
查询1990年1月1日至1991年12月32日出生的学生的学号、姓名、出生日期
select student-id,student-name,born-date from student where born-date between‘1990-1-1’and‘1991-12-31’;
is null
查询备注内容为空的学生的学号、姓名与备注
select student-id,student-name,resume from student where resume is null;
in
查询来自长沙和广州市学生的姓名、班级编号和来自的城市
select student-name,class-id,address from student where address in(‘长沙’,‘广州’)
查询有订单的用户信息
select * from
大于20岁的女生和大于28的男生的信息
select * from student where (sage > 23 and ssex = '女' ) or (sage > 20 and ssex = '男' );
查询课程表中非公共课的课程信息
select * from course where not(c-type=‘公共课’);
查询学生表中来自广州市的学生或者来自其他地方的女学生的学号、姓名、班级编号、家庭住址和备注信息
select student-id,student-name,class-id,address,resume from student where address='广州市' or sex=‘女’;
算数运算符
+-*/%
select a,a+30,a-25+16 from t01;
select a,a+30 from t01 where a%30=0
order by
单列升序
select<column-name>from<table-name>order by<column-name>
单列降序
select<column-name>from<table-name>order by<column-name>desc
多列升序
select<column-name>,<colunm-two>from<table-name>order by<column-one>
多列降序
select<column-name>,<colunm-two>from<table-name>order by<column-one>desc
多列混合排序
select * from chengji order by yuwen desc,shuxue desc;
limit
select * from table limit5,10;检索记录行6-15
select * from table limit95,-1;检索记录行96-last
select * from table limit5;检索前5个记录行
where+order
select {column1},{column2},...from table where columnx = value order by sort;
where+多个字段order by
select * from table where uid=1 order by x,y;
where+多个字段order by+limit
select * from table where id=92876 order by match-weight desc limit 0,3;
函数
聚合函数、日期函数、字符串函数、数字函数
聚合函数:是对一组值计算后返回单个值。
count 统计表中元组个数
select count * fromstudent
count 列名 ,统计本列非空值个数 去重
select count distinct lieming from student
sum distinct lieming 计算列总和
avg distinct lieming 计算列值得平均值
max distinct lieming 计算列值的最大值
min distinct lieming 计算列值的最小值
数学函数
abs lie 绝对值
SELECT ABS (jg) from caidan;
mod lie 余数
SELECT MOD (jg,2) from caidan;
round lie 四舍五入的一个整数
SELECT ROUND (jg) from caidan;
sqrt(X)返回X的平方根
SELECT SQRT(jg) FROM caidan;
power(X,Y)幂运算
SELECT POW(jg,2) FROM caidan;
rand()用来生成0-1.0的随机数
SELECT RAND() FROM caidan;
sign(X)返回当前结果的符号
SELECT SIN(jg) FROM caidan;
floor lie 不大于的最大整数值
SELECT FLOOR(jg) from caidan;
ceiling lie 不小于的最小整数值
日期函数
now()以yyyy-mm-dd hh:mm:ss 格式返回当前日期和时间
current-time 以hh:mm:ss格式返回当前时间值
second(time)返回time的秒数 0-59
minute(time)返回time的分钟
hour(time)小时
select 。。。。。;
month(date)返回date的月份
year(date)返回date的年份
dayofyear(date)返回date在一年中的日数
dayofmonth(date)返回date的月份中的日期
quarter(date)返回date一年中的季度
monthname(date)返回date的月份
dayname(date)返回date的星期名字
dayofweek(date)返回日期date的星期索引 1=星期天 2=星期一
weekday(date)返回date的星期索引 0=星期天
week(date,first)对于星期天是一周的第一天的地方,有一个单个参数,返回date的周数
字符串函数
ASCII(str)返回字符串str的最左面字符的ASCII代码值。如果str是字符串,返回0
select ascii('2') 字符都以该字符对应的ASCII码存储,共256个,
concat(str1,str2,。。)返回来自于参数连接的字符串,如果任何参数是NULL,返回NULL
select concat('my','s','ql'); MySQL
concat-ws(separator,str1,str2,..)将多个字符串参数以给定的分隔符separator首尾
查询。。。用逗号连接后的数据
SELECT CONCAT_WS(',',sid,sname,sage) from student;
trim(str)返回字符串Tr所有前缀或后缀被删除了
ltrim(str)返回删除了其前置空格字符串str
ririm(str)返回删除了其拖后空格字符串的字符串str
length(str)返回字符串str的长度
查询出订单留言内容超过十个字的订单
SELECT * FROM student WHERE LENGTH(dizhi)>10;
lower(str)返回小写的字符串 select lower('quadratically');
upper(str) 返回大写的字符串
reverse(str)返回颠倒字符顺序的字符串str
查询学生信息表中姓名重复为叠名的学生信息
select * from student where recerse (name)=name;
replace(str,from-str,to-str)返回字符串str,其字符串from-str的所有出现由字符串
slect replace(str,from-str,to-str);
substring(str,pos)从字符串str的起始位置pos返回一个子串
select substring(str,pos);
查询学生表里的名字为叠名(性只有一个字)
select * from student where substring(sname,2,1)=substring(sname,3,1);
locate (substr,str)返回子串subster在字符串str第一个出现的位置
group by(分组)
group by从字母意思上理解就是根据‘by’指定的规则对数据进行分组。
例子:select 类别 from 表 group by 类别。
Having
Having只能与group by连用,跟在group by后面,语法与where 语法类似,都是用来筛选结果的。
例子:年销售额大于四万的
select pub_id,sum(ytd_sales)as total from titles group by pub_id Having sum (yid_sales)>40000;
having只能与group by连用,跟在group by后面,语法与where语法类似,都是用来筛选结果。
select pub-id,sum(ytd-salrs)as total from titles group by pub-id having sum(ytd-sales)>40000;
select 类别,sum数量from a group by 类别 having sum数量>20;
学生的他的总分
select xid,sum (chengji)from xscj where xage>20 group by xid havaing sum(chengji)>300;
SELECT * from a group by nl='8';
select sum(nl) from a;
select COUNT(nl) from a;
select nl from a group by nl;
每个年龄的人数
select COUNT(nl) from a group by nl;
8岁的人数;
SELECT COUNT(nl) from a group by nl Having nl="8";
每个年龄阶段的年龄总和;
SELECT SUM(nl) from a GROUP BY nl;
having和where
相同:都是用来设置条件,筛选结果
不同:having可以包含聚合函数,where不可以
在分组操作中,where子句搜索条件在进行分组操作之前应用,having搜索条件在进行分组操作之后应用。
sleect stu-type,sum(score)from student group by id,stu-type prder by id
order by 放在前面,表示先排序再分组
group by 放在前面,表示先分组再排序
group by 中的列,必须在order by 中有
别名
1、字段名 as 别名
2、字段名 别名
例子
select xid, (xage+10) as xage1 from student where xage1>30
select {distinct}<字段列表>或<函数>或<表达式>{as 别名}from <表明>{where<查询条件>}{group by<字段名>{having<条件表达式>}}
{order by《字段名》{as|desc}}{limit n,m}
列如
select id,mane,concat (id,name,pwd)from yonghu;
select pub_id,sum(advancr)as amount,avg(price)as averageprice from pubs where pub_id>0800 group bt pub_id havig sum(advance)>15000 and avg(price)<20;
SELECT DISTINCT name from shangdian;(去重)
upper大写
lower小写
多表查询
select caidan.*,dingdan.* from caidan,dingdan where caidan.cid=dingdan.did;
链接查询两大类:
使用链接谓词进行链接
sql语句基本格式:
select<输出字段>from 表1,表2{。。。} where <表1,字段名1><链接谓词><表2.字段2> group by 字段名 having 条件 order by 字段名 sac/desc limit n,m
使用关键字join进行链接
内连接
查询学生的基本信息和成绩信息
select student.*,svore.* from student inner join score on student.student_id=score.student_id;(内连接)
select student.*,svore.* from student,score where student.student_id=score.student_id;(等值链接)
select 查询内容 from 表1 inner join 表2 on链接条件
select 查询字段 from 表名 where连接条件
外链接
select 输出字段列表 from 表名1<链接类型>表名2 on<链接条件>{<链接类型>表名3 on<链接条件>}
内连接:inner join 左链接:left join 右链接:right join 全连接:full join 交叉连接:cross join
左链接:SELECT student.student_id,tudent_name,course_id,grade from student LEFT OUTER JOIN score on student.student_id=score.student_id;
右链接:SELECT student.student_id,class.class_id from studen RIGHT OUTER JOIN class on student.class_id=class.class_id
sql语句基本格式:
select<输出字段>from 表1,表2{。。。} where <表1,字段名1><链接谓词><表2.字段2> group by 字段名 having 条件 order by 字段名 sac/desc limit n,m
dml是指对数据库中表记录的操作,主要包括表记录的插入,更新,删除和查询
主要关键字包括:
select:查询
insert:插入记录
updata:更新
delete:删除
插入指定列名
insert [into] 表名(列名1,列名2.。。)values(列值1,列值2.。。);
不指定字段
insert 表名 values (‘1002’,‘李璐0’,null)
插入多行
insert 表名 (列名1,列名2)values (列值1,列值2),(列值1,列值2);
INSERT student (id,name,zz) SELECT id,name,zz from student;
更新数据
update student set 列名=‘50’ where sex=‘女’;
更新多个列的值
update 表名 set 列名1=新值1 where 筛选条件
update 表名 set 列名1=新值1 where 列名 in (select 列名 from 表名 where 筛选条件)
查询大于60 的 更新8
update student set lieming=8 where sid in (select sid from score where grade>60);
BETWEEN 60 and 80(之间)
创建:create
创建数据库:create database 数据库名
删除数据库:drop database 数据库名
展示所有数据库:show databases
创建表:create table 表名(列名 数据格式 列约束(unique), .......列名n 数据格式 列约束,foreign key(列名) references 关联表名(关联列名));
删除
delete from 表名 where 筛选条件
修改表名
slter table 表名 rename 新表明
修改表的列名和数据类型语法
alert table 表名 change 原列名 新列名 列类型;
修改表的列数据类型
alert table 表名 modify 列名 新数据类型;
添加列
alter table 表名 add (列名1 列类型)
删除列
alter table 表名 drop 列名
删除表
drop table 表名;
视图
基于某个查询结果的虚拟表格
create view 视图名称【(视图列表1,2)】
as select 语句
【with check option】
alter语句修改视图
alter definer = user current_user view 视图名称 as select语句;
definer = '用户名'@‘登陆主机’,例:definer = ‘test’@‘localhost’ 默认为current_user;
不能对视图做dml操作
1、select 子句中包含distinct,组函数,group by 和order by子句
2、where子句包含相关子查询
3、from 子句包含多个表
4、基表中的非空约束的列未出现在视图定义中,则不能做insert操作
视图中插入数据
insert into 视图名称 列名1,列名2 valuse 值1,值2;
删除视图是指删除数据库已存在的视图,删除视图时只能删除视图的定义,不会删除视图数据,也就是说基表不动
删除语法
drop view 视图名称1,视图名称2
存储过程
是一组为了完成特定功能的SQL语句集,经过编译后存储在数据库中,用户通过指定存储过程的名字给定参数来执行调用它
优点
1、增强了sql语言的功能和灵活性
2、避免了大量的重复工作
3、存储过程因为SQL语句已经编译过了,因此运行的速度比较快
4、主要在服务器上运行,减少了对客户机的压力。
存储过程的参数
in 输入参数 out 输出参数 inout 输入输出参数
创建语法
creat procedure 存储过程名
(in|out|inout)参数名 数据类型,
(in|out|inout)参数名 数据类型
begin
select语句
end
没有参数的存储过程
create procedure p_test()
begin
select 1;
end;
调用
call 表名();
只有输入参数
在student表中插入学生的学号
create procedure p_test(in xuehao int)
begin
insert student (sid)values (xuehao);
end;
调用:call p_test(001);
同时有输出和输入参数
通过学号查询某个学生的成绩
creat procedure p_test (in xh int,out cj int)
begin
select gore into cj from sgore where id=xh;
end;
调用:p_test call(1001,@c);
select @c;
创建存储过程需要注意的问题
1.参数需要注明类型(in,out,inout),多个参数之间用逗号隔开。
2.bengin和end之间用可以用多条SQL语句,用分号隔开
3.调用存储过程时,输入参数是一个值,而输出参数则必须是一个带@符号的变量
4.定义的参数类型,调用时的参数数据类型必须和原表中的数据类型一直
5.调用时的参数个数必须和定义的参数个数一致
触发器
是由事件来触发某个操作
作用
可以实现主键和外键所不能保证的复杂的参照完整性和数据的一致性,可以对数据进行级联修改,强制表的修改又合乎业务规则
常用的条件
insert(插入)
update(更新)
delete(删除)
分类
insert型触发器:插入某一行是激活触发器;
可能通过insert语句触发,包括before insert、 after insert、
update型触发器:更改某一行是激活触发器;
可能通过update语句触发,包括before update、 after update、
delect型触发器:删除某一行是激活触发器;
可能通过delect语句触发,包括before update、 after update、
创建语法
create trigger 触发器名称
before | after
insert | update | dalete on 表名 from each row
begin
SQL语句集;
end;
例如
在学生表上创建插入触发器
create teigger tr_stydent
after
insert on student for each row
begin
declare ssid int;
set ssid=new.id;
insert into sgore(sid)values (ssid);
end;
create teigger tr_stydent
after
insert on student for each row
begin
insert into sgore(sid)values (new.id);
end;
事务
通常一个事务对应一个完整的业务,一个完整的业务需要批量的dml语句共同联合完成。
特性:
原子性:一个事务的执行被视为一个不可分割的最小单元,事务里面的操作,要么全部成功执行,要么全部失败回滚,不可以只执行其中的一部分
一致性:事务开始前和结束后,数据库的完整性约束没有被破坏
隔离性:同一时间,只允许一个事务请求同意数据,不同的事务之间彼此没有任何干扰
持久性:事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚,即使系统故障也不会丢失
隔离级别
读未提交 read—uncommitted
不可重复读 read-committed
可重复度 repeatable-read mysql的默认
串行化 serializable
事务的流程语言
begin 或 start transaction 显示的开启一个事务
commit ;会提交事务,并试已对数据库进行的所有修改成为永久性
rollback work 回滚
savepoint identifier 允许在事务中创建一个保存点
release savepoint identifier 删除一个事务的保存点
rollback to identifier 把事务回滚到标记处
set transaction 用来设置事务的隔离级别
事务创建
事务开启的两个办法
1、用begin,rollback,commit来实现
begin 开始一个事务
rollback事务回滚
commit事务确认
2、直接用set 来改变mysql 的自动提交模式
set autocommit=0 禁止自动提交
set autocommit=1 开启自动提交
事务保存点实例
start reansaction;开始事务
insert into student (id) values(1);表里插入数据
savepoint my_savepoint;设置保存点
insert sthdent (id) values(2);表里插入数据
rollback to savepiont my_savepoint;回滚至保存点
insert into d values(3);表里插入数据
commit;提交
隔离
保证多个并发事务能够在同一台服务器上正确的,有序的完成各自的任务,保证不同事物之间没有干扰,避免数据交互产生的错误结果
级别
读未提交 read—uncommitted 脏读
不可重复读 read-committed 解决了脏读
可重复度 repeatable-read 解决了脏读和不可重复读
串行化 serializable
隔离相关语法
查看隔离级别
select @@tx—isolation;
设置隔离级别
set session transaction isolation level 级别名称;
脏读
一个事务正在访问数据,并且对数据进行了修改,而这种修改还没有提交到数据库中,这时,另一个事务也访问这个数据库,然后使用了这个数据。
虚拟数据:
BEGIN
#Routine body goes here...
DECLARE num INT DEFAULT 1;
WHILE num <10 DO
INSERT INTO tb-manager VALUES(num,CONCAT("ccf",num),"123456");
SET num=num+1
END while;
END;
练习:
查询出订单留言内容超过十个字的订单
SELECT * FROM student WHERE LENGTH(dizhi)>10;
查询学生表里的名字为叠名(性只有一个字)
select * from student where substring(sname,2,1)=substring(sname,3,1);
查询学生信息表中姓名重复为叠名的学生信息
select * from student where recerse (name)=name;
找出不同的店名
SELECT DISTINCT name from shangdian;
找出营业额超出1000的店名
SELECT DISTINCT name FROM shangdian WHERE qian>1000;
找出营业额高于1000或营业额在275及500之间的店名
select DISTINCT name from shangdian where qian>1000 or(qian<500 and qian>275);
统计各个班学生的总人数
select class_id,count(student_id)from student group by class_id
输出总分大于150的学生的学号、总分和平均分
select name,sum(qian) ssum,avg(qian) from shangdian group by name having ssum>150;
含有losangeles、sandiego的资料
SELECT * from xiaoshou WHERE name='losangeles'or name='sandiego';
时间内的资料
select * from xiaoshou where date between''and'';
找出店内含有AN的资料,AN不区分大小写
select * from xiaoshou where upper(name) like '%AN%'
平均数 多表查询
SELECT caidan.*,avg(dingdan.djg) from caidan,dingdan WHERE caidan.did=dingdan.did GROUP BY caidan.did;
多表查询
select caidan.*,dingdan.* from caidan,dingdan where caidan.did=dingdan.did;
查询学生的学号、姓名、所学课程的名称和成绩信息。
select student.student_id,student_name,course_name,grade from student,score,course where student.student_id=score.student_id and score.course_id=course.course_id
查找学生的学号课程号相同且成绩也相同
select a.student_id,b.student_id,a.course_id,a.grade from score a,score b where a.grade=b.grade and a.student_id<>b.student_id and a.coures_id=b.course+id
查询出各部门信息及所属上级部门信息,要求包括部门id、部门名。上级部门id、上级部门名
select b1.id,b1.bmm,b1.sid,b2.bmm FROM bmxxb AS b1,bmxxb AS b2 where b1.sid=b2.id;
查询001课程比002课成绩高的所有学生学号
select scl.sid from sc sc1 ,sc sc2 where scl.cid = '001'and sc2.cid='002'and scl.score>sc2.score
查询平均成绩大于60分的同学的学号和平均成绩
select sid.avg(score) pingjun from sc group by sid having pingjun>60;
查询所有同学的学号,姓名,选课书,总成绩
select student.sid,student.name,count(sc.cid),sum(score) from student,sc where student.sid=sc,sid group by student.sid;
查询姓李老师的个数
select count(tid) from teacher where tname like"%李%"
查询没有学过叶萍老师课的同学学号,姓名:
select student.sid,student.sname
from student
where sid not in (select) from sc,course,teacher where
teacher.tid=course.tid and teacher.tname="叶萍"
没有选修1001号课程的学生记录
select * from student where id not in (select cid from score where cid = '1001');
查询出01班中年龄大于02班所有人的同学
select * from student where banji='01' and age >all (select age from student where banji='02')
插入数据
INSERT student (id,name,zz) VALUES ('1001','杨杰','北京');
INSERT student VALUES ('1001','杨杰','北京');
吧北京的id改为2
update student set id='2' where zz='北京';
把2018年5.2的列改为男,20.
update student set sex='男',age=20 where time='2018-05-02';
查询大于60 的 更新8
update student set lieming=8 where sid in (select sid from score where grade>60);
事务保存点实例
start reansaction;开始事务
insert into student (id) values(1);表里插入数据
savepoint my_savepoint;设置保存点
insert sthdent (id) values(2);表里插入数据
rollback to savepiont my_savepoint;回滚至保存点
insert into d values(3);表里插入数据
commit;提交
事务
创建一个事务,A账户余额减少200,B账户余额增加200.
start transaction;
update shiwu set a = a-200 where id=1;
savepoint my_savepoint;
update shiwu set a = a+200 where id=2;
commit;