数据库登录:
mysql -uroot -p密码(直接输)输入密码是明文mysql -uroot -p 回车,然后出来“enter password” 再输密码是密文***数据库忘记密码怎么办?
方法1:用SET PASSWORD命令
首先登录MySQL
格式:mysql->set password for 用户名@localhost = password('新密码1');
例子:mysql>set password for root@localhost = password('1231');
方法2:用mysqladmin
格式:mysqladmin -u用户名 -p旧密码 password 新密码
例子:mysqladmin -uroot -p123456 password 123
方法3:用UPDATE直接编辑user表
首先登录MySQL。
1 | mysql> use mysql; |
方法4:在忘记root密码的时候,可以这样
以windows为例:
mysqld --skip-grant-tables 回车。–skip-grant-tables的意思是启动MysQL服务的时候跳过权限表认证。use mysql;update user set password = password("123")where user="root";(别忘了最后加分号)。flush privileges;如何卸载?
DB:
DBMS:
SQL:
表:table
表:table是数据库的基本组成单元,所有的数据都以表格的形式组织,目的是可读性强。
一个表包括行和列:
每一个字段应该包括哪些属性?
字段名、数据类型、相关的约束。
第一步:登录mysq1数据库管理系统
dos命令窗口:mysql -uroot -p333
第二步:查看有哪些数据库show databases;(这个不是SQL语句,属于MysQL的命令。)
1 | +-----------------------------------+ |
第三步:创建属于我们自己的数据库create database bjpowernode;(这个不是SQL语句,属于MysQL的命令。)
第四步:使用bjpowernode数据use bjpowernode;(这个不是SQL语句,属于MysQL的命令。)
第五步:查看当前使用的数据库中有哪些表?show tables;(这个不是SQL语句,属于MysQL的命令。)
第六步:初始化数据mysq1>source 文件拖过来
注意:数据初始化完成之后,有三张表:
1 | +-----------------------------—-+ |
当一个文件的扩展名是.sql,并且该文件中编写了大量的slq语句,我们称这样的文件为sql脚本。
注意:直接使用source命令可以执行sql脚本。
sq1脚本中的数据量太大的时候,无法打开,请使用source命令完成初始化。
drop database bipowernode;
desc 表名字;
drop table if exists <表名>; // 当这个表存在的话删除。
drop table <表名>; // 删除表
mysql> desc emp;
select database(); 查看当前使用的是哪个数据库
select version(); 查看mysql的版本号
\c 命令,结束一条语句
exit; 退出mySQL
show create table <表名称>;
建表语句的语法格式:
1 | create table 表名( |
关于MySQL当中字段的数据类型?以下只说常见的
char和varchar怎么选择?
建议:表名在数据库当中一般建议以:t_ 或者 tbl_ 开始
1 |
|
语法格式:
1 | insert into 表名(字段名1,字段名2,字段名3,....) values(值1,值2,值3,....) |
注意:
insert into <表名> (参数) value(值),(值)...表的复制和批量插入
将查询结果当做表创建出来。
1 | create table 表名 as select语句; |
将查询结果插入到一张表中
1 | insert into <目标表名> select * from <查询表名>; |
语法格式:
1 | update 表名 set 字段名1=值1,字段名2=值2... where 条件; |
更新所有记录
1 | update <表名> set 字段 = 值,字段 = 值, ... ; |
注意:没有条件整张表数据全部更新。
案例:将部门10的LOC修改为SHANGHAI,将部门名称修改为RENSHIBU
1 | update dept1 set loc = 'SHANGHAI', dname = 'RENSHIBU' where deptno = 10; |
delete删除之后还可以再回来,效率比较低,适合删小表
truncate删了之后回不来了,删之前必须多次确认,效率高,适合删大型表
语法格式:
1 | delete from 表名 where 条件; |
注意:没有条件全部删除。
删除10部门数据?
1 | delete from dept1 where deptno = 10; |
删除所有记录?
1 | delete from dept1; |
怎么删除大表?(重点)
1 | truncate table 表名; // 表被截断,不可回滚。 永久丢失。 |
对于表结构的修改,这里不讲了,大家使用工具完成即可,因为在实际开发中表一旦设计好之后,对表结构的修改是很少的,修改表结构就是对之前的设计进行了否定,即使需要修改表结构,我们也可以直接使用工具操作。修改表结构的语句不会出现在Java代码当中。
出现在java代码当中的sql包括:insert delete update select(这些都是表中的数据操作。)
增删改查有一个术语:CRUD操作
Create(增) Retrieve(检索) Update(修改) Delete(删除)
语法格式:
select 字段名1,字段名2,字段名3,....from 表名;
提示:
去重:在字段前面加上distinct 关键字
distinct关键字如果出现在所有字段的最前方,则去除所有记录联合起来的重复元素
查找所有工作:
1 | select distinct job from emp; |
统计岗位的数量
1 | select count(distinct job) from emp; |
查询员工的年薪?
1 | select ename,sal*12 from emp; |
说明: 字段可以参与数学运算
给查询结果的列重命名:
1 | select ename, sal*12 as yearsal from emp; |
如果用中文的话,应该用单引号括起来 select ename, sal*12 as '年薪' from emp;
(mysql支持双引号,但是最好别用,因为标准的sql语句是单引号的)
查询所有字段:select * from emp; 平时可以用,实际开发中不能用(效率低)!
语法格式:
1 | select 字段,字段... from 表名 where 条件; |
查询工资等于5000的员工姓名:
1 | select ename from emp where **sal = 5000**; |
查询史密斯的工资:
1 | select sal from emp where **ename = 'smith';** |
查询工资不等于3000员工:
1 | select ename,sal from emp where sal **<>** 3000; |
查询工资1000 - 3000之内的员工:
1 | select ename,sal from emp where sal **between** 1000 **and** 3000; |
select ename,sal from emp where ename between 'A' and 'B';左闭右开找出哪些人没有工资?
1 | select ename,sal from emp where sal is null; |
select ename,sal from emp where sal is not null;找出工作岗位是salesman或manager的员工:
1 | select ename,job from emp where job = 'manager' or job = 'salesman'; |
and和or联合起来用:找出薪资大于1000的并且部门编号是20或30部门的员工。
1 | select ename,sal from emp where sal > 3000 and (deptno = 20 or deptno = 30); |
in等同于or,查询工作岗位是manager和salesman 的员工:
1 | select ename,job from emp where job = 'salesman' or job = 'manager'; |
not in,不等于in中的值的,查询工资不是1000和5000的员工
1 | select ename,sal from emp where sal not in(1000,5000); |
找出名字中含有A的(掌握两个符号:%:表示任意多个字符 __:表示任意一个字符)
1 | select ename from emp where ename like '%A%'; |
找出名字第二个字母是A的:
1 | select ename from emp where ename like '_A%'; |
找出名字中有下划线的(转义字符):
1 | select ename from emp where ename like '%\ _%'; |
按照工资升序找出名字和薪资(order by):
1 | select ename,sal from emp order by sal; |
按照工资降序排列:
1 | select ename,sal from emp order by sal desc; |
按照工资降序,工资相同按照名字升序排列(多个字段排序,靠前的主导性大,前面相等才用到后面的)
1 | select ename,sal from emp order by sal desc, ename asc; |
按照第一列排序(不建议这样, 不健壮):
1 | select ename,sal from emp order by 1;(等于按照ename排序) |
找出工作岗位是salesman的员工并且按照工资降序排列
1 | select ename,sal,job from emp where job='salesman' order by sal desc; |
规定:在所有数据库中,只要表达式中有null,表达式的结果就一定是null
分组函数(对一组数据进行操作),有且仅有5个:
属于多行处理函数:输入多行,最终得到一个结果
单行处理函数:输入一行,输出一行
注意:分组函数自动忽略null,不用添加isnull函数
找出工资总和
1 | select sum(sal) from emp; |
找出总人数
1 | select count(*) from emp; |
计算每个员工的年薪(考虑到有null的情况)
1 | select ename,(sal+ifnull(comm,0))*12 as yearsal from emp; |
找出工资高于平均工资的员工
1 | select ename,sal from emp where sal > (select avg(sal) from emp); |
group by:按照某个字段或者某些字段进行分组
having : having是对分组之后的数据进行再次过滤。
案例:找出每个工作岗位的最高薪资。
1 | select max(sal)from emp group by job; |
注意:当一条sql语句中有group by 的话,select字段中只能有分组函数和分组字段。
select ename,job,max(sal) from emp group by job;这句话在Oracle中报错(因为语法比较严谨),但是在mysql中能执行,但是毫无意义!因为ename是随机选中的。
注意:
分组函数一般都会和group by联合使用,这也是为什么它被称为分组函数的原因。
并且任何一个分组函数(count sum avg maxmin)都是在group by语句执行结束之后才会执行的。
当一条sql语句没有group by的话,整张表的数据会自成一组。
找出每个岗位的平均工资
1 | select job,avg(sal) from emp group by job; |
找出每个部门不同工作岗位的最高薪资
1 | select deptno,job,max(sal) from emp group by job,deptno order by deptno; |
建议:能用where的用where,不能就用having
找出每个部门的最高薪资,要求显示薪资大于2900的数据
1 | select deptno,max(sal) from emp group by deptno having max(sal) > 2900; |
select deptno,max(sal) from emp where sal > 2900 group by deptno;找出每个部门的平均薪资,要求显示薪资大于2000的数据
1 | select deptno,avg(sal) from emp group by deptno having avg(sal) > 2000; |
一个完整的DQL语句:select…from…where…group by…having…order by…
什么是连接查询 ?
分类?
关于表的别名:
1 | select e.ename,d.dname from emp e,dept d; |
表的别名有什么好处?
注意:以后写sql语句的时候都要开始起别名了
笛卡尔积现象
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
1 | select ename,dname from emp,dept; |
笛卡尔积现象:当两张表进行连接查询的时候,没有任何条件进行限制,最终的查询结果条数是两张表记录条数的
乘积。
怎样避免?加上条件进行过滤。
避免了笛卡尔积现象,会减少记录的匹配次数吗? 不会,次数还是56次。只不过显示的是有效记录。
案例:找出每一个员工的部门名称,要求显示员工名和部门名。
1 | select e.ename,d.dname from emp e , dept d where e.deptno = d.deptno; |
最大特点是:条件是等量关系。
案例:查询每个员工的部门名称,要求显示员工名和部门名。
sql92版:select e.ename,d.dname from emp e , dept d where e.deptno = d.deptno;
我们主要用的是sql98版,因为98的更好
为什么98的更好?
1 | select |
或者:
1 | // inner可以省略的,带着inner目的是可读性好一些。 |
语法:
… A join B on 连接条件 where …
最大的特点是:连接条件中的关系是非等量关系。
案例:找出每个员工的工资等级,要求显示员工名、工资、工资等级。
1 | mysql> select e.ename,e.sal,s.grade |
自连接:最大的特点是:一张表看做两张表。自己连接自己。
案例:找出每个员工的上级领导,要求显示员工名和对应的领导名。
1 | 员工的领导编号 = 领导的员工编号 |
什么是外连接,和内连接有什么区别?
内连接:
假设A和B表进行连接,使用内连接的话,凡是A表和B表能够匹配上的记录查询出来,这就是内连接。AB两张表没有主副之分,两张表是平等的。
外连接:
内连接查询的时候,能匹配上的数据才能显示出来
假设A和B表进行连接,使用外连接的话,AB两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NULL与之匹配。
外连接的分类?
左连接有右连接的写法,右连接也会有对应的左连接的写法。
案例:找出每个员工的上级领导?(所有员工必须全部查询出来。)
1 |
|
案例:找出哪个部门没有员工?
1 |
|
三张表怎么连接查询?
语法:
1 | .... |
案例:找出每一个员工的部门名称以及工资等级。
1 |
|
案例:找出每一个员工的部门名称、工资等级、以及上级领导。
1 |
|
什么是子查询?
select语句当中嵌套select语句,被嵌套的select语句是子查询。
子查询可以出现在哪里?
1 | select |
案例:找出高于平均薪资的员工信息。
1 | select * from emp where sal > (select avg(sal) from emp); |
案例:找出每个部门平均薪水的等级。
1 |
|
案例:找出每个部门平均的薪水等级。
不是所有查询的都必须用子查询
1 |
|
案例:找出每个员工所在的部门名称,要求显示员工名和部门名。
1 |
|
union(可以将查询结果集相加)
前提:两张表的列数相等
案例:找出工作岗位是SALESMAN和MANAGER的员工?
第一种:select ename,job from emp where job = 'MANAGER' or job = 'SALESMAN';
第二种:select ename,job from emp where job in('MANAGER','SALESMAN');
第三种:union
只要确定了两张表的查询结果一定不重复,就用UNION ALL, 因为查询效率高
1 | select ename,job from emp where job = 'MANAGER' |
重点中的重点,以后分页查询全靠它了。
limit是mysql特有的,其他数据库中没有,不通用。(Oracle中有一个相同的机制,叫做rownum)
limit取结果集中的部分数据,这时它的作用。
语法机制:
limit startIndex, length
startIndex表示起始位置,从0开始,0表示第一条数据。
length表示取几个
案例:取出工资前5名的员工(思路:降序取前5个)
1 | select ename,sal from emp order by sal desc; |
取前5个:
1 | select ename,sal from emp order by sal desc limit 0, 5; |
limit是sql语句最后执行的一个环节:
1 |
|
案例:找出工资排名在第4到第9名的员工?
1 | select ename,sal from emp order by sal desc limit 3,6; |
通用的标准分页sql?
每页显示3条记录:
第1页:0, 3
第2页:3, 3
第3页:6, 3
每页显示pageSize条记录:
第pageNo页:(pageNo - 1) * pageSize, pageSize
pageSize是什么?是每页显示多少条记录
pageNo是什么?显示第几页
1 |
|
什么是约束?
常见的约束有哪些呢?
只有列级约束,没有表级约束
1 | drop table if exists t_user; |
案例:给某一列添加unique
1 | drop table if exists t_user; |
案例:给两个列或者多个列添加unique
1 | drop table if exists t_user; |
注意:not null约束只有列级约束,没有表级约束。
主键相关的术语?
主键约束 :primary key
主键字段 : id字段添加primary key之后,id叫做主键字段
主键值 :id字段中的每一个值都是主键值。
根据主键字段的字段数量来划分:
根据主键性质来划分:
一张表的主键约束只能有1个
给一张表添加主键约束
1 | drop table if exists t_user; |
使用表级约束方式定义主键
1 | drop table if exists t_user; |
mysql提供主键值自增(非常重要。)
1 | drop table if exists t_user; |
提示:Oracle当中也提供了一个自增机制,叫做:序列(sequence)对象。
关于外键约束的相关术语:
注意:
外键值可以为NULL?外键可以为null。
外键字段引用其他表的某个字段的时候,被引用的字段必须是主键吗?
1 | create table t_class( |
什么是事务? 一个事务是一个完整的业务逻辑单元,不可再分。
比如:银行账户,从A账户向B账户转账10000元,需要执行两条update语句。
update t_act set balance = balance - 10000 where actno = 'act-001';update t_act set balance = balance + 10000 where actno = 'act-002';
以上两条DML语句必须同时成功,或者同时失败,不允许出现一条成功,一条失败。
想要保证以上的两条DML语句同时成功或者同时失败,那么就要使用数据库的”事务机制”。
和事务相关的语句只有:DML语句。(insert delete update)
为什么?因为他们这三个语句都是和数据库表当中的”数据”相关的。
事务的存在是为了保证数据的完整性,安全性。
假设所有的业务都能使用1条DML语句搞定,还需要事务机制吗?不需要事务机制。
但实际情况不是这样的,通常一个”事儿(事务【业务】)”需要多条DML语句共同联合完成。
事务的特性?事务包括四大特性:ACID
事务隔离性存在隔离级别,理论上隔离级别包括4个:
Oracle数据库默认的隔离级别是:第二级别,读已提交。
mysql数据库默认的隔离级别是:第三级别,可重复读。
mysql事务默认情况下是自动提交的。(什么是自动提交?只要执行任意一条DML语句则提交一次。)
怎么关闭默认提交?start transaction;
演示两个事务,假如隔离级别:
set global transaction isolation level read uncommitted;set global transaction isolation level read committed;set global transaction isolation level repeatable read;mysql远程登录:mysql -h192.168.151.18 -uroot -p444
什么是索引? 索引就相当于一本书的目录,通过目录可以快速的找到对应的资源。
在数据库方面,查询一张表的时候有两种检索方式:
索引为什么可以提高检索效率呢? 最根本的原理是缩小了扫描的范围。
索引虽然可以提高检索效率,但是不能随意的添加索引,因为索引也是数据库当中的对象,也需要数据库不断的维护。是有维护成本的。
比如:表中的数据经常被修改,这样就不适合添加索引,因为数据一旦修改,索引需要重新排序,进行维护。
添加索引是给某一个字段,或者说某些字段添加索引。
select ename,sal from emp where ename = 'SMITH';
当ename字段没有添加索引的时候,以上sql语句会进行全表扫描,扫描ename字段中所有的值。
当ename字段添加索引的时候,以上sql语句会根据索引扫描,快速定位。
怎么创建索引对象?怎么删除索引对象?
什么时候考虑给字段添加索引?(满足什么条件)
注意:主键具有unique约束的字段会自动添加索引。根据主键查询效率较高,尽量根据主键检索。
查看sql语句的执行计划(只有MySQL才有):
explain select ename,sal from emp where sal = 5000;
给薪资sal字段添加索引:
create index empindex on emp(sal);
mysql> explain select ename,sal from emp where sal = 5000;
rows检索次数减少了
索引的实现原理?
索引底层采用的数据结构是:B + Tree
通过B Tree缩小扫描范围,底层索引进行了排序,分区,索引会携带数据在表中的”物理地址”,最终通过索引检索到数据之后,获取到关联的物理地址,通过物理索引检索到数据之后,获取到关联的物理地址,通过物理地址定位表中的数据,效率是最高的。
select ename from emp where ename = 'SMITH';
通过索引转换为:
select ename from emp where 物理地址 = 0x123;
索引的分类?
索引什么时候失效?
什么是视图?
视图的作用?
怎么创建视图? create view myview as select empno, ename from emp;
注意:只有DQL语句才能以试图对象的方式创建出来。查询的源表可以是已定义的视图。
创建视图的查询中通常不含ORDER BY和DISTINCT语句,这些语句可放在通过视图查询数据的语句中。
1 | create table emp_bak as select * from emp; |
对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据,不是直接操作的原表),但是只能对单源表的视图进行修改,不能对多源表的视图进行修改。
修改视图
1 | ALTER VIEW 视图名 [ ( 列名 [ ,...n ] ) ] |
删除视图
1 | drop view myview; |
什么是设计范式? 设计表的依据。按照这三个范式设计的表不会出现数据冗余。
三范式都是哪些?
第一范式:任何一张表都应该有主键,并且每一个字段原子性不可再分。
第二范式:建立在第一范式的基础上,所有非主键字段完全依赖主键,不能产生部份依赖。
多对多?三张表,关系表两个外键。
第三范式:建立在第二范式的基础上,所有非主键字段直接依赖主键,不能产生传递依赖。
一对多?两张表,多的表加外键。
提醒:在实际的开发中,以满足客户需求为主,有的时候会拿冗余换执行速度。
一对一怎么设计? 一对一设计有两种方案:主键共享/外键唯一
完整的建表语句
1 | CREATE TABLE `t_x` ( |
注意:在MySQL当中,凡是标识符使用飘号括起来的。最好别用,不通用。
建表的时候可以指定存储引擎,也可以指定字符集。
mysql默认使用的存储引擎是InnoDB方式。默认采用的字符集是UTF-8。(开始的时候我们自己设置的)
什么是存储引擎?
mysql支持很多存储引擎,每个存储引擎都对应了一种不同的存储方式。
每一个存储引擎都有自己的优缺点,需要在合适的时机选择合适的存储引擎。
查看当前mysql支持的存储引擎? show engines \G
mysql 5.5.36版本支持的光速引擎有9个
常见的存储引擎?
MyISAM
1 | Engine: MyISAM |
MyISAM这种存储引擎不支持事务。
MyISAM是mysql最常用的存储引擎,但是这种存储引擎不是默认的。
MyISAM采用三个文件组织一个表
优点:可被压缩,节省存储空间。并且可以转换为只读表,提高检索效率。
缺点: 不支持事务。
InnoDB
1 | Engine: InnoDB |
优点:支持事务、行级锁、外键等。这种存储引擎数据的安全得到保障。
表的结构存储在xxx.frm文件中
数据存储在tablespace这样的表空间中(逻辑概念),无法被压缩,无法转换成只读。
这种InnoDB存储引擎在MySQL数据库崩溃之后提供自动恢复机制。
InoDB支持级联删除和级联更新。
MEMORY
1 | Engine: MEMORY |
缺点:不支持事务。数据容易丢失。因为所有数据和索引都是存储在内存当中的。
优点:查询速度最快。
以前叫做HEPA引擎。
在数据库当中的数据导出
在windows的DOS命令窗口中执行: (导出整个库)
在windows的dos命令窗口中执行:(导出数据库中指定的表)
导入数据