mysql数据库——思维导图

学完mysql后,自己弄得的思维导图。原图30.6MB,太大了放不上来,这里就放个链接吧。
欢迎大家去看,如果有需要改正的地方,请告诉我,谢谢。
链接:https://www.zhixi.com/view/718f3805
密码:6522

下面是MarkDown形式的的内容,但是缺少一些图片。完整的在思维导图上。

mysql数据库

使用DOS命令行窗口连接MySQL数据库

连接到mysql数据服务(mysql数据库)的指令:

mysql -h 主机IP -P 端口名 -u 用户名 -p密码

【注意事项】:

1、-p密码 之间不要有空格。
2、-p后面如果没有写密码,回车之后会要求输入密码。
3、如果没有写 -h 主机,则默认就是本机。
4、如果没有写 -P 端口名,则默认就是3306。
5、在实际工作中,为保证安全,一般会将3306改为其他端口号。

启动数据库 的常用方式

net start mysql服务名

net stop mysql服务名

安装图形化MySQL管理软件

Navicat

SQLyog

数据库的三层结构

1、所谓的安装mysql数据库,就是在主机安装一个“数据库管理系统(DBMS)”,这个管理程序可以管理多个数据库。

DBMS(Database manage system)

2、一个数据库可以创建多个表,以保存数据(信息)

3、数据库管理系统,数据库 和 表的关系。如上图所示

4、mysql数据库 – 普通表的本质仍然是文件。表的一行(row)称之为一条记录,在 Java 程序中,一行记录往往使用“对象”来表示。

SQL语句的分类

DDL:数据定义语句【create 表,库…】

DML:数据操作语句【增加 insert,修改 update,删除 delete】

DQL:数据查询语句【select】

DCL:数据控制语句【管理数据库:例如用户权限(grant,revoke)】

对数据库的增、删、查

创建数据库

create datebase [if not exists] 数据库名 [default] character set 字符集名 [default] collate 校对规则名;

显示数据库语句

show databases;

显示数据库创建(定义信息)语句

show create database 数据库名;

删除数据库

drop database [if exists] 数据库名;

备份恢复数据库

备份数据库(在DOS命令行)

mysqldump -u 用户名 -p -B 数据库1 数据库2 数据库n > 文件名.sql

恢复数据库(进入mysql命令行,然后执行)

source 文件名.sql

例如:source d:\bak.sql ;

直接将 bak.sql 的内容放到查询编辑器中,执行。

备份恢复数据库的“表”

备份库的表

mysqldump -u 用户名 -p密码 数据库1 表1 表2 表n > d:\文件名.sql

创建表

field: 指定列名

datatype: 指定列类型(字段类型)
character set: 如果不指定,则为所在数据库的字符集
collate: 如果不指定,则为所在数据库的校对规则
engine: 存储引擎

mysql表类型 和 存储引擎
基本介绍
  • 1、mysql的表类型由存储引擎(storage engines)决定,主要包括:MyISAM、innodb、Memory 等。
    2、MySQL数据表主要支持 6种类型,分别是:CSV、Memory、ARCHIVE、MGR MYISAM、MYISAM、InnoDB。
    3、这六种又分为2类:一类是“事务安全型”(transaction-safe),比如:innodb ;
    其余都属于第二类,称为“非事务安全”型(non-transaction-safe)【myisam 和 memory】
主要的 存储引擎/表 类型特点
细节说明
  • 1、MyISAM不支持事务,也不支持外键,但是其访问速度快,对事物的完整性没有要求。
    2、InnoDB存储引擎提供了具有 提交、回滚和崩溃恢复能力的事务安全。但是比起MyISAM存储引擎,InnoDB写的处理效率差一些,并且会占用更多的磁盘空间,以保留数据和索引。
    3、Memory存储引擎使用“存在内存中的内容”来创建表。每个Memory 表只实际对应一个磁盘文件。Memory类型访问非常得快,因为它的数据是存储在内存中的,并且还使用Hash索引。但是一旦 MySQL服务关闭,表中的数据就会丢失掉,但是“表的结构”还在。
如何使用MyISAM、InnoDB、Memory三种存储引擎 ?
  • – 查看所有的存储引擎
    SHOW ENGINES;

  • – innodb存储引擎是前面使用过的。
    /* 1、支持事务;2、支持外键;3、支持行级锁 */

如何选择表的存储引擎
  • 1、如果你的应用不需要事务,处理的只是基本的CRUD操作,那么MylSAM
    是不二选择,速度快
    2、如果需要支持事务,选择lnnoDB。
    3.、Memory存储引擎就是将数据存储在内存中,由于没有磁盘I./O的等待,
    速度极快。但由于是内存存储引擎,所做的任何修改在服务器重启后都将消失。(经典用法:用户的在线状态)
修改存储引擎
  • ALTER TABLE 表名 ENGINE = 存储引擎 ;

约束

primary key(主键)

用于唯一的标示表行的数据,当定义主键约束后,该列不能重复
【细节说明】:

1、primary key 不能重复,而且不能为null。
2、一张表最多只能有一个主键,但可以是复合主键。
3、主键的指定方式有两种
(1)在创建表时,直接在字段名后指定:字段名 字段类型 primary key
(2)在表定义的最后一行填写,此时还在()内部:primary key(列名),
4、使用 desc 表名 可以看到 primary key 的情况。
5、在实际开发中,每个表往往都会设计一个主键。

【举例】

CREATE TABLE t17(
id INT PRIMARY KEY, – 表示 id 列是主键
name VARCHAR(32),
email VARCHAR(32)
);

