Mysql笔记

创建数据库:create database 数据库名 default character set 字符编码 collate 字符编码校验规则

create database demo default character set utf8 collate utf8_general_ci;

使用Navicat导入三张表

DROP TABLE IF EXISTS EMP;
DROP TABLE IF EXISTS DEPT;
DROP TABLE IF EXISTS SALGRADE;

CREATE TABLE DEPT
       (DEPTNO int(2) not null ,
    DNAME VARCHAR(14) ,
    LOC VARCHAR(13),
    primary key (DEPTNO)
    );
CREATE TABLE EMP
       (EMPNO int(4)  not null ,
    ENAME VARCHAR(10),
    JOB VARCHAR(9),
    MGR INT(4),
    HIREDATE DATE  DEFAULT NULL,
    SAL DOUBLE(7,2),
    COMM DOUBLE(7,2),
    primary key (EMPNO),
    DEPTNO INT(2) 
    )
    ;

CREATE TABLE SALGRADE
      ( GRADE INT,
    LOSAL INT,
    HISAL INT );




INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
10, 'ACCOUNTING', 'NEW YORK'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
20, 'RESEARCH', 'DALLAS'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
30, 'SALES', 'CHICAGO'); 
INSERT INTO DEPT ( DEPTNO, DNAME, LOC ) VALUES ( 
40, 'OPERATIONS', 'BOSTON'); 
commit;
 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7369, 'SMITH', 'CLERK', 7902,  '1980-12-17'
, 800, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7499, 'ALLEN', 'SALESMAN', 7698,  '1981-02-20'
, 1600, 300, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7521, 'WARD', 'SALESMAN', 7698,  '1981-02-22'
, 1250, 500, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7566, 'JONES', 'MANAGER', 7839,  '1981-04-02'
, 2975, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7654, 'MARTIN', 'SALESMAN', 7698,  '1981-09-28'
, 1250, 1400, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7698, 'BLAKE', 'MANAGER', 7839,  '1981-05-01'
, 2850, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7782, 'CLARK', 'MANAGER', 7839,  '1981-06-09'
, 2450, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7788, 'SCOTT', 'ANALYST', 7566,  '1987-04-19'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7839, 'KING', 'PRESIDENT', NULL,  '1981-11-17'
, 5000, NULL, 10); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7844, 'TURNER', 'SALESMAN', 7698,  '1981-09-08'
, 1500, 0, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7876, 'ADAMS', 'CLERK', 7788,  '1987-05-23'
, 1100, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7900, 'JAMES', 'CLERK', 7698,  '1981-12-03'
, 950, NULL, 30); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7902, 'FORD', 'ANALYST', 7566,  '1981-12-03'
, 3000, NULL, 20); 
INSERT INTO EMP ( EMPNO, ENAME, JOB, MGR, HIREDATE, SAL, COMM,
DEPTNO ) VALUES ( 
7934, 'MILLER', 'CLERK', 7782,  '1982-01-23'
, 1300, NULL, 10); 
commit;
 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
1, 700, 1200); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
2, 1201, 1400); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
3, 1401, 2000); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
4, 2001, 3000); 
INSERT INTO SALGRADE ( GRADE, LOSAL, HISAL ) VALUES ( 
5, 3001, 9999); 
commit;
View Code

 

一、表的查询

查看当前存在的所有数据库:show databases

修改数据库的字符编码:alter database 数据库名 default character set 修改的字符编码

alter database demo default character set gbk;

查看某表中的全部数据:select * from 表名

select * from demo;

不看表数据只查看表结构:desc 表名

DESC his_role;

简单查询:select 字段名 from 表名

查询部门名字?

select dname from dept;

查询多个字段:select 字段名1 ,字段名2 from 表名

select id , drug_type from his_drug;

删除表:drop table 表名

drop table demo;

给查询的列显示别名:select 列明 as 别名 from 表名(as可以用空格代替)

select id as ffff from his_drug;

注:字段可以使用数学表达式

select ename,sal * 12 from emp

条件查询:

查询薪资等于800的员工姓名和编号
select empno , ename from emp where sal = 800;

查询薪资大于800的员工姓名和编号
select empno , ename from emp where sal > 800;

