mysql
来源:互联网 发布:荣威i6 知乎 编辑:程序博客网 时间:2024/06/07 06:11
1 introduction
mysql是一个关系型数据库管理系统,由瑞典mysql ab 公司开发,目前属于 oracle 旗下产品。关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。在业界,由于mysql的开源特性,与操作系统linux,服务器apache或者nginx,脚本解释器php/perl/python,并称为“lamp”或者“lnmp”组合。
mysql使用sql语言访问数据库。结构化查询语言(structured querylanguage)简称sql,是一种特殊目的的编程语言,是一种数据库查询和程序设计语言,用于存取数据以及查询、更新和管理关系数据库系统;同时也是数据库脚本文件的扩展名。结构化查询语言包含6个部分:一:数据查询语言(dql:data querylanguage):其语句,也称为“数据检索语句”,用以从表中获得数据,确定数据怎样在应用程序给出。保留字select是dql(也是所有sql)用得最多的动词,其他dql常用的保留字有where,order by,group by和having。这些dql保留字常与其他类型的sql语句一起使用。二:数据操作语言(dml:data manipulation language):其语句包括动词insert,update和delete。它们分别用于添加,修改和删除表中的行。也称为动作查询语言。三:事务处理语言(tpl):它的语句能确保被dml语句影响的表的所有行及时得以更新。tpl语句包括begin transaction,commit和rollback。四:数据控制语言(dcl):它的语句通过grant或revoke获得许可,确定单个用户和用户组对数据库对象的访问。某些rdbms可用grant或revoke控制对表单个列的访问。五:数据定义语言(ddl):其语句包括动词create和drop。在数据库中创建新表或删除表(creat table 或 drop table);为表加入索引等。ddl包括许多与人数据库目录中获得数据有关的保留字。它也是动作查询的一部分。六:指针控制语言(ccl):它的语句,像declare cursor,fetch into和update where current用于对一个或多个表单独行的操作。(来源自百度百科)
2 数据库操作
1) 创建数据库
createdatabase shujuku;
createdatabase zifuji character set utf8;
showdatabases;
showcreate database zifuji;
2) 删除数据库
dropdatabase shujuku;
3) 切换数据库
usedatabase zifuji;
4) 修改数据库编码集
alterdatabase shujuku character set utf8;
5) 查看正在使用的数据库
selectdatabase();
3 数据库数据类型
1) 字符型
varchar char
都用来存储字符串长度小于255的字符。
char(20)===只能存长度为20的数据 ,哪怕不存任何的数据 20的空间还是被占用。varchar(200)===只能存取200的数据,但是,如果只存20,剩下的空间会自动释放 可变字符型
2) 文本型
text
使用文本型数据,你可以存放超过二十亿个字符的字符串。当你需要存储大串的字符时,应该使用文本型数据。一个文本型字段中的数据通常要么为空,要么很大。文本型字段既大且慢,滥用文本型字段会使服务器速度变慢。文本型字段还会吃掉大量的磁盘空间。
3) 数值型
整数 tinyint smallint int bigint
浮点数float double
数型numeric:numeric型数据使你能表示非常大的数——比int型数据要大得多, numeric型数据还能表示有小数部分的数。
钱型money smallmoney
money型数据可以存储从-922,337,203,685,477.5808到922,337,203,685,477.5807的钱数。
4) 逻辑型
bit:bit型字段只能取两个值:0或1。
5) 日期型
datetime smalldatetime
一个 datetime型的字段可以存储的日期范围是从1753年1月1日第一毫秒到9999年12月31日最后一毫秒。
4 表操作
1) 创建表
createtable newtable(
id int(20) primary key auto_increment,
name varchar(20) unique,
address varchar(50) not null
);
2) 修改表结构
增加列
altertable newtable age int(2) not null;
修改列名
altertable newtable change name username varchar(20) unique;
修改列的属性等
altertable newtable modify address varchar(20) unique;
删除列
altertable newtable drop sex;
修改表名
renametable newtable to oldtable;
显示当前库中所有的表
showtables;
修改表的字符集
altertable newtable character set utf8;
删除表
droptable newtable;
显示表的字符集编码
showcreate table newtable;
5 数据库注释
/*
多行注释
*/
- - 单行注释,可用于sqlinject
6 数据库字段操作
crud
create 增 read读 update 改 delete 删
1) 向数据表插入数据
insertinto newtable (id,name,address) values (1,’aa’,’bbb’);
或者
insertinto newtable values (null,’aa’,’bbb’),(null,’aa2’,’bb2’);
2) 更新数据
updatenewtable set name=’aa3’,address=’cc3’ where id=1;
3) 删除数据
deletefrom newtable where name=’aa3’;
deletefrom 表名;和truncate table 表名;区别?
delete:直接把表中的数据按照行删除。 truncate:它是先把表删除,然后再创建一张新的表。
truncate删除表比较快,但删除的数据不能恢复,不能rollback回滚,只能删除表中的所有数据,而delete删除比truncate慢,删除的数据可以恢复,可以rollback回滚,后面可以跟where条件删除某些指定记录。
drop tablestudent和deletefrom sdudent 的区别?
drop:数据被删除同时表也被删除。
delete:只是删除表中的数据,表还是存在。
4) 查询数据
① 查询数据库中所有的数据
select * from newtable;
② 查询表中列的记录
select id,name from newtable;
③ 按条件查询
select name,address from newtablewhere id>3;
判断条件:
a.相等= 不等< >
b.区间between...and...
c.in(23,25,26) 相当于where age=23 or age=25 or age=26
d.模糊查询 like。where name like... %:表示任意字符 _:单个的任意字符
example:name like ‘张%’; namelike ‘%张%’; name like ‘张_’; name like ‘_张_’
e.is null 判断该列的记录是否为空
where name is null; where name is not null;
f. 逻辑运算符
and or not
④ 对查询的结果进行排序
a.降序
select * from newtable order by ageasc;
b.升序
select * from newtable order by agedesc;
c.可变参数排序
select * from newtable order by agedesc,score asc;
排序可以应用于排行榜,查询最小值,最大值的操作。
⑤ 给查询出来的列明取别名
select name as username from newtablewhere id=1;
//省略关键字 as
select name username from newtablewhere id=1;
question:下面两条sql的区别
select age score from student;
//这从student表中查询出age一列,并且将age起别名为score
select age,score from student;
//这是直接查询的两列数据
5) sql函数(聚合函数)
① count() 统计记录的个数
select count(*) from newtable; select count(行数) from newtable;
② sum() 求和
select sum(列名) from newtable;
select sum(score) from newtable; select sum(age)+sum(score) from newtable; select sum(ifnull(age,0) from newtable;
③ avg() 求平均数
select avg(age) from newtable;
④ max() min()
select max(age) from newtable; select min(age) from newtable;
⑤ group by 分组函数
create table orders(
idint primary key auto_increment,
productvarchar(20),
pricenumeric(18,2)
);
insert into orders values(null,'电视',5000);
insert into orders values(null,'洗衣机',300);
insert into orders values(null,'冰箱',1000);
insert into orders values(null,'洗衣粉',5);
insert into orders values(null,'桔子',2);
insert into orders values(null,'电视',5000);
insert into orders values(null,'洗衣粉',10);
select produnt,sum(price) from odersgroup by product;
同时出现需要group by 分组函数, order by 关键字,where或having 条件语句,或者出现其中两个时,它们的先后顺序是
group by>order by>where或者having
如果有聚合函数的话,先分组,再进行计算;select 后面跟着的是被分组的列,或者是函数;如果使用分组的话,再需要过滤(条件),这时一般不使用where而是使用having关键字;where 条件后面不可以跟聚合函数;having 后面是可以跟着聚合函数的。
⑥ 过滤重复的数据 distinct
select distincename,age from newtable;
6) 表设计
外键约束
① 创建表时添加外键约束
foreign key (id) reference oldtable(id),
② 修改原表中的列为外键约束
alter table newtable add foreign key(id) references oldtable(id);
7) 多表查询
① 直接多张表一起查询,得到的是一组笛卡尔积
select * from newtable,oldtable;
② 内连接查询。在多表笛卡尔积的基础上,按照条件查询。
语法一:select a,b from newtable,oldtable wherenewtable.id=oldtable.id;
语法二:select a,b, from newtable inner join oldtableon newtable.id=oldtable.id;
③ 外连接查询。
a. 左外连接
用左表的数据去连接右表数据去查询,不管在右表中是否得到记录,左表中的数据全部显示。如果没有记录,则用null来填充
select * from newtable left outer joinoldtable on newtable.name=oldtable.name;
outer可以省略。
select * from newtable outer joinoldtable on newtable.name=oldtable.name;
b. 右外连接
用右表的数据去连接左表数据去查询,不管在左表中是否得到记录,右表中的数据全部显示。如果没有记录,则用null来填充
select * from newtable right outerjoin oldtable on newtable.name=oldtable.name;
outer可以省略。
select * from newtable outer joinoldtable on newtable.name=oldtable.name;
c. 全外连接
select * from 表1 full outer join 表2 on 条件 但是mysql不支持这个语法。在mysql中使用union将左外和右外连接到一起实现全连接,但是如果使用union 自动去除重复数据
select * from newtable left outer joinoldtable on newtable.name=oldtable.name union select * from newtable rightouter join oldtable on newtable.name=oldtable.name;
④ 关联子查询
把一个sql的查询结果做为另一个sql的查询条件(参数)。
select * from newtable where id in(
select id from oldtable where age=(
select max(age) from oldtable
)
);
8) 其他
① in
age in(23,24) age=2 or age=3;
select * from newtable where agein(select id from newtable where age>10);
② exists
表示存在,当子查询的结果存在,就会显示主查询中的所有数据。
select* from student s where exists (select * from studentcourse sc wheres.`id`=sc.student_id and score<60);
③ any some
any和some是一样;any 或者some的用法 >any(1,2,3) 等价于>1 or >2 or>32 数据库操作联系
④ all
>all(1,2,3)等价于 >1 and >2 and >3
select* from student where id in(
selectstudent_id from studentcourse where score >=all(
selectscore from studentcourse
)
);
7 数据库操作练习
准备工作:
-- 部门表
create table dept(
deptno int primary key auto_increment, --部门编号
dname varchar(14) , --部门名字
loc varchar(13) -- 地址
) ;
-- 员工表
create table emp(
empno int primary key auto_increment,-- 员工编号
ename varchar(10), -- 员工姓名 -
job varchar(9), -- 岗位
mgr int, -- 直接领导编号
hiredate date, -- 雇佣日期,入职日期
sal int, -- 薪水
comm int, -- 提成
deptno int not null, -- 部门编号
foreign key (deptno) referencesdept(deptno)
);
insert into deptvalues(10,'财务部','北京');
insert into deptvalues(20,'研发部','上海');
insert into deptvalues(30,'销售部','广州');
insert into deptvalues(40,'行政部','深圳');
insert into empvalues(7369,'刘一','职员',7902,'1980-12-17',800,null,20);
insert into empvalues(7499,'陈二','推销员',7698,'1981-02-20',1600,300,30);
insert into empvalues(7521,'张三','推销员',7698,'1981-02-22',1250,500,30);
insert into empvalues(7566,'李四','经理',7839,'1981-04-02',2975,null,20);
insert into empvalues(7654,'王五','推销员',7698,'1981-09-28',1250,1400,30);
insert into empvalues(7698,'赵六','经理',7839,'1981-05-01',2850,null,30);
insert into empvalues(7782,'孙七','经理',7839,'1981-06-09',2450,null,10);
insert into empvalues(7788,'周八','分析师',7566,'1987-06-13',3000,null,20);
insert into empvalues(7839,'吴九','总裁',null,'1981-11-17',5000,null,10);
insert into empvalues(7844,'郑十','推销员',7698,'1981-09-08',1500,0,30);
insert into empvalues(7876,'郭靖','职员',7788,'1987-06-13',1100,null,20);
insert into empvalues(7900,'令狐冲','职员',7698,'1981-12-03',950,null,30);
insert into empvalues(7902,'张无忌','分析师',7566,'1981-12-03',3000,null,20);
insert into empvalues(7934,'杨过','职员',7782,'1983-01-23',1300,null,10);
-----------------------------------------------------------------------------------------
根据以上员工表练习
-- 1.列出至少有一个员工的所有部门。
selectdeptno,count(*) from emp group by deptno having count(*) >= 1;
select *from dept where deptno in(
select distinct deptno from empwhere empno is not null
);
selectd.deptno,d.dname,t.renshu from dept d inner join
(selectdeptno,count(deptno) renshu from emp group by deptno havingcount(deptno)>=1) t
ond.deptno=t.deptno;
-- 2.列出薪金比"刘一"多的所有员工。
select *from emp where sal>(
select sal from emp where ename='刘一'
);
-- 3.***** 列出所有员工的姓名及其直接上级的姓名。
selectt1.ename 员工姓名, t2.ename直接上级 from empt1,emp t2 where t1.mgr = t2.empno;
selectempt.ename 员工,mgrt.ename上级 from(select ename,mgr from emp) empt inner join
(select ename,empno from emp) mgrt onempt.mgr=mgrt.empno
;
selectename 员工,tt.jingli经理 from empee inner join
(selectt.mgr jinglihao,ename jingli from emp e inner join
(selectmgr from emp group by mgr) t
one.empno=t.mgr) tt
onee.mgr=tt.jinglihao
;
-- 4.列出受雇日期早于其直接上级的所有员工。
selectt1.*,t2.hiredate from emp t1,emp t2 where t1.mgr = t2.empno and t1.hiredate< t2.hiredate;
selectempt.`ename` 员工 from empempt
inner join
emp mgrt
on empt.`mgr`=mgrt.`empno` andempt.`hiredate`<mgrt.`hiredate`;
-- 5.列出部门名称和这些部门的员工信息,同时列出那些没有员工的部门。
select *from dept left join emp on dept.`deptno`=emp.`deptno`;
-- 6.列出所有job为“职员”的姓名及其部门名称。
select enamefrom emp empt inner join dept on empt.`deptno`=dept.`deptno` and empt.`job`='职员';
selectd.dname 部门,t.ename 职员 from dept d inner join
(selectename,deptno from emp where job='职员') t
ond.deptno=t.deptno
;
-- 7.列出最低薪金大于1500的各种工作。
selectmin(sal),job from emp group by job having min(sal)>1500;
-- 8.列出在部门 "销售部" 工作的员工的姓名,假定不知道销售部的部门编号。
selectename from emp where deptno=(
select deptno from dept wheredname='销售部'
);
selectemp.ename from emp,dept where emp.deptno = dept.deptno and dept.dname = '销售部';
-- 9.列出薪金高于公司平均薪金的所有员工。
selectename from emp where sal>(
select avg(sal) from emp
);
-- 10.列出与"周八"从事相同工作的所有员工。
selectename from emp where ename<>'周八' and job=(
select job from emp where ename='周八'
);
-- 11.列出薪金等于部门30中员工的薪金的所有员工的姓名和薪金。
selectename sal from emp where sal in (
select sal from emp wheredeptno=30
);
-- 12.列出薪金高于在部门30工作的所有员工的薪金的员工姓名和薪金。
selectename sal from emp where sal>all(
select sal from emp wheredeptno=30
);
select *from emp where sal > (
select max(sal) from emp where deptno = 30
);
-- 13.列出在每个部门工作的员工数量、平均工资。
selectcount(*) 员工数量,avg(sal) 平均工资,deptno from emp group by deptno;
select t.dname 部门,count(empno),avg(sal) from emp e inner join
(selectdname,deptno from dept) t
one.deptno=t.deptno
group bye.deptno
;
-- 14.列出所有员工的姓名、部门名称和工资。
selectename,sal,deptt.`dname` from emp empt inner join dept deptt whereempt.`deptno`=deptt.`deptno` order by empt.`sal` desc;
selectemp.ename,dept.dname,emp.sal from emp,dept where emp.deptno = dept.deptno;
-- 15.列出所有部门的详细信息和部门人数。
selectdeptt.*,empt.renshu from dept deptt left join (
select count(*) renshu,deptno fromemp group by deptno
) empt ondeptt.`deptno`=empt.`deptno`;
selectd.*,t.renshu 部门人数 from deptd inner join
(selectcount(sal) renshu,deptno from emp group by deptno) t
ond.deptno=t.deptno;
-- 16.列出各种工作的最低工资。
selectmin(sal),job from emp group by job;
-- 17.列出各个部门的 经理 的最低薪金。
selectmin(sal),deptno from(
select * from emp where job='经理'
) empt group by deptno;
selectd.dname,min(sal) 经理最低薪金from emp e inner join
(selectdname,deptno from dept) d
ond.deptno=e.deptno
wheree.job='经理'
group bye.deptno;
-- 18.列出所有员工的年工资,按年薪从低到高排序。
selectename,12*sal+ifnull(comm,0) sals from emp order by sals asc;
-- 19.查出emp表中薪水在3000以上(包括3000)的所有员工的员工号、姓名、薪水。
selectempno,ename,sal from emp where sal>=3000;
-- 20.查询出所有薪水在'陈二'之上的所有人员信息。
select *from emp where sal>(
select sal from emp where ename='陈二'
);
-- 21.查询出emp表中部门编号为20,薪水在2000以上(不包括2000)的所有员工,显示他们的员工号,姓名以及薪水,以如下列名显示:员工编号 员工名字 薪水
selectempno 员工编号,ename 员工姓名,sal 薪水 from emp where deptno=20 and sal>2000;
-- 22.查询出emp表中所有的工作种类(无重复)
selectdistinct job from emp;
-- 23.查询出所有奖金(comm)字段不为空的人员的所有信息。
select *from emp where comm is not null;
-- 24.查询出薪水在800到2500之间(闭区间)所有员工的信息。(注:使用两种方式实现and以及between and)
select *from emp where sal>=800 and sal<=2500;
select *from emp where sal between 800 and 2500;
-- 25.查询出员工号为7521,7900,7782的所有员工的信息。(注:使用两种方式实现,or以及in)
select *from emp where empno=7521 or empno=7900 or empno=7782;
select *from emp where empno in(7521,7900,7782);
-- 26.查询出名字中有“张”字符,并且薪水在1000以上(不包括1000)的所有员工信息。
select *from emp where ename like '%张%'and sal>1000;
-- 27.查询出名字第三个汉字是“忌”的所有员工信息。
select *from emp where ename like '__忌';
-- 28.将所有员工按薪水升序排序,薪水相同的按照入职时间降序排序。
select *from emp order by sal asc,hiredate desc;
-- 29.将所有员工按照名字首字母升序排序,首字母相同的按照薪水降序排序。 order byconvert(name using gbk) asc;
select *from emp order by convert(ename using gbk)asc,sal desc;
-- 30.查询出最早工作的那个人的名字、入职时间和薪水。
selectename,hiredate,sal from emp where hiredate = (select min(hiredate) from emp);
select ename,hiredate,sal from emp where hiredate <= all(select hiredatefrom emp);
-- 31.显示所有员工的名字、薪水、奖金,如果没有奖金,暂时显示100.
selectename,sal,ifnull(comm,100) from emp;
-- 32.显示出薪水最高人的职位。
select jobfrom emp where sal>=all(
select sal from emp
);
select jobfrom emp where sal = (
selectmax(sal) from emp
);
-- 33.查出emp表中所有部门的最高薪水和最低薪水,部门编号为10的部门不显示。
selectmin(sal),max(sal) from emp where deptno !=10 group by deptno;
selectmin(sal),max(sal) from emp where deptno <>10 group by deptno;
selectt.dname 部门,max(sal) 最高薪水,min(sal) 最低薪水 from emp e inner join
(select dname,deptnofrom dept) t
one.deptno=t.deptno
wheree.deptno<>10
group bye.deptno
;
-- 34.删除10号部门薪水最高的员工。
deletefrom emp where empno=(
select empno from emp wheresal>=all(
select sal from emp wheredeptno=10
) and deptno=10
);
上面是1093错误代码。
deletefrom emp where empno=(
select c.e from (
select empno e from emp emptwhere sal>=all(
select sal from empwhere deptno=10
)
) c
);
//mysql不支持,在一条语句对同一个表,先查询再更新的操作。
//可以利用临时表套嵌实际的表,取表别名,解决这个问题。oracle没有这个问题。
insertinto emp values(7840,'吴九','总裁',null,'1981-11-17',5000,null,10);
或者
deletefrom emp where empno=(select c.d from
(selectempno d from emp where sal in
(selectb.a from(select max(sal) a from emp where deptno=10)
b)
anddeptno=10)
c);
deletefrom emp where empno=(select empno from emp where sal
in(selectmax(sal) b from emp where deptno=10)
anddeptno=10);--这是错误的代码。
或者
deletefrom emp where deptno=10 and sal >= all(
selectt.sal from (
select salfrom emp where deptno=10
)
t );
-- 35.将薪水最高的员工的薪水降30%。
update empset sal=sal*0.7 where sal=(
select c.e from (
select max(sal) e from emp
) c
);
与上题同样,如果不做套嵌查询表,会出现1093报错。
-- 36.查询员工姓名,工资和 工资级别(工资>=3000 为3级,工资>2000 为2级,工资<=2000 为1级)
selectename,sal, case when sal>=3000 then '3级' when sal>2000 then '2级' else '1级' end 级别 from emp;
- Mysql
- MySql
- MYSQL
- MySQL
- mysql
- mysql
- mysql
- mysql
- Mysql
- Mysql
- mysql
- MySQL
- mysql
- Mysql
- mysql
- mysql
- mysql
- mySQL
- HTML/CSS专项(错题)
- 大数据架构师从入门到精通 学习必看宝典
- 排序 (插入排序,快速排序,希尔排序)数据结构与算法分析-C语言描述
- Charles抓包软件简介
- php static
- mysql
- oracle实用知识(五)
- http://dl-ssl.google.com/android上不去解决方案
- LCS+路径还原
- bzoj 5241. 【GDOI2018模拟8.8】苹果和雪梨 贪心
- 安卓实训笔记第二天
- 七、基础教程-坐标轴(Axis)
- Js中JSON对象
- quartus || 怎样调用PLL 核