数据库mySql

175 阅读17分钟

基础命令

  打开mysql:net start mysql

  退出mysql:net stop mysql

  进入mysql数据库: mysql -hlocalhost -uroot -p(简写:mysql -uroot -p)

        其中-h表示服务器名,loc alhost表示本地;-u为数据库用户名,root是mysql默认用户名;-p为密码,如果设置了密码,可直接在-p后链接输入,如:-p123456,用户没有设置密码,显示Enter password时,直接回车即可。

  连接到远程mysql:  假设远程主机的IP为:192.168.206.100,用户名为root,密码为12345678。

                mysql -h192.168.206.100 -uroot -p12345678;

退出mysql数据库:exit、q;

显示所有数据库:  show databases;

对数据库进行的操作:

mysql> create database db_name;  -- 创建数据库

mysql> show databases;           -- 显示所有的数据库

mysql> drop database db_name;    -- 删除数据库

mysql> use db_name;              -- 选择数据库

mysql> create table tb_name (字段名 varchar(20), 字段名 char(1));   -- 创建数据表模板

mysql> show tables;              -- 显示数据表

mysql> desc tb_name;            -- 显示表结构

mysql> drop table tb_name;      -- 删除表

基础概念

  DB: 数据库

  SQL:数据库管理语言,结构化查询语言。

  DBMS:数据库管理系统

  列: 字段

  DQL:数据库查询

DML:数据库增删改

DDL:对表结构的增删改

TCL: 事务控制语言(commit, rollback)

DCL:数据控制语言

总体执行顺序

image.png

select max(age) from t_student where grade = 3 group by sex having sex = girl order by studentID asc

第一步:from 选择表(join on 在其后面)

第二步:where 筛选条件,筛选对象--行   第三步:group by 将筛选出来的数据进行分组

第四步:having 筛选条件,筛选对象--组

第五步:select 选取最后的结果

第六步:order by 将结果按照特定顺序排列

第七步: limit 分页取数

Sql语句

注意

  1. 任何sql语句都以;结尾
  2. 不区分大小写

查询语句(DQL)

简单查询

1、全部查询

Select  *  from 表名  获得该表的全部信息

注意:不建议使用效率低

2、单字段查询

Select 字段名1(表头), from 表名;

3、多字段查询(逗号隔开)

Select 字段名1(表头),字段名2,..., from 表名;

4、给查询的表头重命名

Select  sal*12  as  yearsal,字段名2  from 表名;

Select  sal*12  as  ‘年薪’,字段名2  from 表名;

  注意: 汉字需要加单引号,双引号也可以,但是别的数据库系统不支持;


条件查询

语法格式: select 字段,...,字段 From 表名Where条件

基本符号

等于: 查询工资等于300的员工

Select ename from emp  where sal = 300;

不等于: 查询工资不等于300的员工 <>,!=

Select ename from emp  where sal  <>!=  300;

区间: 查询工资在300-800的员工 between...and

Select ename from emp  where sal between 300 and 800 ; //左小右大

: 找出哪些员工津贴不为null    is null , is not null

Select ename,sal,comn from emp where comn is nullis not null

: 找出哪些员工没有津贴 or,in(not in 取反面)

Select ename,sal,comn from emp where comn is null or comn = 0;

Select ename,sal,comn from emp where comn(is null0);

and和or:找出薪资大于100且部门编号是20或30的员工

Select ename,sal,demtno from emp where sal>100 and (demtno = 20 or demtno = 30);

注意: 当优先级不确定时加小括号。

模糊查询 (like)

基本符号:

            %: 代表任意多个字符

            _: 代表任意一个字符

例:

   找出名字第二个字母是A的?

   Select ename from emp where ename like ‘_A%’;

找出名字中含有_的(转义字符\转义为普通的字符)?

   Select ename from emp where ename like%\_%’;

找出命中最后一个字符是T的 ?

   Select ename from emp where ename like%T’;