查询薪资在800到1000之间的员工姓名和编号
select empno ,ename from emp where sal >= 800 and sal <= 1000;
或
select empno , ename from emp where between 800 and 1000;

查询空值时需要使用is,
例如查询工资为空的员工姓名和编号
select empno , ename from emp where sal is null;
 
查询工资不为空的员工姓名和编号
select empno , ename from emp where sal is not null;

查询工作岗位是MANAGER和SALESMAN的员工
select empno,ename,job frome emp where job = 'MANAGER' or jbo = 'SALESMAN';

in表示包含 相当于多个or (in不适一个区间 in后面跟的是具体的值)
查询工作岗位是MANAGER和SALESMAN的员工
select empno,ename,job from emp where job in ('manager' , 'salesman');

not in表示除了这几个值以外的数据
查询工作岗位除了MANAGER和SALESMAN的员工
select empno,ename,job from emp where job not in ('manager' , 'salesman');

 模糊查询

like用做模糊查询 支持%和下划线匹配
% 匹配任意多个字符
_ 匹配任意一个字符

例子:找出名字中含有o字母的
select ename from emp where ename like '%o%';

查询结果排序:order by 默认是升序

查询所有员工薪资,并排序(默认是升序)
select ename , sal from order by sal;

降序:desc(升序是asc,不写也行)
select ename , sal from order by sal desc;

多个字段排序。sal在前起主导 只有当sal相等时 才会启用ename排序
查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,按照名字升序排列
select ename , sal from emp order by sal asc , ename asc;

数据处理函数,单行处理函数

特点:一个输入对应一个输出

lower 转换小写
select lower(ename) from emp;

upper 转换大写
select upper(ename) from emp;

substr 取子字符串(起始下标从1开始)
select substr(ename, 1,3) from emp;
例子:找出名字第一个字母为A的员工
select ename from emp where substr(ename,1,1)='A';

concat 字符串拼接
select concat (empno,ename) from emp;

length 取长度
select length(ename) from emp;

trim 去空格
select * from emp where name = trim('    KING');

round 四舍五入
select round(123.412) from emp;

rand()生成随机数
select rand() from emp;

ifnull空处理函数(ifnull(comm,0))
在所有数据库中 只要有null参与的数学运算 最终结果都是null
例子:计算每个员工的年薪
select ename , (sal + ifnull(comm,0)) * 12 as result from emp 

 数据处理函数,分组函数,多行处理函数(输入多行 输出一行)

注意:分组函数自动忽略null,不需要提前对null进行处理

分组函数不能直接使用在where子句中

count 计数
例子:计算员工数量
select count(ename) from emp;
分组函数中count(*)和count(具体字段)有什么区别:
count(具体字段):表示统计该字段下所有部位NULL的元素总数
count(*):统计表中的总行数(只有有一行数据count则++)
sum 求和
例子:计算工资和
select sum(sal) from emp;
avg 平均值
例子计算平均工资
select avg(sal) from emp;
max 最大值
例子:找出最高工资
select ename , max(sal) from emp ;

min 最小值
例子 找出最低工资
select ename , min(sal) from emp ;

分组查询:在实际应用中 可能需要先进行分组 然后再对每一组数据进行操作 这个时候需要用到分组查询

关键字的执行顺序:select...from...where...group by...order by...
1.from 2.where 3.group by 4.select 5.order by
groub by 分组查询
例子:找出每个工作岗位的工资和?
select job , sum(sal) from emp group by job;

找出每个部门,不同工作岗位的最高薪资
select deptno , job , max(sal) from emp group by DEPTNO,job;

having可以对分完组之后的数据进行进一步过滤:having不能单独使用 必须和group by 联合使用
例子:找出每个部门的最高薪资,要求显示大于3000的?
select deptno , max(sal) from emp group by deptno having max(sal)>3000
where和having都可以使用时 优先选择where 优化后:
select deptno , max(sal) from emp where sal > 3000 group by deptno;

 distinct查询结果去重

1.查询有哪些工作岗位
select
distinct job from emp;
2.统计工作岗位数量
select count(distinct job) from emp;