复合主键
  • 一张表最多 只能有一个主键,但是可以是复合主键(那也只能有1个)。
    CREATE TABLE t18(
    id INT PRIMARY KEY,
    name VARCHAR(32) PRIMARY KEY,-- 错误
    email VARCHAR(32)
    );

  • /* 演示复合主键的使用(id和name做成复合主键) */
    CREATE TABLE t18(
    id INT,
    name VARCHAR(32),
    email VARCHAR(32),
    PRIMARY KEY (id,name) – 这里就是复合主键,以后添加数据时,只有id和name同时发生重复时,才会报错。
    );

not null(非空)
如果在列上定义了not null,那么插入数据时,必须为列提供数据。

字段名 字段类型 not null

自增长
基本介绍
  • 在某张表中,存在一个id列(整数),我们希望在添加记录的时候,该列从 1 开始,自动增长。
使用细节
  • 1、一般来说,自增长和 primary key 配合使用。
    2、自增长也可以单独使用(但是需要配合一个 unique)
    3、自增长修饰的字段为整数型的。(虽然小数也可以但是很少这样使用)
    4、自增长默认从1开始,也可以通过下列命令来修改
    alter table 表名 auto_increment = 新的开始值 ;
    5、如果添加数据时,给自增长字段(列)指定的有值,则以指定的值为准。如果指定了自增长,就按照自增长的规则来添加数据。
添加 自增长的的字段方式
  • (1)insert into xxx(字段1,字段2,…) values(null,‘值’,…) ;

– null对应字段1,如果字段1是自增长的,那么添加之后就是1,之后2,3。

  • (2)insert into xxx(字段2,…) values(‘值1’,‘值2’,…) ;

– 直接从字段2开始写,值1对应字段2,…不给字段1赋值,它会自己从1开始增长。

  • (3)insert into xxx values(null, ‘值1’,…)

– 前面直接什么都不写,然后把所有数据的值都写清楚,它会自动的添加。

举例
  • 创建表

  • 测试自增长的使用

    • INSERT INTO t24
      VALUES(NULL, ‘tom@qq.com’,‘tom’);

这里的null给的是id,因为id是自增长的,所以虽然写的是null,但是实际上给的是1。再执行一次,给tom分配的id为2。

  * 执行一次,给hsp分配的id为3

INSERT INTO t24
(email,name) VALUES(‘hsp@123.com’,‘hsp’);

  • 修改默认的自增长开始值

unique(唯一)

在定义了唯一约束后,该列的值是不能重复的。

字段名 字段类型 unique

【细节】:

1、如果没有指定 not null,则unique字段可以有多个 null。
2、一张表可以有多个 unique字段。
3、unique not null 使用效果类似 primary key

foreign key(外键)

用于定义 主表 和 从表 之间的关系:

1、外键约束要定义在“从表”上,“主表”则必须要有“主键约束”或者“unique”约束。这样形成的外键约束关系才是唯一的。
2、当定义外键约束后,要求外键列数据必须在主表的主键列存在或是为null。

【举例】学生表(从表,即:外键所在的表) 班级表(主表)
           id, name, class_id                                  id, class_name

1、学生表的class_id为300的,在班级表中并不存在,所以就会添加失败,这叫外键约束.
2、如果学生表的jack和班级表已建立联系再删除班级表的id就会失败,得先删除学生表的jack才行,也叫外键约束

【基本语法】

foreign key(本表字段名) references 主表名(主键名或者unique字段名)

【细节说明】

1、外键指向的主表的字段,必须是primary key 或者 unique;
2、表的类型(存储引擎)是“innodb”,这样的表才支持外键
3、外键字段的类型和关联的主键字段的类型要一致,长度可以不一样。
4、外键字段的值,必须在主键字段中出现过,或者为“null”【前提是:外键字段允许为null】
5、一旦建立了 主键、外键的关系,数据就不能随意删除了。
6、删除主表的记录能否成功,要看是否有从表的外键指向它。如果有,则把从表中的相关记录全部删掉,然后再删主表的记录

check

check:用于强制行数据必须满足的条件。
假定在sal列上,定义了check约束,并要求sal列的值在1000~2000之间。如果不在这个范围内就会报错。
【老韩提示】oracle和sql server均支持check,但是MySQL5.7 目前还不支持check,只做语法校验,但不会生效。
		即:语法上支持,但运行不会生效, 如果不满足check的条件,语句也会执行。
【基本语法】:列名 类型 check (check的条件)
【举例】

CREATE TABLE t23(
id INT PRIMARY KEY,
name VARCHAR(32),
sex VARCHAR(6) CHECK (sex IN (‘man’,‘woman’)),
sal DOUBLE CHECK (sal>1000 AND sal<2000)
);

mysql常用的的“数据类型”(列类型)

数值型(整数)的基本使用

使用规范:在满足需求的情况下,尽量选择占用空间小的。

#1. 如果没有指定 unsinged , 则 Ttinyint 就是有符号

#2. 如果指定 unsinged , 则 tinyint 就是无符号 0-255

【举例】

create table t01(id tinyint); # 有符号的
create table t01(id tinyint unsigned); # 无符号的

数值型(bit)的基本使用

【说明】

1、bit(m) m在1~64。8是一个字节,64是8个字节。
2、添加数据 范围按照你给的位数来确定。8位一个字节来控制,比如m=8,表示一个字节0~255
3、显示按照bit位的方式来显示。【0是0,1是1,2是10,3是11,255是1111 1111】
4、查询时仍然可以按照 数 来查询。

【举例】

CREATE TABLE t05 (num BIT(8));
INSERT INTO t05 VALUES(2);

数值型(小数)的基本使用

float/double [unsigned]

float–单精度,double–双精度

decimal[M,D] [unsigned]