排序(order by)

格式:select 字段1,字段2 from 表名order by 字段2

注意:

  1. 默认为升序排列。
  2. 可以拿1,2列这么排序,但是不健壮。不建议

指定升序(asc):

select ename,sal from emp order by sal asc

指定降序(desc):

select ename,sal from emp order by sal desc

例:

   按照工资的降序排列,当工资一样时,按照名字的升序排列?

select ename,sal from emp order by sal desc,  ename asc

   注意:多个字段同时排序,越靠前的字段起的主导作用越大。

找出工作岗位是admin的,并要求按照工资降序?

select ename,sal,job  from emp  where job= admin  order by sal desc; 

分组函数(多行函数)

格式:select 符号(字段) from 表

     基本符号:

             Count:计数

             Sum:求和

             Avg:求平均值

             Max、min:最大值、最小值

注意:

1、所有的分组函数都是对某一组数据进行操作。

2、分组函数自动忽略空。

3、多行函数,输入一行,输出多行。

4、Where后面不能使用分组函数

例:

找出工资总和?(计数,最大,最小格式都相同)

Select sum(sal) from emp;

找出高于平均工资的员工?

Select ename,sal from emp where sal >select avg(sal) from emp)

单行处理函数(进去多少行,出来多少)

计算每个员工的年薪?

Select ename,(sal+comn)*12 as yearsal from emp;

注意:如果函数的某一个字段为null,则最后输出的结果也为null。

当有字段可能为null时(sum除外)?Ifnull空处理函数解决

Select ename,(sal+ifnull(comm,0))*12 as yearsal from emp;

分组查询(group by, having)

Group by:按照某个字段或者某些字段进行分组。

Having:对分组过后的数据进行再次过滤。

注意:1、分组函数都是在分组之后进行的,通常都会连用。

2、分组都是在where之后执行。

3、默认自成一张表。

4、当一条sql出现group by时,select后出现的字段只能跟分组函数和参与分组的字段。

5、能在where中过滤的先过滤,在考虑having,提高性能。

6、having  和Group by不能分开,having不能单独用,group by 可以。

例:

   找出每个岗位的最高工资?

     Select  max(sal) from  emp  group  by  job;

   找出每个部门不同岗位的最高薪资?(联合分组,注意分组顺序)

     Select job,daprt,max(sal) from  group by depart,job

   找出每个部门的最高薪资,要求显示大于290的?

     Select max(sal),depart from emp where sal >2900 group by depart;

     select max(sal),depart from emp where group by depart having max(sal)> 290;

   找出每个部门的平均薪资,要求显示薪资大于200的数据?

     Select depart,avg(sal) from emp group by depart having avg(sal) >200;

去除重复记录(distinct)

格式:Select  disitinct 字段,...,字段 from 表;

注意:distinct 必须出现在所有字段的最前方,表示所有字段联合去重。因为去重后数据行数不同,与不去重的相比 例:

  统计岗位的数量?

  Select count(distinct job) from emp;

连接查询

意义:实际开发中通常不是单表查询,而是多张表联合查询,一个业务对应多个表,一个表存在太多数据的时候会导致数据冗余。

连接分类

        年代:Sql92,Sql99;

        方式:

             内连接:等值连接,非等值连接,自连接

             外连接: 左外连接,右外连接。

连接查询原理和笛卡尔积现象

 例:

   找出每一个员工的部门名称,要求显示员工名和部门名?

     Select ename,dname from emp,dept;

     Select e.ename,d.dnamefrom emp e,dept d; //取别名

输出14*4共56条数据,因为没有任何条件进行约束,最终结果是两张表记录条数的乘积,这就是笛卡尔积现象。

表别名的好处: 可读性高,执行效率高。  

避免笛卡尔积现象

Select e.ename,d.dname from emp e,dept d where e.depart = d.depart; 

 // sql92   淘汰了