distinct出现在两个字段之前表示两个字段联合起来去重

 

连接查询

当两张表进行连接查询 没有任何条件限制的时候 最终查询结果条数 是两张表条数的乘积。

sql92:缺点 结构不清晰
查询每个员工所在的部门名称?
select ename , dname from emp , dept where emp.deptno = dept.deptno;
性能优化:
select e.ename , d.dname from emp e , dept d where e.deptno = d.deptno;

sql99:join...on...优点:表连接条件是独立的
select e.ename , d.dname from emp e join dept d on e.DEPTNO = d.DEPTNO

内连接,等值连接:inner join ... on ...(inner可以省略 带着可读性好一些)

查询每个员工所在的部门名称,显示员工名和部门名?
select e.ename , d.dname from emp e inner join dept d on e.DEPTNO = d.DEPTNO

内连接,非等值连接:

找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
select ename , sal , grade from emp inner join salgrade on losal < sal and hisal > sal order by grade asc;
性能优化:
select e.ename , e.sal , s.grade from emp e inner join salgrade s on s.losal < e.sal and s.hisal > e.sal order by grade asc;

 内连接,自连接。技巧:一张表看做两张表

select a.ename as '员工', b.ename as'领导' from emp a join emp b on a.mgr = b.empno;

外连接,右外连接:right join 表示将join关键字右边的这张表看成主表,主要是为了这张表的数据全部查询出来,捎带着关联查询左边的表。在外连接中 两张表连接产生了主次关系。与之相同的还有左外连接:left join。

查询所有员工和部门,无人部门也要显示?
select e.ename , d.deptno from emp e right outer join dept d on e.deptno = d.deptno;
outer可以省略 带着可读性强

例子:查询每个员工的上级领导,要求显示所有员工的名字和领导名
select a.ename as '员工' , b.ename as '领导' from emp a left outer join emp b on a.mgr = b.empno;  

 多表连接:使用多个join on

找出每个员工的部门名称以及工资等级,要求显示员工名、部门名、薪资、薪资等级?
select e.ename ,e.sal , d.dname , s.grade from emp e inner join dept d on e.deptno = d.deptno inner join salgrade s on e.sal > s.losal and e.sal < s.hisal;

子查询:select语句中嵌套select语句,被嵌套的语句称为子查询。

例子:找出比最低工资高的员工姓名和工资?
第一步:查询最低工作
select min(sal) from emp;
第二步:找出>800的
select ename , sal from emp where sal > 800;
第三步:合并
select ename , sal from emp where sal > (select min(sal) from emp);

from子查询:from后面的子查询可以将子查询的查询结果当做一张临时表

例子:找出每个岗位的平均高工资的薪资等级?
第一步:查出每个岗位的平均工资
select job , avg(sal) from emp group by job;
把查询的结果视为临时表t
第二步:在当前查询的结果表t中找到工资等级
select t.* , s.grade from (select job , avg(sal) as avgsal from emp group by job ) t join salgrade s on t.avgsal between s. losal and s. hisal

 select子查询:select嵌套的子查询如果多余一条会报错

union合并查询结果集,使用union时要保证两个结果集列数相同。oracle要求列和列的数据类型也要相同

例子:查询工作岗位是MANAGER和SALESMAN的员工
使用or:
select ename , job from emp where job = 'manager' or job = 'salesman';
或,使用in
select ename , job from emp where job in ('manager', 'salesman');
使用union合并结果集
select ename , job from emp where job = 'manager'
union
select ename , job from emp where job = 'salesman';

性能:union的效率高一些 对于表连接来说 每连接一次新表 则匹配次数满足笛卡尔积 指数翻倍 但是union可以减少匹配次数。

a连接b连接c
a 10条记录
b 10条记录
c 10条记录
使用表连接,匹配次数为:10*10*10 = 1000次
使用union,匹配次数为10*10 + 10*10 = 200次

limit:将查询结果集的一部门取出来,通常在分页查询中使用。

例子:按照薪资降序,取出薪资最高的五名员工。
select ename , sal from emp order by sal desc limit 0,5;
0表示起始位置5表示长度
例子2:取出薪资排名在3到5的员工
select ename , sal from emp order by sal desc limit 2,3;
2表示从第三条记录开始 3表示长度