(1)可以支持更加精确地小数位。M是小数位数(精度)的总数,D是小数点(标度)后面的位数。
如:decimal(5,3):一共是5位数,其中小数有3位。

(2)如果D是0,则值没有小数点或分数部分。M最大是65,D最大是30。
【如果D被省略,默认是0;M被省略,默认是10】

(3)【建议】如果希望小数的精度高,推荐使用decimal。

字符串 的基本使用

char(size) 固定长度字符串,最大255字符

varchar(size) 0~65535字节 :可变长度字符串,最大65532字节【utf8编码最大21844字符,1-3个字节用于记录大小】

【utf8编码最大21844字符,每个汉字3个字节,所以65532/3 = 21844】
【gbk编码,每个汉字2个字节,65532/2 = 32766个 字符】

【使用细节】

细节一
char(4) // 这个4表示字符数(最大255),不是字节数,不管是中文还是英文字母都是放4个,按字符计算。
varchar(4) //这个4表示字符数,不管是中文还是字母都是以定好的表的编码来存放数据。不管是中文还是英文,都最多存放4个,是按照字符来存放的。
细节二
char(4) 是定长(固定大小),就是说:即使插入的是‘aa’,也会占用分配的4个字符的空间。
varchar(4) 是变长(变化的大小),就是说,即使插入了‘aa’,实际占用空间大小并不是4个字符,而是按照实际占用空间来分配。
  • varchar本身还需要1-3个字符来记录存放内容的长度。L (实际数据大小) +(1-3)字节
细节三
什么时候用char?什么时候用varchar?
  • 如果数据是定长,推荐使用char。比如:md5的密码,邮编,手机号,身份证号等。

  • 如果一个字段的长度不确定,我们使用varchar,比如:留言,文章

  • 查询速度:char > varchar

细节四
存放文本时,可以使用text数据类型。可以将 TEXT列 视为 VARCHAR列。

注意text不能有默认值,大小0~2^16字节。
如果希望存放更多的字符,可以选择 mediumtext 0~2^24
或者 longtext 0~2^32

日期类型 的基本使用

需要在 timestamp数据类型后添加的代码为:

NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP

删除表

drop table 表名 ;

修改表

基本介绍

使用 alter table 语句追加,修改或删除列的语法

添加列

alter table 表名

add (column datatype [dafault expr]
[, column datatype]…
);

【举例】

(1)员工表 emp 的上增加一个 image 列,varchar 类型(要求在 resume 后面)
ALTER TABLE emp
ADD image VARCHAR(50) NOT NULL DEFAULT ‘’
AFTER resume ;

删除列

alter table 表名 drop (column) ;

修改列

alter table 表名

modify (column datatype [dafault expr]
[, column datatype]…
);

查看表的结构

desc 表名 ;

修改表名

rename table 表名 to 新表名

修改表的字符集

alter table 表名 character set 字符集 ;

修改列名

【举例】修改列名name为user_name

ALTER TABLE employee
CHANGE name user_name VARCHAR(32) NOT NULL DEFAULT ‘’ ;

删除列

alter table 表名 drop 列名 ;

数据库的CRUD语句

C[create]

R[read]
U[update]
D[delete]

insert语句

基本语法

insert into 表名 [(列名 [, 列名, …])]

   values (value [, value, ...]) ;

使用细节

1、插入的数据应与字段的数据类型相同。

2、数据的长度要在列的规定范围内。

3、在values中列出的数据位置,必须与被加入的列的排列位置对应。

4、字符和日期型数据应该包含在单引号中。

5、列可以插入空值(前提是该字段允许为空) insert into table value(null)

6、insert into 表名(列名…) value(), (), () 的形式添加多条记录。

7、如果是给表中的所有字段添加数据,可以不写前面的字段名称。

8、默认值的使用:

(1)当不给某个字段值时,如果有默认值就添加默认值,否则就报错。
(2)如果某个列没有指定 not null,那么当添加数据时,没有给定值,则默认会给null。
(3)如果我们希望指定某个列的默认值,可以在创建表时指定。

举例

INSERT INTO goods (id, goods_name, price)

VALUES(50, ‘三星手机’, 2300),(60, ‘海尔手机’, 1800);

INSERT INTO goods VALUES(70, ‘IBM 手机’, 5000);

CREATE TABLE dept( /部门表/

     deptno MEDIUMINT UNSIGNED NOT NULL DEFAULT 0, 
     dname VARCHAR(20) NOT NULL DEFAULT '', 
     loc VARCHAR(13) NOT NULL DEFAULT ""

);

update语句

使用update语句修改表中的数据

基本语法

update 表名

     set 列名2 = 新的值 [,列名2 = 新的值 , ...]
     [where 条件语句] ;

使用细节

1、update语法可以用新值更新原有表行中的各列。

2、set子句指示要修改哪些,要给予哪些值。

3、where子句指定 应该更新哪些行。如果没有where子句,则更新所有的行(记录),所以一定要小心。

4、如果需要修改多个字段,可以通过 set 字段1 = 值1, 字段2 = 值2 …

5、在set子句中,不存在 += 或 -= 之类的情况。老老实实的用 num = num +1 这样的语句形式。

delete语句

使用delete语句删除表中的数据(按行)

基本语法:

delete from 表名

   [where 条件语句] ;

删除表中的所有记录

delete from 表名 ;

使用细节:

1、如果不使用 where子句,将会删除表中的所有数据。

2、delete语句不能够删除某一列的值。(可以使用update 设为 null 或者 ‘’)

3、使用delete语句仅能够删除表中的记录,不删除表本身。如要删除表,使用drop语句。 drop table 表名 ;

查询表select

单表查询

基本语法

select [distinct] * | {列名1, 列名2, …}
   from 表名 ;