匹配的次数不会减少,但是显示的数据会少

内连接****

假设A和B表进行连接,使用内连接的话,凡是A表和s表能够匹配上的记录查询出来,这就是内连接。AB两张表没有主副之分,两张表是平等的。

内连接之等值连接****

 例:

   找出每一个员工的部门名称,要求显示员工名和部门名?

Sql92:

  Select e.ename,d.dname from emp e,dept d where e.depart = d.depart;

  Sql99:

  Select e.ename,d.dname from emp e  join dept d on e.depart = d.depart;

  优点: 表的连接条件和后面的where条件分离了。

内连接之非等值连接

找出每个员工的工资等级,要求显示员工们,工资,工资等级?

Select e.ename,e.sal,s.grade from emp e join salgrade on e.sal between e.losal and e.hisal;

注意: between  and  是闭区间

内连接之自连接

特点:一张表看做两张表,自己连自己

例:

   找出每个员工的上级领导,要求显示员工名和对应的领导名?

Select  a.ename as ‘员工名’, b.ename  as ‘领导名’ from emp a join emp b on a.mgr = b.empno
外连接

假设A和B表进行连接,使用外连接的话,A两张表中有一张表是主表,一张表是副表,主要查询主表中的数据,捎带着查询副表,当副表中的数据没有和主表中的数据匹配上,副表自动模拟出NUZ与之匹配。

左外连接: 左边为主表

右外连接: 右边为主表

左连接有右连接的写法,右连接也有左连接的写法。

特点:主表的数据无条件的查询出来。

例:

   找出每个员工的上级领导,要求显示员工名和对应的领导名,员工名是主表?

Select  a.ename as ‘员工名’, b.ename  as ‘领导名’ from emp a left join emp b on a.mgr = b.empno;

相比内连接多了King的数据,因为King没有领导,但是外连接的时候员工名是主表,所以显示King员工,领导为null。

多表查询

A和B表先连接,之后A表再和C表连接

Select  e.ename, d.dname, 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

 

子查询

Where 子查询

   找出高于平均薪资的员工信息?

第一步先找平均薪资

Select avg(sal) from emp;

第二步输出信息

Select * from emp where sal > (Select avg(sal) from emp)
From子查询

   找出每个部门平均薪资的薪资等级?

第一步:找出每个部门的平均薪资,然后把其当做一个临时表和薪资等级表做连接。条件是

select d.deptno, s.grade from (select deptno, avg(sal) as avgsal   from emp group by deptno) d join salgrade s on d.avgsal between  s.losal and s.hisal;

   找出每个人的薪水等级

第一步: select e.deptno, s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal;

 第二步   加右连接是因为deptno40 没有人 但是我表里也得显示

select d.deptno, avg(t.grade) from (select e.deptno, s.grade from emp e join salgrade s on e.sal between s.losal and s.hisal) t right join dept d on d.deptno = t.deptno group by d.deptno;

不用子查询的做法: 但是因为我们没有和dept做连接,所以少了个部门

select e.deptno, avg(s.grade) from emp e join salgrade s on e.sal between s.losal and s.hisal group by e.deptno;

在select后嵌套子查询

找出每个员工所在的部门名称,要求显示员工名和部门名?

Select e.ename, d.dname from emp e join dept d on e.deptno = d.deptno;

嵌套写法****

Select e.ename, (select dname from dept where e.deptno = deptno)  as dname from emp;

 

Union(可以将查询结果集相加)

如果是查询两张表时,查询的字段要一样多

image.png

Limit以及通用分页查询****

Limit是mysql特有的,其他数据库没有,oracle 有个类似的语句*(rownum)

Limit是语句执行的最后一个环节

startIndex 为 length * (页数 -1)

语法:

Limit   startindex,length

       startIndex表示起始位置

       Length 表示取几个

案例:

取出工资前五名的员工?0可以省略不写