limit通用分页:每页显示pageSize条记录,第pageNo页:(pageNo - 1) * pageSize , pageSize

 

二、表的创建

建表的语法格式:

create table 表名(字段名1 数据类型 , 字段名2 数据类型,....);

mysql的数据类型:

varchar:可变长度字符串(根据实际的数据长度 动态分配空间) 优点:节省空间 缺点:需要动态分配空间,速度慢。
char:定长字符串(分配固定长度空间存储数据)   优点:不需要动态分配空间 速度快 缺点:使用不当可能会导致空间的浪费。
int:整型,等同于java中的int
bigint:长整型,等同于java中的long
float:单精度浮点型数据
double:双精度浮点型数据
date:短日期类型
datetime:长日期类型
clob:字符大对象 最多可以存储4G大字符串(超过255字符的都要采用字符大对象来存储)
blob:二进制大对象,专门用来存储 图片、声音、视频等流媒体数据。blob字段上插入数据时需要使用IO流
例子:创建一个学生表
create table student(no int,name varchar(32),sex char,age int,email varchar(100))

删除表:drop

删除学生表(如果不存在会报错):
drop table student;
如果学生表存在的话,删除(如果表不存在也不会报错):
drop table if exists student;

default:创建表时添加默认值

创建学生表且使性别默认值为m
create table student(no int,name varchar(32),sex char(1) default 'm', age int(3),email varchar(255));

insert into :向表中插入数据,insert into 表名(字段名1,字段名2,字段名3...) values (值1,值2,值3...);

insert into student(no,name,sex,age,email)values(1,'张三','',12,'22@qq.com')

注意:insert into 省略字段名需要把后面的值都写上。

format:格式化数字 format(数字,'格式')

select ename,format(sal,'$999,999') as sal from emp;

str_to_date:将字符串varchar类型转换成date类型。

格式:str_to_date('字符串日期','日期格式'),mysql的日期格式:

%Y:年 %m:月 %d:日 %h:时 %i:分 %s:秒

案例,插入学生生日
1.创建学生表
create table student1(name varchar(32) , age int , birth date);
2.插入学生张三
insert into student1(name,age,birth) value('张三',18,str_to_date('2000-01-02','%Y-%m-%d'))

注意:如果日期格式为:%Y-%m-%d格式则不需要使用str_to_date函数。

 

date_format:将data类型转换成具有一定格式的varchar字符串类型。

将日期类型转换为字符串并输出:
select age,name,date_format(birth,'%Y/%m/%d')as birth from student1

若不使用日期格式化 sql会进行默认的日期格式化,自动将数据库中的date类型转换成varchar类型,并且采用的格式是musql的默认日期格式:'%Y-%m-%d'

 

三、表的修改

语法格式:update 表名 set 字段名1=值1,字段名2=值2,...where 条件;

注意:没有条件限制会造成所有数据全部更新

update student1 set name = 'zhangsan' where name = '张三';

 

 四、删除数据

语法格式:delete from 表名where 条件;

注意:没有条件,整张表的数据会全部删除。

delete from student1 where name = 'zhangsan';

 

 五、其他

 1.insert语句可以一次插入多条数据

insert into student1(name,age,birth) value('zhangsan',12,'1999-01-02'),('lisi',12,'1999-01-02');

2.复制表

create table emp2 as select * from emp

原理:将一个查询结果当成一张新表创建 可以完成表的快速复制

3.truncate语句删除:删除效率高 物理删除 不支持回滚

truncate student1;

 

六、创建表约束

约束:在创建表时给表加上一些约束,以此来保证表中数据的完整性和有效性

1)非空约束:not null,约束的字段不能为null,not null只有列级约束 没有表级约束

例子:创建vip表,使id不能为空
create table vip(id int not null,name varchar(255),sex char(5));

 

2)唯一性约束:unique,约束的字段不能重复 但是可以为null

例子:创建VIP表使name具有唯一性。
drop table if exists vip;
create table vip(id int  not null , name varchar(255) unique , sex varchar(5));
例子2:创建VIP表使name和id联合起来具有唯一性
drop table if exists vip; create table vip(id int not null, name varchar(255) , sex varchar(5), unique(name,id));