注意事项

1、select 指定查询哪些列的数据。
2、select * 表示查询所有的列

select emp.* 表示查询emp表的所有列。

3、from 指定查询哪张表。
4、distinct 可选,指显示结果时,是否去掉重复数据。

使用表达式,对查询的列进行运算

语法:

select * | {列名1 | 表达式1, 列名2 | 表达式2… }
from 表名 ;

【举例】

SELECT name,(chinese + english + math + 10) FROM student;

在select语句中使用 as 语句给列名起一个别名

语法:

select 列名 as 别名 from 表名 ;

【举例】

SELECT name AS ‘姓名’, (chinese + english + math + 10) AS total_score FROM student;

在where子句中经常使用的运算符

between … and … 是闭区间

使用where子句,进行过滤查询

使用 order by 子句排序查询结果

基本语法
select 列名1, 列名2, 列名3…
   from 表名
   order by 列名 asc | desc
使用细节
1、order by 指定排序的列,排序的列既可以是表中的列名,也可以是select语句后指定的列名。
2、asc – 升序
  desc -- 降序
3、order by 子句应该位于select 语句的结尾。

加强查询

在 mysql 中,日期类型可以直接比较, 需要注意格式

SELECT * FROM emp

WHERE hiredate > ‘1992-01-01’ ;

like操作符

% 表示 0~多个任意字符

_ 表示单个任意字符

如何显示第三个字符为大写 O 的所有员工的姓名和工资 ?

SELECT ename, sal FROM emp
WHERE ename LIKE ‘__O%’ ;

order by 子句(多个排序条件)

按照部门号升序而雇员的工资降序排列 , 显示雇员信息

SELECT * FROM emp
ORDER BY deptno ASC , sal DESC ;

分页查询

基本语法:

select … limit start, rows
表示 从 start+1 行开始取,取出 rows行,start从 0 开始计算

推导公式

select * from 表名
order by 列名
limit 每页显示记录数 * (第几页-1), 每页显示记录数

使用分组函数和分组语句 group by

SELECT COUNT(*),COUNT(IF(comm IS NULL,1,NULL)) ;

如果comm列为空,如果是空的就返回1,如果不为空就返回null。

FROM emp;
显示管理者的总人数

SELECT COUNT(*) FROM emp WHERE job = ‘MANAGER’;
或者
SELECT COUNT(DISTINCT mgr ) FROM emp; #distinct —— 去重

数据分组的总结

如果select语句中同时含有group by,having,limit,order by。那么它们的顺序是:group by,having,order by,limit。
/*

select 列名1,列名2,列名3,… from 表名

group by 列名

having 条件

order by 列名

limit start,rows ;

如果顺序写错,语法不会通过。

*/

【应用案例】

请统计各部门的平均工资,并且是大于1000的,而且按照平均工资从高到低排序,取出前两行记录。
SELECT deptno,AVG(sal) AS ‘平均工资’
FROM emp
GROUP BY deptno
HAVING 平均工资>1000
ORDER BY 平均工资 DESC # 【分组 --> 过滤 --> 排序】
LIMIT 0,2;

多表查询

多表查询指的是:基于2张或者2张以上的表进行的查询

当我们需要指定显示某个表的列是,需要 表.列表

举例

SELECT ename,sal,dname,emp.deptno FROM emp,dept #ok
WHERE emp.deptno = dept.deptno;
– ?如何显示部门号为10的部门名、员工名和工资

SELECT dname,ename,sal,emp.deptno
FROM emp,dept
WHERE emp.deptno = dept.deptno AND emp.deptno = 10 ;

注意事项

在默认情况下:当两个表进行查询时,规则:

1、从第一张表中,取出1行和第二张表的每一行进行组合,返回多个结果。【含有两张表的所有列,全部都包含在里面】

2、一共返回的记录数:第一张表的行数第二张表的行数。【134=52】

3、这样的多表查询默认处理的返回结果,称为“笛卡尔集”。

4、解决多表的关键:在where中 写出正确的过滤条件。这需要程序员进行正确的分析。
– 老韩小技巧:多表查询的条件不能少于表的个数-1,否则会出现笛卡尔集

自连接

定义
在同一张表的连接查询【将同一张表看作两张表】
特点
1、把同一张表当做两张表使用
2、需要给表取别名 表名 表别名
3、列名不明确,可以指定列的别名 列名 as 列的别名
举例
SELECT worker.ename AS ‘职员名’ , boss.ename AS ‘上级名’

FROM emp worker, emp boss
WHERE worker.mgr

注意事项
给表取别名,那么这个别名可以在查询语句的 select 部分中使用,但是也只能在这个查询语句中使用!

子查询

定义

嵌入在其他sql语句中的select语句,也叫“嵌套查询”

单行子查询

只返回一行数据的子查询语句
【举例】

【Question】如何显示与smith同一部门的员工?

1、先查询smith在哪个部门,部门号是什么?
SELECT deptno
FROM emp
WHERE ename=‘SMITH’;

2、把上面的select语句当做一个子查询使用。
SELECT * FROM EMP
WHERE DEPTNO=(
SELECT deptno
FROM emp
WHERE ename=‘SMITH’
);

多行子查询

返回多行的子查询语句,使用关键字in
【举例】

如何查询和部门 10 的工作相同的雇员的 名字、岗位、工资、部门号, 但是不含 10 号部门自己的雇员。

1、查询到10号部门有哪些工作

SELECT DISTINCT job
FROM emp
WHERE deptno = 10

2、把上面查询的结果当做子查询使用

SELECT ename, job, sal, deptno
FROM emp
WHERE job IN ( # 多行子查询要使用in
SELECT DISTINCT job
FROM emp WHERE deptno = 10
) AND deptno <> 10;