Select ename from emp order by desc limit 0,5 

创建表

常见的数据类型

Int

Bigint

Float

Char  定长字符串

Varchar  可变长字符串

Date   添加时也需要加引号

Blob (二进制,储存图片视频等流媒体)

Clob (字符大对象,储存较大文件)

BLOB 和 CLOB不能用insert 插入 ,需要 lo流写入

Default 可指定默认值

create table t_student

(no bigint,

name varchar(255),

 sex char(1)   default  “1”,

classno varchar(255),

birth date);
#### **更改表结构(了解)******

1、添加表字段

alter table 表名 add  字段名 类型(值)

示例:alter table   user  add name varchar(40);

2、删除表字段

alter table 表名 drop  字段名

示例: alter table user drop name;

 

3、字段名更名

alter table 表名 rename 老字段名 to 新字段名

示例:alter table  user  rename oldname to newname;

 

4、更改字段类型

alter table 表名 alter 字段 类型;

示例:alter table user alter name varchar(50);

插入数据

格式: insert  into  表名(字段名1,字段名2....) values(值1,值2...)

简写: Insert  into  表名 values(值1,值2)

一次插入多行数据:Insert  into  表名 values(值1,值2),(值1,值2),(值1,值2);

   

要求:字段的数量和值的数量相等,并且数据类型要相对应。

      简写的方式要求字段列的values相等而且必须按顺序添加

 

例:

Insert into

 t_student(no,name,sex,classno,birth )

values(0,”zs”,”1”,”sannian2ban”,”1998-10-14”)

表的复制

格式: create table 新表名 as  select语句(被复制的表);

将查询结果当做表创建出来

将查询结果插入到一张表中****

格式: insert  into 表名 select * from 查询表

修改数据(update)

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

注意: 没有条件整个表都会修改,通常都将no的值作为标识。

update t_student set classno = "三年二班邱小东" where no = 0;

删除数据(delete)

格式:delete  from 表名 where 条件;

注意:没有条件全部删除

Delete from  t_student  where  no =1;

删除大表

Truncate table 表名; //表被截断,不可回  

约束*

什么是约束?常见的约束有哪些呢?****

在创建表的时候,可以给表的字段添加相应的约束,添加约束的目的是为了保证表中数据的合法性、有效性、完整性。

常见的约束有哪些呢?

非空约束(not null) : 约束的字段不能为null

唯一约束(unique) : 约束的字段不能重复

主键约束(primary key) : 不能为null 也不能重复

外键约束(foreign key)

检查约束(check):注意oracle数据库有check约束,但是mysq1没有,目前mysql不支持该约束.

非空约束(not null)****

image.png  

唯一性约束(unique)

image.png

联合约束:

注意: 多行之间的usercode和username 不能同时相同,单个可以相同,表级约束 image.png

主键约束(primary key)

image.png

术语

主键约束 : primary key

主键字段 : 添加主键约束的字段

主键值: 主键字段中的每个值

主键的作用

表的设计三范式中有要求,第一范式就要求任何一张表都应该有主键。

主键的作用:主键值是这行记录在这张表当中的唯一标识。(就像一个人的身份证号码一样)

主键的分类

根据主键字段的字段数量来划分:

单一主健(推荐的,常用的。)

复合主键(多个字段联合起来添加一个主键约束)(复合主键不建议使用,因为复合主键违背三范式。)

根据主键性质来划分:

自然主键:主键值最好就是一个和业务没有任何关系的自然数。

业务主键:主键值和系统的业务挂钩,例如:拿着银行卡的卡号做主键,拿着身份证号码作为主键。(不推荐用)

最好不要拿着和业务挂钩的字段作为主键。因为以后的业务一旦发生改变的时候,主键值可能也需要随着发生变化,但有的时候没有办法变化,因为变化可能会导致主键值重复。

 

以下看看就行

image.png

image.png