注:在mysql中,如果一个字段同时被not null 和unique约束的话 该字段自动变成主键字段(oracle不存在这种方式)

 

3)主键约束:primary key,主键值是每一行记录的唯一标识。

任何一张表都应该有主键,没有主键的表是无效的。

主键的特征:unique、not null 不能为空,也不能重复

例子:创建vip表,使id为主键
drop table if exists vip;
create table vip(id int primary key, name varchar(255) , sex varchar(5), unique(name,id));

错误1:不能重复
insert into vip(id , name ,sex) values(1,'zhangsan2','') > 1062 - Duplicate entry '1' for key 'PRIMARY'.
错误2:不能为空
insert into vip(name) values('ss') > 1364 - Field 'id' doesn't have a default value.

也可以使用表级约束添加主键
create table vip(id int , name varchar(255) unique, sex char(5) , primary key(id));

复合主键
create table vip (id int , name varchar(255) , sex char(5) ,primary key (id,name));

自增主键
create table vip(id int primary key auto_increment , name varchar(255) , sex char(5));

 注意:一张表主键只能有一个,主键值建议使用 int bigint char等定长值

 

4)外键约束:foreign key

 若添加了外键约束 删除表时应先删除子表 再删除父表。

创建班级表
create table class(classno int primary key, classname varchar(255));
创建学生表
create table student(no int primary key auto_increment, name varchar(255) , cno int, foreign key(cno) references class(classno))

 外键不一定是主键 但是必须具有unique约束

 

检查约束:check(Oracle支持)

 

事务:

一个事务就是一个完整的业务逻辑。

只有DML语句才有事务,其他语句与事务无关(insert/delete/updata)。

 其实就是批量的DML语句同时成功或同时失败。

提交事务:commit;语句

回滚事务:rollback;语句(只能回滚到上一次的提交点)

 mysql默认情况下是自动提交事务的,每执行一条DML语句自动提交一次。

 mysql中关闭自动提交机制:start transaction;

 

事务的特性:

 原子性:事务是最小的工作单元,不可再分。

一致性:所有事务要求,要同一事务中,所有的操作必须同时成功或同时失败以保证数据的一致性

隔离性:两个事务间具有一定的隔离。

持久性:事务最终结束的保障,事务提交,就相当于将没有保存到硬盘上的数据保存到硬盘上。

 

事务隔离性的级别:

1.读未提交:read uncommitted(没有提交就能读到)

  最低的隔离级别,事务A可以读取到事务B未提交的数据。脏读现象。这种级别是理论上的,大多数数据库都是比这种级别高。

 

2.读已提交:read committed (提交之后才能读到)

  事务A只能读取到事务B提交之后的数据,这种隔离级别解决了脏读现象。不可重复读取数据。

  在事务开启后,第一次读到的数据时3条,当前事务还没有结束,可能第二次再读取的时候,读到的数据是4条。3不等于4称为不可重复读取。

  这种隔离级别是比较真实的数据,每一次读到的数据绝对真实,oracle默认的级别就是这个。

 

3.可重复读:repeatable read (提交之后也读不到,永远读取到的都是刚开启事务时的数据)

  事务A开启后,不管是多久,每一次在事务A中读取到的数据都是一致的。即使事务B将数据已经修改,并且提交了,事务A读取到的数据还是没有发生改变。

  缺点:每一次读到的数据都是幻想,不够真实。

  mysql的默认级别

 

4.序列化/串行化:serializable

  这是最高隔离级别,效率最低,解决了所有问题

  每一次读取到的数据都是最真实的,并且效率是最低的。

 

查看隔离级别:SEKECT @@tx_isolation;

设置隔离级别:set globle transaction isolation level 隔离级别名称;

 

索引

什么是索引:在数据库表的字段上添加,为了提高查询效率存在的一种机制。

一张表的一个字段可以添加一个索引,多个字段联合起来也可以添加索引。

索引可以简单理解为“排好序的快速查找数据结构“

 

posted @ 2019-11-05 09:46  剑器近丶  阅读(169)  评论(0编辑  收藏  举报