子查询当做临时表使用
把子查询的语句用括号括起来,放在from 子句中,并在括号后面 对临时表取别名tmp
  • 【举例】
    查询每个部门的信息(包括:部门名,编号,地址)和人员数量
    SELECT tmp.* , dname, loc
    FROM dept, (
    SELECT COUNT(*) AS per_num, deptno
    FROM emp
    GROUP BY deptno
    ) tmp
    WHERE tmp.deptno = dept.deptno ;
在多行子查询中使用 all / any
all
  • – 请思考:显示工资比部门30的所有员工的工资高的员工的姓名、工资和部门号。
    SELECT ename,sal,deptno
    FROM emp
    WHERE sal>ALL(
    SELECT sal
    FROM emp
    WHERE deptno = 30
    );
any
  • – 请思考:显示工资比部门30的其中一个(任意一个)员工的工资高的员工的姓名、工资和部门号。
    在多行查询中使用any操作符
    SELECT ename,sal,deptno
    FROM emp
    WHERE sal>ANY(
    SELECT sal
    FROM emp
    WHERE deptno = 30
    );

多列子查询

指的是:返回多个列的子查询语句
基本语法
(字段1,字段2…) = (select 字段1,字段2 from…) ;

字段1与字段1匹配,字段2与字段2匹配。

举例
【问题】查询与allen的部门、岗位完全相同的所有雇员(并且不含smith本人)。

– 分析:1、得到allen的部门、岗位
SELECT deptno, job
FROM emp WHERE ename = ‘ALLEN’;

– 2、把上面的查询当做子查询使用,并且使用多列子查询的语法来进行匹配
SELECT * FROM emp
WHERE (deptno,job) = (
SELECT deptno, job
FROM emp WHERE ename = ‘ALLEN’
)AND ename <> ‘ALLEN’;

表的自我复制(蠕虫复制)

目的:为了对某个 sql 语句进行效率测试,我们需要海量数据时,可以使用此法为表创建海量数据。

复制步骤

1、先把emp表的记录复制(迁移)到 my_tab01

【先查找数据,然后把查找的数据 列对列 的放入新的表中】

INSERT INTO my_tab01

(id, name, sal, job, deptno)
SELECT empno, ename, sal, job, deptno FROM emp;

2、自我复制
INSERT INTO my_tab01
SELECT * FROM my_tab01;

【提问】如何删除掉一张表中的重复记录?

1、先创建一张临时表 my_temp, 该表的结构和my_tab02一样。
CREATE TABLE my_temp LIKE my_tab02;

这个语句把my_tab02表的结构(列)等信息,不包含数据,复制到my_temp

2、把my_temp 的记录,通过distinct 关键字处理后,把记录复制到my_temp。
INSERT INTO my_temp SELECT DISTINCT * FROM my_tab02;

DISTINCT去重

3、清除掉 my_tab02 的所有记录。(不是删掉 表my_tab02 本身)
DELETE FROM my_tab02;
4、把my_temp表的记录复制到my_tab02。【可以把my_tab02删掉drop后,再把my_temp表改名为my_tab02】
– 改表名:rename old_name to new_name;
INSERT INTO my_tab02 SELECT * FROM my_temp;
5、drop掉 临时表my_temp。
DROP TABLE my_temp;

合并查询

目的

有时在实际应用中,为了合并多个select语句的结果,可以使用 集合操作符号 union,union all。

union all

– union all 就是将查询结果合并 (取并集),不会去重
SELECT ename,sal,job FROM emp WHERE sal>2500

UNION ALL
SELECT ename,sal,job FROM emp WHERE job=‘MANAGER’; – 8条记录

union

– union 该操作与union all相似,但是会“自动去掉”结果集合中的“重复行”。
SELECT ename,sal,job FROM emp WHERE sal>2500

UNION
SELECT ename,sal,job FROM emp WHERE job=‘MANAGER’; – 6条记录

表外链接

左外连接

如果左侧的表完全显示,我们就说是“左外连接”。即使左边的表和右边的表如果没有匹配的,那他也会把左边的表全部显示出来
基本语法
select … from 表1(左表) left join 表2(右表) on 条件;

右外连接

如果右侧的表完全显示,我们就说是“右外连接”
基本语法
select … from 表1(左表) right join 表2(右表) on 条件;

函数

合并/统计函数

count

返回行的总数
基本语法
select count(*) | count(列名)

from 表名
[where 条件语句] ;

count(*) 和 count(列) 的区别
count(*) – 返回满足条件的记录的行数。
count(列) – 统计满足条件的某列有多少个,但是会排除 为null的情况。

sum

基本语法
select sum(列名1) [, sum(列名2) ]

from 表名
[where 条件语句] ;

注意事项
1、sum()仅对 数值起作用。

2、对多列求和," , "号不能少。

举例
统计一个班级语文、英语、数学的成绩总和

SELECT SUM(math + english + chinese) FROM student;

avg

返回满足where条件的一列的平均值
基本语法
select avg(列名1) [, avg(列名2) ]

from 表名
[where 条件语句] ;

max/min

max():返回满足where条件的一列的 最大值

min():返回满足where条件的一列的 最小值

【举例】

求班级最高分和最低分(数值范围在统计中特别有用)
SELECT MAX(math + english + chinese), MIN(math + english + chinese)
FROM student;

group by

对列进行分组
基本语法
select 列名1, 列名2, 列名3, …

from 表名
group by 列名 ;

having

对分组后的结果进行过滤
基本语法
select 列名1, 列名2, 列名3, …

from 表名
group by 列名 having … ;

having一般与group by 连用