主键值自增(auto_increment)

image.png

外键约束(foreign key)

image.png

引用副表(reference 表名(字段名))

image.png

image.png

事务(transaction)

image.png

和事务相关的语句只有:DM语句。(insert delete update)

为什么?因为它们这三个语句都是和数据库表当中的"数据"相关的。事务的存在是为了保证数据的完整性,安全性。

假设所有的业务都能使用1条DM语句搞定,还需要事务机制吗?

不需要事务。

但实际情况不是这样的,通常一个"事儿(事务【业务】)"需要多条DMz语句共同联合完成。

事务的特性?

事务包括四大特性:ACID

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

C:一致性:事务必须保证多条DM语句同时成功或者同时失败。

I:隔离性:事务A与事务B之.间具有隔离。

D:持久性:持久性说的是最终数据必须持久化到硬盘文件中,事务才算成功的结束。

关于事务之间的隔离性

事务隔离性存在隔离级别,理论上隔离级别包括4个:

第一级别:读未提交(read uncommitted)

对方事务还没有提交,我们当前事务可以读取到对方未提交的数据。读未提交存在脏读(Dirty Read)现象:表示读到了脏的数据。

第二级别:读已提交(read committed)

对方事务提交之后的数据我方可以读取到。这种隔离级别解决了:脏读现象没有了。读己提交存在的问题是:不可重复读。

第三级别:可重复读(repeatable read)

这种隔离级别解决了:不可重复读问题。这种隔离级别存在的问题是:读取到的数据是幻象。就是数据备份缓存下来的数据,不是原表的数据,读到的都是一样的,不管怎么折腾

第四级别:序列化读/串行化读

解决了所有问题。

效率低。需要事务排队。一个事务开启了,在没有commit之前其他对表的操作都不生效。

oracle数据库默认的隔离级别是:读已提交。

Mysql数据库默认的隔离级别是:可重复读。

事务的演示

Start  transaction 开启事务,即不自动保存 Commit 提交   rollback 回滚 回滚只能回滚到上一个提交点

image.png

记得接下来开启事务 start transaction

索引

image.png

注意

image.png

创建索引

Create index 索引名称on 表名(字段名)

删除索引

Drop index 索引名称 on 表名

索引的分类?

单一索引:给单个字段添加索引

复合索引:给多个字段联合起来添加1个索引主键索引:主键上会自动添加索引

唯一索引:有unique约束的字段上会自动添加索引.. ..

索引什么时候失效?

select ename from emp where ename like '%A%' ;

模糊查询的时候,第一个通配符使用的是%,这个时候索引是失效的。

视图(view)

什么是视图?

站在不同的角度去看到数据。(同一张表的数据,通过不同的角度去看待)。

怎么创建视图?怎么删除视图?

create view myview as select empno , ename from emp;

drop view myview ;

注意:只有DQL语句才能以视图对象的方式创建出来。

对视图进行增删改查,会影响到原表数据。(通过视图影响原表数据的,不是直接操作的原表)可以对视图进行cRUD操作。

视图的作用

视图可以隐藏表的实现细节。保密级别较高的系统,数据库只对外提供相关的视图,java程序员只对视图对象进行CRUD.

DBA命令

导出整个数据库(做项目之前先去备份)

在windows的dos命令窗口中执行:

mysqldump 数据库名>地址+命名  -uroot -p333

mysqldump bjpowernode>D : \bjpowernode.sql -uroot -p333

导出指定库下的指定表

导入

create database bjpowernode ;

use bjpowernode ;

source D: \bjpowernode . sql

三范式

注:一对多,两张表,多的表加外键:多对多三张表关系表俩外键

image.png

image.png

存储引擎(了解)

image.png

常用的存储引擎

1、MYISAM

image.png

2、innoDB默认使用,支持事务,数据库崩溃后自动恢复 image.png

3、MEMORY(停电了数据就没了) image.png