登录mysql:
mysql -uroot -p
修改密码的常见方法:
set password命令:
登录mysql
set password for 用户名@localhost = password(‘新密码’);
例如:set password for root@localhost = password(‘123’);
用mysqladmin
mysqladmin -u用户名 -p旧密码 password 新密码
用Update直接编辑user表
use mysql;
update user set password=password(‘新密码’) where user=‘root’ and host=‘localhost’;
flush privileges;
忘记root密码的情况下修改密码:(以window为例)
mysqld --skip-grant-tables
,–skip-grant-tables代表启动Mysql服务的时候跳过权限表认证。mysql
use mysql;
update user set password=password(‘新密码’) where user=‘root’;
flush privileges;
表是数据库的基本组成单元,是一个结构化文件。其包括
select
的都是DQLinsert、delete、update
create、drop、alter
mysql -uroot -p密码
show datebases;
create database 数据库名字;
drop database 数据库名字;
use 数据库名字;
show tables;
source 文件路径;
mysqldump 数据库名;
musqldump 数据库名 表名;
desc 表名;
exit
查询一个字段:select 字段名 from 表名;
tips: 所有的sql语句都要以;
结尾。并且sql不区分大小写。
查询多个字段:
select 字段名1,字段名2... from 表名
;查询全部字段:
select * from 表名;
给字段起别名:
select 字段名 as 别名 from 表名;
select 字段名 别名 from 表名;
(以空格分隔其别名)字段进行简单运算:
select money*10 from wages;
对重复字段进行去重:使用distinct关键字
select dinstinct job from emp;
tips:
1、dinstinct只能放在所有字段的最前面。代表将select的字段看成一组再进行过滤。
2、可以跟分组函数一起使用。
tips:当参与运算的字段为NULL时,计算的结果始终为NULL。
补充:空处理函数
ifnull(可能为null的数据,被当做什么处理)
如:ifnull(ewage,0) 表示当ewage为null时结果变成0
格式:
select 字段,字段,字段...
from 表名
where 条件;
执行顺序:from–>where–>-select
比较操作符: | = , < , > , >= , <= , <>或!= |
---|---|
字符串比较: | LIKE , NOE LIKE |
逻辑操作符: | AND , OR , NOT |
值的域: | BETWEEN , NOT BETWEEN |
值的列表: | IN , NOT IN |
未知的值: | IS NULL , IS NOT NULL |
查询工资等于5000的员工名字:select ename from emp where ewage=5000;
查询工资在3000~5000的员工名字:
select ename from emp where ewage>=3000 and ewage<=5000;
select ename from emp where ewage between 3000 and 5000;
查找没有津贴的员工名字:
select ename from emp where comm is null;
找出工资大于1000且编号是20或30的员工:
select ename from emp where ewage>1000 and (eno=20 or eno=30);
tips:当运算符不确定时,加个小括号
找出岗位是MANAGE和SALESMAN的员工:
select ename from where job in ('MANAGE','SALESMAN');
模糊查找:like 、not like
%
:匹配任意多个字符_
:匹配单个字符select ename from emp where ename like ‘%O%’;
select ename from emp where ename like ‘_A%’;
_
是有特殊含义的,需要使用\
转义)
select ename from emp where ename like ‘%\_%’;
格式:
select 字段名
from 表名
[where 条件]
order by 要排序字段1,字段2,字段3... [asc|desc];
asc:表示升序排序。desc表示降序排序。如不指定则默认升序排序
**tips:**上面格式的执行顺序为:from --> where --> select --> order by
select * from emp order by ewage;
升序select * from emp order by ewage asc;
升序select * from emp order by ewage desc;
降序select * from emp where job='SALESMENT' order by ewage desc,ename asc;
分组函数又叫多行处理函数、聚合函数。
分组函数都是对某一组数据进行操作
count | 计算数据条数 |
---|---|
sum | 求和 |
avg | 求平均值 |
max | 求最大值 |
min | 求最小值 |
分组函数的特点:
使用:
select sum(ewage) from emp;
select max(ewage) from emp;
select count(*) from emp;
思考1:count(*)和count(某个字段)的区别:
count(*) 是统计记录总条数
count(某个字段) 是统计这个字段不为null的数据总数
思考2:
如果要找出工资大于平均工资的员工:可否使用下面这个语句
select ename from emp where ewage > avg(ewage);
答案是不可以。因为分组函数不能用在where后面。为什么呢?在分组查询那里揭晓。
select 字段名1,字段名2...
from 表名
[where 条件]
group by 要分组的字段
[having 分组后过滤的条件];
执行顺序:from --> where --> group by --> having --> select
tips:
案例:
select max(ewage) from emp group by job;
select depino,job,max(ewage) from emp group by deptno,job;
select deptno from emp group by deptno having max(ewage)>2900;
select deptno from emp where ewage>2900 group by deptno;
select deptno,avg(ewage) from emp group by deptno having avg(ewage)>2000;
思考下面这条语句是否正确:
select ename,max(ewage),job from emp group by job;
答案:错误。因为ename没有进行分组。
解决分组函数部分留下的问题:
找出工资大于平均工资的员工
select ename from emp where ewage > (select avg(ewage) from emp);
一个完整的sql语句格式:
执行顺序
select 字段 5
from 表名 1
where 条件 2
group by 要分组字段 3
having 再次过滤的条件 4
order by 排序字段; 6
根据语法来分:
from A,B where A.字段=B.字段
from B join A on 表的连接条件 where 数据筛选条件
根据表的连接方式来分:
inner
outer
在表的连接查询方面有一种现象被称为笛卡尔积现象。即两张表连接的时候没有进行条件限制,导致最终结果是两张表记录条数的乘积。
说白了就是第一张表的每条数据会跟第二张表的每条数据连接,然后形成一张大表。
如何避免笛卡尔积?
答:增加条件限制
避免了笛卡尔积现象会减少匹配次数吗。
答:不会,因为两张表的每条数据还是要带着条件一一匹配,匹配成功则显示。
内连接跟外连接的区别
:
内连接
:假设A表和B表进行内连接,凡是AB表同时匹配上的记录都会被查询出来。外连接
:假设A表和B表进行外连接,那么AB表中有一个是主表,有一个是副表,而查询主要查主表内容,捎带着查询B表而已。即A表中的数据全部会显示,B表中的数据只有跟A表中的数据匹配上时才会显示,否则为null。查询每个员工的部门名称,显示员工名和部门名。
// SQL92写法:
select e.ename,d.dname
from emp e,dept d
where e.deptno=d.deptno;
// SQL99写法:推荐
select e.name,d.dname
from emp e
[inner] join dept d
on e.deptno=d.deptno;
找出员工的工资等级,显示员工名、工资、工资等级
select e.name,e.ewage,e.range
from emp e
join erange r
on e.ewage>=r.lowwage and e.ewage < r.highwage
找出每个员工的上级领导,显示员工名和对应的领导名
select e.ename,e.boss
from emp a
join emp b
on a.boss = b.eno;
//弊端就是当此员工没有上级领导时不显示
找出每个员工的上级领导,显示员工名和对应的领导名
select e.ename,e.boss
from emp a
left [outer] join emp b
on a.boss = b.eno;
//好处是当此员工没有上级领导时正常显示
找出没有员工的部门
select d.*
from emp e
join dept d
on e.deptno = d.deptno
where e.ename!=null;
找出每个员工的部门名称、工资等级以及上级领导
select e.ename,d.dname,w.range,e.boss
from emp e
join dept d
on e.deptno=d.deptno
join wage w
on e.ewage between w.lowwage and w.highwage
left join emp e1
on e.boss = e1.empno;
sql语句中可以嵌套select语句,嵌套的select语句就是子查询。
子查询可以出现在哪里:
select ..(select)
from ..(select)
where ..(select)
在from中嵌套子查询
找出每个部门平均工资的薪水等级
select t.*,w.range
from (select deptno,avg(ewage) as sal from emp group by deptno) as t
join wage w
on t.sal between w.lowwage and w.highwage;
union作用:可以将两个不相干的表的查询结果集相加。
select ename from emp
union
select dname from dept;
语法:limit startIndex,length
startIndex
代表起始位置(不指定默认为0)。length
代表长度。
select ename from emp order by ewage desc limit 5;
select ename from emp order by ewage desc limit 0,5;
select ename from emp order by ewage limit 3,6;
通用的标准分页sql:
设每页显示 5条数据
第一页:limit 0,5
第二页:limit 5,5
第三页:limit 10,5
第四页:limit 15,5
。。。。。。
结论:设每页显示Size条数据,则第N页要显示的数据为:limit (N-1)*Size,Size
格式:
create table 表名(
字段名1 数据类型 [约束条件],
字段名2 数据类型 [约束条件],
字段名3 数据类型 [约束条件],
....
);
如创建学生表(学号,姓名,班级,班级编号,生日)
drop table if exists t_student; //t_student存在的话就删除
create table t_student(
sno bigint,
name varchar(255),
sex char(1)
);
格式:insert into 表名(字段1,字段2...) values(值1,值2...);
字段的数量跟值得数量要相等,且类型要对应相同。
若不指定具体字段则表示全部字段。
insert into t_student values(1,'codekiang','1');
insert into t_student(sno,name,sex) values(1,'codekiang','1');
insert into t_student values(2,'hang','1'),(3,'meinv','0');
insert into t_student(name) values('hhh');
格式:update 表名 set 字段1=值1,字段2=值2... where 条件;
tips:若不指定条件则对整张表的数据全部更新
update dept set loc='shanghai' where deptno=10;
格式:delete from 表名 where 条件;
tips:没有条件则全部删除
delete from dept where deptno=10;
删除大表(不可恢复)
通过delete的方式删除数据后还可以恢复。但如何永久删除数据呢?
truncate table 表名;
表给截断,不可回滚delete table 表名;
常见约束:
not null
:非空约束,表示该字段不能为空unique
:唯一约束,表示该字段不能重复primary key
:主键约束,表示该字段不能为空也不能为重复foreign key
:外键约束,drop table if exists t_user;
create table t_user(
id int not null,
name varchar(255),
);
给某一列添加unique(列级约束)
drop table if exists t_user;
create table t_user(
id int unique,
name varchar(255),
);
给多列分别添加unique
drop table if exists t_user;
create table t_user(
id int unique,
sno int unique,
name varchar(255)
); //每个id不可以重复,每个sno不可以重复
给多列添加unique(表级约束)
drop table if exists t_user;
create table t_user(
id int,
sno int,
name varchar(255),
unique(id,sno),
);//id跟sno联合起来不可以重复,如id=1,sno=2跟id=1,sno=3是不违背unique的。
一般一张表就一个主键,不建议多个。
主键的作用:作为每条记录的唯一标识。
drop table if exists t_user;
create table t_user(
id int primary key,
name varchar(255),
);
主键分类:
单一主键
:就一个主键。(推荐)复合主键
:多个字段联合起来形成一个主键。(违背三范式)自然主键
:主键值不跟业务挂钩。(推荐使用)业务主键
:主键值跟业务挂钩,如身份证,银行卡。**自增主键:auto_increment **
drop table if exists t_user;
create table t_user(
id int auto_increment, //该字段自动维护一个自增的数字,从1开始,每次递增1
name varchar(255),
)
A表的a
字段参考B表的某个唯一
字段,则a字段
被称为外键
tips:
外键值可以为null。
被引用值不一定是主键,但一定要唯一。
外键值 必须 跟 被引用字段中的 其中一个的值 相等。
address表 | user表(dno为外键,参考address的id字段) |
---|---|
id address | sno name dno |
101 广州 | 1 李四 208 正确 ,dno = 208 = id |
208 深圳 | 2 张三 555 不正确 ,dno = 555 != id |
304 梅州 | 3 王五 208 正确 ,dno = 208 =id |
401 佛山 | 4 杭杭 304 正确 ,dno = 304 = id |
格式:
create table student(
sno int,
sname varchar(255),
classno int,
foreign key(classno) references t_class(cno)
);
存储引擎
:mysql存储表的机制。
在建表的时候可以指定存储引擎和字符集。如create table s (id int) ENGINE=InnoDB DEFAULT CHARSET=UTF8;
mysql默认使用的存储引擎是InnoDB
,默认字符集是UTF8
。
mysql常见存储引擎:
MyISAM
.frm
文件(存储表的结构).MYD
文件(存储表的数据).MYI
文件(存储表的索引)InnoDB
.frm
文件**MEMORY
.frm
文件中一个事务是一个完整的业务逻辑,不可再分。
事务的存在使数据更加的安全,完整。
例如:银行账户转账,从A账户向B账户转账1000,需要执行两条DML语句update t_act set money=money-1000 where actno='A';
跟update t_act set money=money+1000 where actno='B';
。此时需要保证这两条更新语句必须同时成功或同时失败。
tips:
事务
。事务执行流程
:
commit;
提交事务。缓存区的内容更新到文件,清空缓存区rollback;
回滚事务。清空缓存区。事务的特性:ACID
事物的隔离性
分为4
个等级:
tips:
oracle
默认使用的隔离级别是:读已提交
mysql
默认使用的隔离级别是:可重复读
start transaction;
可关闭自动提交机制。索引就相当于书目录,通过它可快速查找到数据。
添加索引是只给某个或某些字段添加索引。
数据库查找数据有两种检索机制:
创建索引对象:create index 索引名 on 表名(字段名);
删除索引对象:drop index 索引名 on 表名;
tips:
那什么时候考虑加索引呢:
索引分类:单一索引
、复合索引
、主键索引
、唯一索引
索引底层采用的数据结构:B+树
索引实现原理:
通过B+树缩小扫描范围,底层会对索引字段
**(携带着该字段在表中的物理位置)**进行排序分区(可能是按大小,也可能按字母),当索引检索到数据之后获取到该数据的物理位置,通过物理位置直接定位到表中的数据。
索引什么时候会失效?当模糊查找且第一个位是通配符时。
此部分在另一篇博客写的比较详细,就不在此重复了。
详情可看另一篇博客:数据库原理紧急复习
另外,过几天会放一些我做的练习题跟答案上来。