其中 group by用于对查询结果进行统计,
having 子句用于限制 分组显示结果。

字符串相关函数

charset (str)

返回字符串str的字符集

concat (string2 [, …])

连接字符串,将多个列拼接成一列

instr (string, substring)

返回 substring在string中出现的位置,没有的话,就返回0

ucase (string2)

转换成大写, 本身是大写的,还是大写。

lcase (string2)

转换成小写

left (string2, length)

从String2中的左边起,获取length个字符

right (string2, length)

从String2中的右边起,获取length个字符

length (string)

string的长度【按照字节】
SELECT LENGTH(‘韩顺平’) FROM DUAL ; # 9,按照字节返回,utf8编码一个汉字占3个字节。如果是字符的话,会返回3.

replace (str, search_str, repalce_str)

在str中用replace_str替换search_str

strcmp (string1, string2)

逐个字符比较2个字符串的大小(根据ascll码),看这两个string是否相等。
SELECT STRCMP(‘hanshunping’,‘hanxianchu’)FROM DUAL;返回-1,跟表本身是否区分大小写有关。

SELECT STRCMP(‘hanshunping’,‘hanshunping’)FROM DUAL;返回0。

substring (str, position [, length])

从str的position开始【从1开始计算】,取length个字符

ltrim (string2)

去除前端空格
SELECT LTRIM(’ 韩顺平教育’) FROM DUAL;

rtrim (string2)

去除后端空格
SELECT RTRIM('韩顺平教育 ') FROM DUAL;

trim (string2)

把左右两端的空格都去掉
SELECT TRIM(’ 韩顺平教育! ') FROM DUAL;

数学相关函数

abs (num)

绝对值

bin (decimal_number)

十进制转换成二进制

ceiling (number)

向上取整,得到比number2大的最小整数

conv (number2, from_base, to_base)

进制转换 convert:转换
SELECT CONV(8,10,2) FROM DUAL;

把数字8当做十进制来对待,让它转换成二进制。

floor (number2)

向下取整,得到小于number2的最大整数

format (number, decimal_places)

保留小数位数(四舍五入)
SELECT FORMAT(78.325386,2) FROM DUAL;

保留2位小数

hex (DecimalNumber)

转十六进制

least (number, number2 [, …])

求最小值

mod (numerator, denominator)

求余数

rand ([seed])

返回一个随机数,其范围是0 <= v <= 1.0

加入数字seed后,返回的随机数不再改变。每次更换seed的值,查询结果都会改变。
如果已经产生一个整数N,则它被用作种子值,用来产生重复序列。

时间日期相关函数

current_date ()

当前日期

current_time ()

当前时间

current_timestamp ()

当前时间戳
SELECT CURRENT_TIMESTAMP() FROM DUAL;
  • 返回结果:2022-06-19 20:49:24

date (datetime)

返回datetime的日期部分

date_add (date2, interval d_value d_type)

在date2上面加上日期/时间
SELECT *
FROM mes
WHERE DATE_ADD(sendtime,INTERVAL 10 MINUTE) >= NOW();

INTERVAL 时间间隔

date_sub (date2, interval d_value d_type)

在date2上减去一个时间

datediff (date1, date2)

两个日期差(单位是天,而且是date1-date2)
请在mysql的sql语句中求出2011-11-11与1990-1-1相差多少天?

SELECT DATEDIFF(‘2011-11-11’,‘1990-01-01’)/365 FROM DUAL;

timediff (date1, date2)

两个时间差(时分秒,而且是date1-date2)
SELECT TIMEDIFF(‘13:13:13’,‘10:10:10’) FROM DUAL;

now()

当前时间
SELECT NOW() FROM DUAL;

year (datetime)

返回datetime里的的年份
SELECT YEAR(NOW()) FROM DUAL;

month (datetime)

返回datetime里的的月份
SELECT MONTH(NOW()) FROM DUAL;

day (datetime)

返回datetime里的的天数
SELECT DAY(NOW()) FROM DUAL;

date(datetime)

返回datetime里的日期部分(年月日)
SELECT DATE(NOW()) FROM DUAL;

unix_timestamp()

返回的是从1970-1-1到现在的秒数,不是毫秒数。
SELECT UNIX_TIMESTAMP() FROM DUAL;

from_unixtime()

可以把一个unix_timestamp的秒数(时间戳),转成指定格式的日期。
%Y-$m-%d 表示:年月日,这是规定好的格式。

%Y-%m-%d %H:%i:%s 表示: 年月日时分秒(默认格式)

SELECT FROM_UNIXTIME(1655028638)FROM DUAL
SELECT FROM_UNIXTIME(1655028638,‘%Y-%m-%d’)FROM DUAL
SELECT FROM_UNIXTIME(1655028638,‘%Y-%m-%d %H:%i:%s’)FROM DUAL

# 意义:在开发中,我们可以把一个数值当做一个时间来记录,然后通过from_unixtime()方法来进行转换。

加密和系统函数

user ()

查询用户

database()

数据库名称

MD5(str)

为字符串str算出一个MD5 32的字符串,常用来(用户密码)加密
root的密码是:123456 -> md5加密 -> 在数据库中存放的是加密后的密码。

SELECT MD5(‘123456’) FROM DUAL;
SELECT LENGTH(MD5(‘123456’)) FROM DUAL; # 32位。

password (str)

加密函数。从原文密码str计算并返回密码字符串,通常用于连接对mysql数据库的用户密码加密。
SELECT PASSWORD(‘sdyu’) FROM DUAL;

在MySQL数据库的密码就是用这个函数加密的。

select * from mysql.user \G

mysql.user表示: 数据库.表 的含义。

SELECT * FROM mysql.user ;

这样不用切换数据库,就可以查询到其他数据库的表。

流程控制函数

if (expr1, expe2, expr3 )

如果expr1为true,则返回expr2的值,否则返回expr3的值。

ifnull(expr1, expr2)

如果expr1不为null,则返回expr1,否则返回expr2

select case

when expr1 then expr2
when expr3 then expr4
else expr5
end ;

– select case

– when expr1 then expr2 如果expr1为True,就返回expr2,然后结束。如果expr1为false,就执行下个when代码
– when expr3 then expr4 如果expr3为true,就返回expr4,然后结束。
– else expr5 如果expr3为false,就返回expr5,然后结束。
– end; 【感觉 类似于多重分支语句】

SELECT CASE
WHEN TRUE THEN 'jack'   -- jack
WHEN FALSE THEN 'tom'	-- 执行else语句,返回mary。
ELSE 'mary'		
END;
如果emp表的job是clerk,则显示 职员;如果是 manager,则显示 经理;如果是salesman,则显示 销售人员,其他的正常显示。

SELECT ename, (SELECT CASE
WHEN job = ‘CLERK’ THEN ‘职员’ – jack
WHEN job = ‘MANAGER’ THEN ‘经理’ – 执行else语句,返回mary。
WHEN job = ‘SALESMAN’ THEN ‘销售人员’
ELSE job
END
)AS ‘job’ FROM emp ;

索引

提高数据库的性能,加快查询速度(不用加内存,不用改程序,不用调sql)

原理

如果没有索引

会进行全表扫描。因为找到一个结果后,不确定在表的其他位置是否还有符合条件的结果。所以要全表扫描,这样一来会浪费很多时间。

如果有索引

会形成一个索引的数据结构,例如二叉树索引,B+树索引等。查询效率会增加。

类型

主键索引:主键自动的为主索引,类型 primary key

唯一索引:类型unique

普通索引:index

全文索引:fulltext,适用于MyISAM

一般开发不适用mysql自带的全文索引,而是使用:全文搜索 Solr 和 ElasticSearch(ES)

使用

1、查询表是否有索引

show indexses from 表名 ;

2、添加索引

基本语法
【法一】
  • create [unique] index 索引名称 on 表名(列名[(length)]) [asc|desc],…) ;
