参赛话题:学习笔记
个人主页:BoBooY的CSDN博客_Java领域博主 前言:本篇文章总结了 MySQL的入门知识点(上),希望通过 文字介绍 + 代码 + 图片的形式帮助大家快速掌握 MySQL入门知识点(下):https://blog.csdn.net/qq_58233406/article/details/127144532 MySQL经典练习题+解题思路:https://blog.csdn.net/qq_58233406/article/details/127150051
英文单词DataBase,简称DB。按照一定格式存储数据的一些文件的组合。
顾名思义:存储数据的仓库,实际上就是一堆文件。这些文件中存储了具有特定格式的数据。
DataBaseManagement,简称DBMS。
数据库管理系统是专门用来管理数据库中数据的,数据库管理系统可以对数据库当中的数据进行增删改查。
MySQL、Oracle、MS SqlServer、DB2、sybase等…
结构化查询语言
程序员需要学习SQL语句,程序员通过编写SQL语句,然后DBMS负责执行SQL语句,最终来完成数据库中数据的增删改查操作。SQL是一套标准,程序员主要学习的就是SQL语句,这个SQL在mysql中可以使用,同时在Oracle中也可以使用,在DB2中也可以使用。
DQL
数据查询语言(Data Query Language)
凡是带有select关键字的都是查询语句
select…
DML
数据操作语言(Data Manipulation Language)
凡是对表当中的数据进行增删改的都是DML
insert delete update
insert 增
delete 删
update 改
这个主要是操作表中的数据data。
DDL
数据定义语言 (Data Definition Language)
凡是带有create、drop、alter的都是DDL。
DDL主要操作的是表的结构。不是表中的数据。
create:新建,等同于增
drop:删除
alter:修改
这个增删改和DML不同,这个主要是对表结构进行操作。
TCL
是事务控制语言(Transaction Control Language)
包括:
事务提交:commit;
事务回滚:rollback;
DCL
是数据控制语言。
例如:授权grant、撤销权限revoke…
DBMS–执行–> SQL --操作–> DB
先安装数据库管理系统MySQL,然后学习SQL语句怎么写,编写SQL语句之后,DBMS对SQL语句进行执行,最终来完成数据库的数据管理。
exit;
show databases;
mysql默认自带了4个数据库:information_schema、mysql、performance_schema、sys
use mysql;
create database bjpowernode;
show tables;
select version();
select database();
source F:\JAVA\MySQL_document\bjpowernode.sql #注意:路径中不要有中文!!!!
xxxx.sql这种文件被称为sql脚本文件。
sql脚本文件中编写了大量的SQL语句。
我们执行SQL语句,可以使用sql脚本文件。
在mysql当中怎么执行sql脚本文件呢?
你在实际的工作中,第一天到了公司,项目经理会给你一个xxx.sql文件,你执行这个脚本文件,你电脑上的数据库数据就有了,你想使用记事本打开sql脚本文件很有可能打不开,因为太大了,记事本内存不够,所以要使用source命令初始化这个sql脚本文件,不要试图用记事本打开后复制代码再执行。
desc dept;
/c
mysql命令 执行命令的时候结尾必须加分号 “;” ,没遇到分号不执行。除了导入sql文件的source命令
另外SQL语句不区分大小写,都行。
select 后面可以跟某个表的字段名(可以等同看做变量名),也可以跟字面量/字面值(数据)。
select 1000 as num from dept;
select '1000' as num from dept;
select 字段名 from 表名;
select 和 from 都是关键字,字段名和表名都是标识符。
使用逗号隔开“,”
select deptno,dname from dept; #查询部门编号和部门名
可以把每个字段都写上
select a,b,c,d,e,f... from tablename;
可以使用*
select * from dept;
缺点:
在实际开发中不建议,可以自己玩没问题。 你可以在DOS命令窗口中想快速的看一看全表数据可以采用这种方式。
mysql> select deptno,dname as deptname from dept;
注意:只是将显示的查询结果列名显示为deptname,原表列名还是叫:dname
记住:select语句是永远都不会进行修改操作的。(因为只负责查询)
select deptno,dname deptname from dept;
select deptno,dname 'dept name' from dept; #加单引号
select deptno,dname "dept name" from dept; #加双引号
注意:在所有的数据库当中,字符串统一使用单引号括起来,单引号是标准
双引号在oracle数据库中用不了。但是在mysql中可以使用。
条件查询:不是将表中所有数据都查出来。是查询出来符合条件的。
select
字段1,字段2,字段3....
from
表名
where
条件;
(1)= 等于
例:查询薪资等于800的员工姓名和编号?
select ename,empno from emp where sal = 800;
例:查询SMITH的编号和薪资?
select empno,sal from emp where ename = 'SMITH'; #字符串使用单引号
(2)<> 或!= 不等于
例:查询薪资不等于800的员工姓名和编号?
select empno,ename from emp where sal != 800;
select empno,ename from emp where sal <> 800;
(3)< 小于
例:查询薪资小于2000的员工姓名、编号和薪资?
select empno,ename,sal from emp where sal < 2000;
(4)<= 小于等于
例:查询薪资小于等于3000的员工姓名、编号和薪资?
select empno,ename,sal from emp where sal <= 3000;
(5)> 大于
例:查询薪资大于3000的员工姓名、编号和薪资?
select empno,ename,sal from emp where sal > 3000;
(6)>= 大于等于
例:查询薪资大于等于3000的员工姓名和编号?
select empno,ename,sal from emp where sal >= 3000;
(7)between … and ….
两个值之间, 等同于 >= and <=
例:查询薪资在2450和3000之间的员工信息?包括2450和3000
select empno,ename,sal from emp where sal >= 2450 and sal <= 3000;
select
empno,ename,sal
from
emp
where
sal between 2450 and 3000;
注意:
(8)is null 和 is not null
例:查询哪些员工的津贴/补助为null?
select empno,ename,sal,comm from emp where comm is null;
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-Ls5YAwaX-1664697099999)(MySQL笔记.assets/image-20220406214157304.png)
例:查询哪些员工的津贴/补助不为null?
select empno,ename,sal,comm from emp where comm is not null;
注意:在数据库当中null不能使用等号进行衡量。需要使用is null因为数据库中的null代表什么也没有,它不是一个值,所以不能使用等号衡量。
(9)and 并且
例:找出工作岗位manager并且工资大于2500的员工信息?
select
empno,ename,sal
from
emp
where
job = 'manager' and sal > 2500;
(10)or 或者
例:查询工作岗位是manager和salesman的员工
select
empno,ename,sal
from
emp
where
job = 'manager' or job = 'salesman';
and 和 or 优先级
and和or同时出现,and优先级较高。如果想让or先执行,需要加“小括号”.以后在开发中,如果不确定优先级,就加小括号就行了。
(11)in 和 not in (包含与不包含)
相当于多个or(not in 不在这个范围中)
注意:in不是一个区间,in后面跟的是具体的值。
例:查询薪资是800和5000的员工信息?
select empno,ename,sal from emp where sal in (800,5000); #这个不是表示800到5000都找出来,而是两个值
(12)like
称为模糊查询,支持 % 或 下划线 匹配
例:找出名字中含有o的员工?
select ename from emp where ename like '%o%';
例:找出名字以T结尾的员工?
select ename from emp where ename like '%T';
例:找出名字以K开始的员工?
select ename from emp where ename like 'K%';
例:找出第二个字每是A的员工?
select ename from emp where ename like '_A%';
例:找出第三个字母是R的员工?
select ename from emp where ename like '__R%';
例:找出名字中有“_”的员工?
select ename from emp where ename like '%\_%'; # \ 转义字符
select
ename,sal
from
emp
order by
sal; # 默认是升序!!
指定降序: desc,指定升序: asc
例:查询员工名字和薪资,要求按照薪资升序,如果薪资一样的话,再按照名字升序排列。
select
ename,sal
from
emp
order by
sal asc, ename asc; # sal在前,起主导,只有sal相等的时候,才会考虑启用ename排序。
select ename,sal from emp order by 2; #2表示第二列,第二列是sal
不建议在开发中这么写,不建议在开发中这么写,因为不健壮。因为第二列可能会发生变化,列顺序改变之后,2就废了
例:找出工资在1250到3000之间的员工信息,要求按照薪资降序排列。
select
empno,ename,sal
from
emp
where
sal between 1250 and 3000
order by
sal desc;
关键字顺序不能变:
select
...
from
...
where
...
order by
... ;
以上语句的执行顺序必须掌握:
第一步:from
第二步:where
第三步:select
第四步:order by(排序总是在最后执行!)
数据处理函数又被称为单行处理函数,聚合函数
特点:一个输入对应一个输出。
lower 转换小写
select lower(ename) as ename from emp;
upper 转换大写
select upper(ename) as ename from emp;
substr 取子串
(substr(被截取的字符串, 起始下标,截取的长度))
select substr(ename, 1, 1) as ename from emp;
注意:起始下标从1开始,没有0
例:找出员工名字第一个字是A的员工信息?
select
empno, ename
from
emp
where
substr(ename,1,1) = 'A';
concat 拼接字符
例:将查询出来的员工的名字首字母大写?
select concat(upper(substr(ename,1,1)),lower(substr(ename,2,length(ename) - 1))) as result
from emp;
length 取长度
select length(ename) enamelength from emp;
trim 去空格
select * from emp where ename = trim(' KING');
round 四舍五入
select round(1236.567, 0) as result from emp; #保留整数位。
select round(1236.567, 1) as result from emp; #留1个小数
select round(1236.567, 2) as result from emp; #保留2个小数
select round(1236.567, -1) as result from emp; #保留到十位。
rand() 生成随机数
select round(rand()*100,0) from emp; # 100以内的随机数
ifnull 空处理函数
可以将 null 转换成一个具体值
在所有数据库当中,只要有NULL参与的数学运算,最终结果就是NULL。
注意:NULL只要参与运算,最终结果一定是NULL。
为了避免这个现象,需要使用ifnull函数。ifnull函数用法:ifnull(数据, 被当做哪个值)。如果“数据”为NULL的时候,把这个数据结构当做哪个值。
例:计算所有员工的年薪?
select ename, (sal + comm) as yearsal from emp; #与NULL参与运算的结果都是NULL
所以使用 ifnull函数 处理如下:
select ename,(sal + ifnull(comm,0)) as yearsal from emp; # 0为NULL时被指定的值
case…when…then…when…then…else…end
例:当员工的工作岗位是MANAGER的时候,工资上调10%,当工作岗位是SALESMAN的时候,工资上调50%,其它正常。 (注意:不修改数据库,只是将查询结果显示为工资上调)
select
ename,
job,
sal as oldsal,
(case job when 'MANAGER' then sal*1.1 when 'SALESMAN' then sal*1.5 else sal end) as newsal
from
emp;
str_to_date 将字符串转换成日期
将date类型转换成具有一定格式的varchar字符串类型。
drop table if exists t_user;
create table t_user(
id int,
name varchar(32),
birth date #生日也可以使用date日期类型
);
create table t_user(
id int,
name varchar(32),
birth char(10) #生日可以使用字符串,没问题
);
插入数据?
insert into t_user(id,name,birth) values(1, ‘zhangsan’, ‘01-10-1990’); #1990年10月1日
生日:1990-10-11 (10个字符)
出问题了:原因是类型不匹配。数据库birth是date类型,这里给了一个字符串varchar。
怎么办?可以使用str_to_date函数进行类型转换
语法格式:
str_to_date('字符串日期', '日期格式')
mysql的日期格式:
%Y 年
%m 月
%d 日
%h 时
%i 分
%s 秒
insert into t_user(id,name,birth) values(1, 'zhangsan', str_to_date('01-10-1990','%d-%m-%Y'));
insert into t_user(id,name,birth) values(2, 'lisi', '1990-10-01');
date_format
这个函数可以将日期类型转换成特定格式的字符串。
select id,name,date_format(birth, '%m/%d/%Y') as birth from t_user;
select id,name,birth from t_user;
以上的SQL语句实际上是进行了默认的日期格式化,
自动将数据库中的date类型转换成varchar类型。
并且采用的格式是mysql默认的日期格式:‘%Y-%m-%d’
format 设置千分位
select ename,format(sal, '$999,999') as sal from emp;
now 获取系统当前日期时间
create table t_date(create_time datetime);
insert into t_date(create_time) values(now());
select * from t_date;
timestampdiff 计算两个日期的时间差
TimeStampDiff(间隔类型, 前一个日期, 后一个日期)
间隔类型:
SECOND 秒,
MINUTE 分钟,
HOUR 小时,
DAY 天,
WEEK 星期
MONTH 月,
QUARTER 季度,
YEAR 年
多行处理函数的特点:输入多行,最终输出一行
例:找出最高工资?
select ename,max(sal) from emp;
例:找出最低工资?
select ename,min(sal) from emp;
例:计算工资的和?
select sum(sal) from emp;
例:计算平均工资?
select avg(sal) from emp;
例:计算员工的数量?
select count(ename) from emp;
分组函数在使用的时候必须先进行分组,然后才能使用,如果你没有对数据进行分组,整张表默认为一组
分组函数自动忽略NULL,你不需要提前对NULL处理
分组函数中count(*)和count(具体字段)有什么区别?
分组函数不能够直接使用在where子句中。
所有的分组函数可以组合起来一起用。
select sum(sal),min(sal),max(sal),avg(sal),count(*) from emp;
select
...
from
...
group by
...
计算每个部门的工资和?
计算每个工作岗位的平均薪资?
select
...
from
...
where
...
group by
...
order by
...
例:找出每个工作岗位的工资和?
实现思路:按照工作岗位分组,然后求和
select
job, sum(sal) as '工资总和'
from
emp
group by
job;
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-0DaXChB6-1664697100012)(MySQL笔记.assets/image-20220407203230338.png)
顺序:先从emp表中查询数据,将这个表分组,然后对每一组数据进行求和sum(sal)
例:找出每个工作岗位的最高工资?
实现思路:先查询emp表然后对工作岗位分组,然后查询最高工资
select
job,max(sal)
from
emp
group by
job;
例:找出每个部门,不同工作岗位的最高工资?
技巧:两个字段联合成1个字段看(两个字段联合分组)
select
job, deptno,max(sal)
from
emp
group by
deptno,job;
外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-2lx19QsG-1664697100012)(MySQL笔记.assets/image-20220407212711309.png)
使用having可以对分完组之后的数据进一步过滤。
having不能单独使用,having不能代替where,having必须和group by一起使用
例:找出每个部门最高薪资,要求显示最高薪资大于3000的?
第一步:找出每个部门最高薪资
select
deptno,max(sal)
from
emp
group by
deptno;
第二步:对结果进行筛选,显示最高薪资大于3000的
select
deptno,max(sal)
from
emp
group by
deptno
having
max(sal) > 3000;
思考:以上的sql语句执行效率是不是低?
比较低,实际上可以这样考虑:现将大于3000的都找出来,然后分组。
优化策略:where和having优先选择where,where完成不了的,再选择having
select
deptno,max(sal)
from
emp
where
sal > 3000
group by
deptno;
例:找出每个部门平均薪资,要求显示平均薪资高于2500的。
select
deptno,avg(sal)
from
emp
group by
deptno
having
avg(sal) > 2500;
综合案例:
找出每个岗位的平均薪资,要求显示平均薪资大于1500的,除了MANAGER岗位之外,要求按照平均薪资降序排列
select
job,avg(sal)
from
emp
where
job != 'MANAGER' #也可以写成:job <> 'MANAGER'
group by
job
having
avg(sal) > 1500
order by
avg(sal) desc;
把查询结果去除重复记录
注意:原表数据不会被修改,只是查询结果去重。
select distinct job from emp;
select distinct job,deptno from emp;
例:统计工作岗位的数量
select count(distinct job) from emp;
什么是连接查询?
emp表和dept表联合起来查询数据,从emp表中取出员工名字,从dept表中取部门名字。这种跨表查询,多张表联合起来查询数据,被称为连接查询
当两张表进行连接查询,**没有任何条件限制的时候,**最终查询结果条数,是两张表条数的成绩,这种现象被称为:笛卡尔积现象(笛卡尔发现的,这是一个数学现象)
select
ename,dname
from
emp,dept
where
emp.deptno = dept.deptno;
select
emp.ename,dept.dname #这里能增加查询的效率
from
emp ,dept
where
emp.deptno = dept.deptno;
select
e.ename,d.dname
from
emp e,dept d
where
e.deptno = d.deptno;
注意:通过笛卡尔积现象,标的连接次数越多效率越低,尽量避免表的连接次数
例:查询每个员工所在部门名称,显示员工名和部门名?
emp e和dept d表进行连接。条件是:e.deptno = d.deptno
select
e.ename,d.dname
from
emp e,dept d
where
e.deptno = d.deptno;
SQL92缺点:结构不清晰,表的连接条件,和后期进一步筛选的条件,都放到了where后面
select
e.ename,d.dname
from
emp e
inner join #此处inner是可以省略的
dept d
on
e.deptno = d.deptno;
SQL99优点:表连接的条件是独立的,连接之后,如果还需要进一步筛选,再往后继续添加where
select
...
from
表a
join
表b
on
a和b的连接条件
where
筛选条件
例:找出每个员工的薪资等级,要求显示员工名、薪资、薪资等级?
(员工表)
(工资等级表)
select
e.ename,e.sal,s.grade
from
emp e
join
salgrade s
on
e.sal between s.losal and s.hisal;
select
e.ename,e.sal,s.grade
from
emp e
inner join #此处inner是可以省略的
salgrade s
on
e.sal between s.losal and s.hisal;
一张表看成两张表
例:查询员工的上级领导,要求显示员工名和对应的领导名?
技巧:一张表看成两张表
emp a 员工表
emp b 领导表
select
a.ename as '员工名' ,b.ename as '领导名'
from
emp a
join
emp b
on
a.mgr = b.empno;
这里只有13记录,因为KING没有领导
内连接:(a和b两张表没有主次关系,平等的)
select
e.ename,d.dname
from
emp e
join
dept d
on
e.deptno = d.deptno; #内连接特点:完全能够匹配的上这个条件的数据查询出来
select
e.ename,d.dname
from
emp e
right outer join #outer可以省略 写上就是可读性强
dept d
on
e.deptno = d.deptno;
right 代表什么:表示将join关键字右边的这张表看成主表,主要是为了将这张表的数据全部查询出来,捎带着关联查询左边的表。
在外连接当中,两张表连接,产生了主次关系。
select
e.ename,d.dname
from
dept d
left outer join #outer可以省略,写上就是可读性强
emp e
on
e.deptno = d.deptno;
思考:外连接的查询结果条数一定是 >= 内连接的查询结果条数?
正确
例:查询每个员工的上级领导,要求显示所有员工的名字和领导名?
select
a.ename '员工名',b.ename '领导名'
from
emp a
left join
emp b
on
a.mgr = b.empno; #这行代码的意思是:员工表每个员工的领导编号 = 员工表的员工号(相当于是领导的员工编号)
#所以就可以把a表看作是员工表,b表看作是领导表
此处king的信息用外连接也查出来了,而使用内连接就差不出来
全连接就是连接的表全是主表
语法:
select
...
from
a
join
b
on
a和b连接的条件
right join
c
on
a和c的连接条件
left join
d
on
a和d的连接条件
...
例:找出每个员工的部门名称以及工资等级,要求显示员工名,部门名,薪资,薪资等级?
select
e.ename '员工名',d.dname '部门名',e.sal '薪资',s.grade '薪资等级'
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal;
案例升级:找出每个员工的部门名称以及工资等级,还有上级领导。
要求显示员工名、领导名、部门名、薪资、薪资等级?
select
e.ename '员工名',l.ename '领导名',d.dname '部门名',e.sal '薪资', s.grade '薪资等级'
from
emp e
join
dept d
on
e.deptno = d.deptno
join
salgrade s
on
e.sal between s.losal and s.hisal
left join
emp l
on
e.mgr = l.empno;
什么是子查询?
select语句中嵌套select语句,被嵌套的select语句称为子查询
子查询都可以出现在哪里?
select
..(select).
from
..(select).
where
..(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后面的子查询,可以将子查询的查询结果当做一张临时表。(技巧)
例:找出每个岗位的平均工资的薪资等级。
实现思路:
第一步:查询每个岗位的平均薪资?
select
job, avg(sal)
from
emp
group by
job;
第二步:将查询结果当做一张表进行查询,查询这个结果的薪资等级?
select
t.job,t.avgsal,s.grade '薪资等级'
from(
select
job, avg(sal) as avgsal #这里数据处理函数不取别名的话,程序会报错,说avg(sal)不存在!!!
from
emp
group by
job
) as t
join
salgrade s
on
t.avgsal between s.losal and s.hisal;
例:找出每个员工的部门名称,要求显示员工名,部门名?
select e.ename,(select d.dname from dept d where e.deptno = d.deptno) as dname from emp e;
注意:对于select后面的子查询来说,这个子查询只能一次返回一个结果,否则就会报错如下:
错误:ERROR 1242 (21000): Subquery returns more than 1 row
例:查询工作岗位是MANAGER和SALESMAN的员工?
select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
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使用的注意事项:
limit的作用
将查询结果集的一部分取出来。通常使用在分页查询当中。
百度默认:10条记录。
分页的作用是为了提高用户的体验,因为一次全部都查出来,用户体验差。可以一页一页翻页看。
limit的使用
**完整用法:**limit startIndex, length
startIndex是起始下标,length是长度。
**缺省用法:**limit 5 这是取前五
例:按照薪资降序,取出排名前五的的员工?
select
ename,sal
from
emp
order by
sal desc
limit 5; #取前五
select
ename,sal
from
emp
order by
sal desc
limit 0,5; #取前五
例:取出工资排名在3-5名的员工?
select
ename,sal
from
emp
order by
sal desc
limit
2,3; #[3-5]名 2是起始位置,3是长度
分页
每页显示3条记录
第1页:limit 0,3 0 1 2
第2页:limit 3,3 3 4 5
第3页:limit 6,3 6 7 8
第4页:limit 9,3 9 10 11
每页显示pageSize条记录
第pageNo页:limit (pageNo - 1) * pageSize , pageSize (公式)
public static void main(String[] args){
// 用户提交过来一个页码,以及每页显示的记录条数
int pageNo = 5; //第5页
int pageSize = 10; //每页显示10条
int startIndex = (pageNo - 1) * pageSize;
String sql = "select ...limit " + startIndex + ", " + pageSize;
}
select
...
from
...
where
...
group by
...
having
...
order by
...
limit
...
执行顺序:
DDL包括:create drop alter
create table 表名(字段名1 数据类型, 字段名2 数据类型, 字段名3 数据类型);
create table 表名(
字段名1 数据类型,
字段名2 数据类型,
字段名3 数据类型
);
表名:建议以t_ 或者 tbl_开始,可读性强。见名知意。
字段名:见名知意。
表名和字段名都属于标识符。
很多数据类型,我们只需要掌握一些常见的数据类型即可。
(1)varchar(最长255)
可变长度的字符串
比较智能,节省空间。
会根据实际的数据长度动态分配空间。
优点:节省空间
缺点:需要动态分配空间,速度慢。
(2)char(最长255)
定长字符串
不管实际的数据长度是多少。
分配固定长度的空间去存储数据。
使用不恰当的时候,可能会导致空间的浪费。
优点:不需要动态分配空间,速度快。
缺点:使用不当可能会导致空间的浪费。
(3)int(最长11)
数字中的整数型。等同于java的int。
(4)bigint
数字中的长整型。等同于java中的long。
(5)float
单精度浮点型数据
(6)double
双精度浮点型数据
(7)date
短日期类型
(8)datetime
长日期类型
字符大对象
最多可以存储4G的字符串。
比如:存储一篇文章,存储一个说明。
超过255个字符的都要采用CLOB字符大对象来存储。
Character Large OBject:CLOB
(10)blob
二进制大对象
Binary Large OBject
专门用来存储图片、声音、视频等流媒体数据。
往BLOB类型的字段上插入数据的时候,例如插入一个图片、视频等,
你需要使用IO流才行
学号、姓名、年龄、性别、邮箱地址
create table t_student(
no int,
name varchar(32),
sex char(1),
age int(3),
email varchar(255)
);
create table t_student(
no int,
name varchar(32),
sex char(1) default '男', #使用default设置默认值
age int(3),
email varchar(255)
);
原理:将一个查询结果当做一张表新建
这个可以完成表的快速复制
表创建出来,同时表中的数据也存在了
create table emp2 as select * from emp; #as可写可不写
drop table 表名;
当这张表不存在的话会报错!
所以将删表格式改为:
drop table if exists 表名;
第一:在实际的开发中,需求一旦确定后,表一旦设计好之后,很少的进行表结构的修改。因为开发进行中的时候,修改表结构,成本比较高。修改表的结构,对应的java代码就需要进行大量的修改。成本是比较高的。这个责任应该由设计人员来承担!
第二:由于修改表结构的操作很少,所以我们不需要掌握,如果有一天真的要修改表结构,你可以使用工具!
修改表结构的操作是不许需要写到java程序中的。实际上也不是java程序员的范畴
alter table goods2 rename to shop_db.goods2;
ALTER TABLE goods add tax int(10) AFTER price;
ALTER TABLE goods drop tax;
如果需要修改字段类型及名称, 你可以在ALTER命令中使用 MODIFY 或 CHANGE 子句 。
alter table goods modify c varchar(10);
使用 CHANGE 子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型
alter table goods change tax tax1 bigint
alter database 数据库名 character set utf8;
ALTER TABLE 表名 DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE 表名 CHANGE 列名 列名 VARCHAR( 100 ) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL;
非空约束:not null
唯一性约束: unique
主键约束: primary key (简称PK)
外键约束:foreign key(简称FK)
检查约束:check(mysql不支持,oracle支持)
非空约束not null约束的字段不能为NULL
当你插入数据的时候,如果你插入的数据的字段是非空的,你就必须要插入这个字段的数据,否则的就会报错。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) not null # not null只有列级约束,没有表级约束!
);
唯一性约束unique约束的字段不能重复,但是可以为NULL。
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255) unique,
email varchar(255)
);
insert into t_vip(id) values(1); # name字段虽然被unique约束了,但是可以为NULL
insert into t_vip(id) values(2);
新需求:name和email两个字段联合起来具有唯一性
以下这样的数据是符合我“新需求”的:
insert into t_vip(id,name,email) values(1,'zhangsan','zhangsan@123.com');
insert into t_vip(id,name,email) values(2,'zhangsan','zhangsan@sina.com');
insert into t_vip(id,name,email) values(2,'sada','zhangsan@sina.com');
如何做到联合唯一约束?
drop table if exists t_vip;
create table t_vip(
id int,
name varchar(255),
email varchar(255),
unique(name,email) # 约束没有添加在列的后面,这种约束被称为表级约束。
);
简称:PK
主键约束的相关术语?
主键约束:就是一种约束。
主键字段:该字段上添加了主键约束,这样的字段叫做:主键字段
主键值:主键字段中的每一个值都叫做:主键值。
什么是主键?有啥用?
主键值是每一行记录的唯一标识。
主键值是每一行记录的身份证号!!!
记住:任何一张表都应该有主键,没有主键,表无效!!
**主键的特征:not null + unique(**主键值不能是NULL,同时也不能重复!)
怎么给一张表添加主键约束呢?
drop table if exists t_vip;
# 1个字段做主键,叫做:单一主键
create table t_vip(
id int primary key, #列级约束
name varchar(255)
);
可以这样添加主键吗,使用表级约束?
drop table if exists t_vip;
create table t_vip(
id int primary key, #列级约束
name varchar(255),
primary key(id)
);
表级约束主要是给多个字段联合起来添加约束
drop table if exists t_vip;
// id和name联合起来做主键:复合主键!!!!
create table t_vip(
id int,
name varchar(255),
email varchar(255),
primary key(id,name)
);
在实际开发中不建议使用:复合主键。建议使用单一主键!
因为主键值存在的意义就是这行记录的身份证号,只要意义达到即可,单一主键可以做到。
复合主键比较复杂,不建议使用!!!
一张表只能添加一个主键
主键值建议使用:
int
bigint
char
等类型。
不建议使用:varchar来做主键。主键值一般都是数字,一般都是定长的!
主键除了:单一主键和复合主键之外,还可以这样进行分类:
自然主键:主键值是一个自然数,和业务没关系。
业务主键:主键值和业务紧密关联,例如拿银行卡账号做主键值。这就是业务主键!
在实际开发中使用业务主键多,还是使用自然主键多一些?
自然主键使用比较多,因为主键只要做到不重复就行,不需要有意义。
业务主键不好,因为主键一旦和业务挂钩,那么当业务发生变动的时候,
可能会影响到主键值,所以业务主键不建议使用。尽量使用自然主键。
在mysql当中,有一种机制,可以帮助我们自动维护一个主键值
drop table if exists t_vip;
create table t_vip(
id int primary key auto_increment, //auto_increment表示自增,从1开始,以1递增!
name varchar(255)
);
insert into 表名(字段名1,字段名2,字段名3...) values(值1,值2,值3);
注意:字段名和值要一 一对应。什么是一一对应?
数量要对应。数据类型要对应。
例:向学生表中插入数据
insert into t_student(no,name,sex,age,email) values(1,'啵啵鱼','男',20,'boboyu@qq.com');
下面这样也可以:(只要数据和字段名对应就可以)
insert into t_student(name,no,sex,age,email) values('酸菜鱼',2,'男',20,'suancaiyu@qq.com');
insert语句中的“字段名”可以省略吗?可以。
insert into t_student values(2); //错误的
注意:前面的字段名省略的话,等于都写上了!所以值也要都写上!
insert into t_student values(2, '啵啵鱼', '男', 20, 'boboyu@qq.com');
insert into t_student(no) values(1);
insert into t_student(name) values('烤鱼');
insert into t_user(id,name,birth) values
(1,'zs','1980-10-11'),
(2,'lisi','1981-10-11'),
(3,'wangwu','1982-10-11');
emp_bak插入前:
create table dept_bak as select * from dept; #as可写可不写
将查询结果插入到emp_bak中:
insert into dept_bak select * from dept; #这里不能写as
update 表名 set 字段名1=值1,字段名2=值2,字段名3=值3... where 条件;
例:t_user表修改前:
修改后:
update t_user set name = '酸菜鱼', birth = '2020-1-1' where id = 1;
update t_user set name = '啵啵鱼';
delete from 表名 where 条件;
删除前:
删除后:
delete from t_user where id = 2;
delete from t_user; #删除所有
表中数据被删除了,但是这个数据在硬盘上的真实存储空间不会被释放!
这种删除缺点是:删除效率比较低。
这种删除优点是:支持回滚,后悔了可以再恢复数据!!!
这种删除缺点:不支持回滚。
这种删除优点:快速。
用法:(这种操作属于DDL操作。)
truncate table dept_bak;
大表非常大,上亿条记录
删除的时候,使用delete,也许需要执行1个小时才能删除完!效率较低。
可以选择使用truncate删除表中的数据。只需要不到1秒钟的时间就删除结束。效率较高。
但是使用truncate之前,必须仔细询问客户是否真的要删除,并警告删除之后不可恢复!
扫码关注腾讯云开发者
领取腾讯云代金券
Copyright © 2013 - 2025 Tencent Cloud. All Rights Reserved. 腾讯云 版权所有
深圳市腾讯计算机系统有限公司 ICP备案/许可证号:粤B2-20090059 深公网安备号 44030502008569
腾讯云计算(北京)有限责任公司 京ICP证150476号 | 京ICP备11018762号 | 京公网安备号11010802020287
Copyright © 2013 - 2025 Tencent Cloud.
All Rights Reserved. 腾讯云 版权所有