【法二】
  • alter table 表名 add index [索引名] (表的列名) ;
添加唯一索引
create unique index 索引名称 on 表名 (列名) ;
添加普通索引
create index 索引名 on 表名(列名) ;
alter table 表名 add index 索引名(表的列名) ;
如何选择 ?
如果某一列的值是不会重复的,则优先考虑使用unique索引,否则使用普通索引。
添加主键索引
在使用 create创建完表后,使用

alter table 表名 add primary key(表的列名) ;

3、删除索引

删除索引
drop index 索引名 on 表名 ;
删除主键索引(比较特别)
alter table 表名 drop primary key ;

4、修改索引

先删除 原索引,然后添加 新的索引。

5、查询索引

【方式1】 show index from 表名 ;
【方式2】show indexes from 表名 ;
【方式3】show keys from 表名 ;
【方式4】desc 表名 ;

小结

【哪些列上适合使用索引 ?】

1、较频繁的作为查询条件的字段,应该创建索引。
2、唯一性太差的字段不适合单独创建索引,即使频繁作为查询条件。(例如:男女性别)
3、更新非常频繁的字段,不适合创建索引。(例如:用户登陆次数 会频繁改变)
4、不会出现在“where子句”中的字段不该创建索引。

事务

什么是“事务”?

事务用于保证数据的一致性,由一组相关的dml语句组成,该组的dml语句要么全部成功,要么全部失败。(例如:转账要用事务来处理,用以保证数据的一致性)

事务和锁

在执行事务操作时(dml语句),mysql语句会在表上加锁,防止其他用户更改表的数据。这对于用户来讲十分重要。

mysql控制台事务的几个重要操作

start transaction 开始一个事务
savepoint 保存点名,设置保存点
rollback to 保存点名,回滚事务至某一个保存点
rollback 回滚全部事务至事务开始时的样子
cmmit 提交事务,同时也会删除从 start transaction 开始的所有保存点,所有的操作生效,不能回退。

回退事务 rollback

执行回退事务时,,通过指定保存点可以回退到指定的点。

提交事务 commit

使用commit语句可以提交事务。当执行了commit语句后,会确认事务的变化、结束事务、删除该事务定义的所有保存点、释放锁、数据生效。当使用 commit语句结束事务后,其他会话(其他连接)可以查看到 事务变化后的新数据 。【所有数据就正式生效】

事务细节讨论

1、如果不开始事务,默认情况下,dml操作是自动提交的,不能回滚。

2、如果开始一个事务,而我们又没有创建保存点,可以执行 rollback ,默认退回到该事务开始时的状态。
3、当事务还没有提交时,可以在事务中创建多个保存点。
(比如:savepoint aaa ; 执行dml,savepoint bbb ;)
4、可以在事务没有提交前,选择退回到哪个保存点。
5、mysql 的事务机制需要 innodb 的存储引擎 才可以使用,MyISAM 不好使。
6、开启一个事务有2种方式
(1)start transaction
(2)set autocommit=off

事务的隔离级别

多个连接开启各自事务操作数据库中的数据时,数据库系统要负责隔离操作,以保证各个连接在获取数据时的准确性。

如果不考虑隔离性,可能会引发:脏读、不可重复读、幻读 3种问题。

脏读(dirty read)

当一个事物读取到另外一个事务“尚未提交的改变(update,insert,delete)”时,产生脏读。

不可重复读(nonrepeatable read)

同一查询在同一事物中多次进行,由于“其他提交事物所做的 修改 和 删除”,每次都会返回不同的结果集,此时发生不可重复读。

幻读(phantom read)

同一查询在同一事物中多次进行,由于“其他提交事务所做的 插入 ”操作,每次返回不同的结果集,此时发生幻读。

事务的隔离级别

MySQL的隔离级别定义了“事务与事务之间的隔离程度”。

设置事务的隔离级别

1、查看当前会话的隔离级别(指某一个用户的)
   SELECT @@tx_isolation ;
2、查看系统当前的隔离级别(即:所有用户登陆时的隔离级别)
  SELECT @@global.tx_isolation ;
3、设置当前会话的隔离级别
 SET SESSION TRANSACTION ISOLATION LEVEL READ UNCOMMITTED ;

READ UNCOMMITTED 是4个隔离级别之一

4、设置系统的当前隔离级别
   SET GLOBAL TRANSACTION ISOLATION LEVEL [你设置的级别] ;
– mysql默认的事务隔离界别是 repeatable read, 一般情况下,没有特殊的要求,没有必要修改

– (因为该级别可以满足绝大部分项目的需求)

事务的ACID

1、原子性(Atomicity)

事务是一个不可分割的工作单位,事务中的操作要么都发生,要么都不发生。

2、一致性(Consistency)
事务必须使数据库从一个一致性状态转变为另一个一致性状态。
(事务一旦提交了,就会进行一个整体性的改变。这样事务就结束,然后就再开启一个新的事务)

3、隔离性(Isolation)
多个用户并发访问数据库时,数据库为每一个用户开启的事务,不能被其他事务的 操作数据所干扰,多个并发事务之间一定要相互隔离。

4、持久性(Durability)
一个事务一旦被提交,它对数据库中数据的改变就是永久性的,接下来即使数据库发生故障,也不会对其有任何影响。

视图

什么是视图 ?什么是基表 ?

视图是一个虚拟表,其内容由查询定义。同真实的表一样,视图包含列,其数据来自对应的真实表(基表)。

视图与基表的关系

【对视图的总结】

1、视图是根据基表(可以是多个基表)来创建的,视图是虚拟的表。
2、视图也有列,数据来自基表
3、通过视图可以修改基表的数据
4、基表的改变,也会影响到视图的数据。

“视图”与“基表” 之间的是 “映射关系”,一个视图 可以对应 多个基表。

视图的基本使用

基本语法

1、create view 视图名 as select 语句

2、alter view 视图名 as select 语句
3、show view 视图名 as select 语句
4、drop view 视图名1, 视图名2

select语句是 根据 基表 来进行选择。

举例

使用细节

1、创建视图后,到数据库去看,对应视图只有一个视图结构文件。(文件形式:视图名.frm)

2、视图的数据变化会影响到基表,基表的数据变化也会影响到视图(insert update delete)

3、视图中可以再使用视图,数据仍来自于基表。

举例

视图的最佳实践

mysql管理

mysql用户

使用原因:

当我们做项目开发是时,可以根据不同的开发人员,赋给他相应的mysql操作权限
所以MySQL数据库管理人员根据需要创建不同的用户,赋给相应的权限,供人员使用。

mysql中的用户,都存储在 系统数据库mysql里的user表中。

创建用户,同时指定密码

create user ‘用户名’ @‘允许登陆位置’ identified by ‘密码’ ;

删除用户

drop user ‘用户名’ @‘允许登陆位置’ ;

用户修改密码

修改自己的密码

set password = password(‘新密码’) ;

修改他人的密码(需要有修改他人密码的权限)

set password for ‘用户名’@‘登录位置’ = password(‘密码’) ;

登录

不同的数据库用户,登录到DBMS后,根据相应的权限,可以操作的数据库和数据对象(表、视图、触发器)不一样

mysql中的权限

给用户授权

基本语法

grant 权限列表 on 库.对象名 to ‘用户名’@‘登录位置’ [identified by ‘密码’] ;

说明

1、权限列表,多个权限用逗号分隔开

grant select on …
grant select, delete, create on …
grant all [privileges] on … //表示赋予该用户在该对象上的所有权限。

2、特别说明

. :代表本系统中的所有数据库的所有对象(表、视图、存储过程等)
库.* :表示某个数据库中的所有数据对象(表、视图、存储过程等)

3、identified by 可以省略,也可以写出

(1)如果用户存在,就是修改用户的密码
(2)如果该用户不存在,就是创建该用户!

回收用户授权

基本语法

revoke 权限列表 on 库.对象名 from ‘用户名’@‘登录位置’ ;

举例

权限生效指令

如果权限没有生效,就执行下面的指令:

【基础语法】
flush privileges ;

细节说明

1、在创建用户时,如果不指定主机Host,则为 % 。

% 表示所有的IP都有连接权限。
create user xxx ;

2、也可以这样指定

create user ‘xxx’@‘192.168.1.%’ ; —— 表示 xxx用户在192.168.1.*的ip可以登录mysql

3、在删除数据库的时候,如果host 不是 %,就需要明确指定 ‘用户’@‘host值’

CREATE TABLE customer(

     customer_id CHAR(8) PRIMARY KEY, -- 程序员自己决定
     `name` VARCHAR(64) NOT NULL DEFAULT '', 
     address VARCHAR(64) NOT NULL DEFAULT '', 
     email VARCHAR(64) UNIQUE NOT NULL, 
     sex ENUM('男','女') NOT NULL , -- 这里使用的枚举类型, 是生效
     card_Id CHAR(18)

);

  • 1
    点赞
  • 2
    收藏
  • 打赏
    打赏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:书香水墨 设计师:CSDN官方博客 返回首页
评论 1

打赏作者

xueshengliang1998

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值