目录
- 一、认识MySQL数据库
- 二、win10安装MySQL和图形工具
- 三、Mac系统安装MySQL数据库
- 四、MySQL基本操作命令
- 五、MySQL中的数据类型
- 六、MySQL中的类型约束和运算
- 七、MySQL数据表操作详解
- 八、MySQL数据库中的表引擎
- 九、MySQL中的字符集utf8
- 十、MySQL中的DML操作-数据的增删改
- 十一、MySQL查询
- 十二、MySQL数据库数据的导入导出
- 十三、MySQL数据库权限管理
一、认识MySQL数据库
1.1 什么是数据库
数据库(Database)就是按照数据结构来组织,存储和管理数据的仓库
专业的数据库是专门对数据进行创建,访问,管理,搜索等操作的软件,比起我们自己用文件读写的方 式对象数据进行管理更加的方便,快速,安全
1.2 作用
- 对数据进行持久化的保存
- 方便数据的存储和查询,速度快,安全,方便
- 可以处理并发访问
- 更加安全的权限管理访问机制
1.3 常见的数据库
数据库分两大类,一类是 关系型数据库。另一类叫做 非关系型数据库。
- 关系型数据库: MySQL(已被Oracle收购),Oracle,PostgreSQL,SQLserver。。。。
- 非关系型数据库:Redis内存数据库,MongoDB文档数据库。。。
1.4 MySQL概述
数据库:
表
1.5 MySQL基本操作
进入MySQL并切换数据库
查看表
查看表结构
二、win10安装MySQL和图形工具
2.1 安装MySQL
Windows安装MySQL5.7.17
1)在MySQL官网 http://dev.mysql.com/downloads/mysql/ 上面下载ZIP安装包(第二个:Windows (x86, 64- bit), ZIP Archive)。
2)下载完成后解压,将其放到想要安装的目录下。 例如:D:\MySQL5.7\mysql-5.7.17-winx64
3)新建一个my.ini配置文件,原始的my-default.ini配置文件只是个模版,不要在里面改动
my.ini的内容如下: (!!!注意basedir、datadir的值需要根据MySQL的目录具体设定)
[mysql]
default-character-set=utf8
[mysqld]
port = 3306
basedir=D:\MySQL5.7\mysql-5.7.17-winx64
datadir=D:\MySQL5.7\mysql-5.7.17-winx64\data
max_connections=200
character-set-server=utf8
default-storage-engine=INNODB
explicit_defaults_for_timestamp=true
4)在安装路径下新建一个空的data文件夹。
5)以管理员身份运行cmd,进入bin目录,执行 mysqld --initialize-insecure --user=mysql 命令。不进行这一步,安装完成之后无法启动服务。
6)依然在管理员cmd窗口的bin目录下,执行 mysqld install 命令安装。完成后会提示安装成功。
7)依然在管理员cmd窗口的bin目录下,执行 net start mysql 命令启动MySQL服务。
8)修改环境变量,添加"D:\MySQL5.7\mysql-5.7.17-winx64\bin"。 (这样就可以在任意目录下使用MySQL)
9)在普通cmd窗口中,进入bin目录,执行 mysql -u root -p 命令,默认没有密码,回车进入。
2.2 安装navicate
三、Mac系统安装MySQL数据库
3.1 方法一:官网下载安装包安装
3.2 方法二:使⽤Mac中的Homebrew进⾏mysql的安装
1.下载安装mysql
安装成功后界面
2,配置重启mysql
3.3 更换国内镜像源地址
卸载MySQL
3.4 卸载MySQL
四、MySQL基本操作命令
4.1 简单介绍
使用方法:
- 方式一: 通过在命令行敲命令来操作 ( 有助于命令的掌握)
- 方式二: 通过图型界面工具,如 Navicat 等(在熟练掌握后再使用)
- 方式三:通过编程语言(python,php,java,go…)执行mysql命令
SQL ( Structure query language ) 结构化查询语言
- SQL语言分为4个部分:DDL(定义)、DML(操作)、DQL(查询)、DCL(控制)
SQL语句中的快捷键
- \G 格式化输出(文本式,竖立显示)
- \s 查看服务器端信息
- \c 结束命令输入操作
- \q 退出当前sql命令行模式
- \h 查看帮助
4.2 操作数据库步骤
1)通过命令行连接MySQL
2) SQL 语句可以换行, 要以分号结尾
3)命令不区分大小写. 关键字和函数建议用大写
4)如果提示符为 '> 那么需要输入一个’回车
5)命令打错了换行后不能修改, 可以用 \c 取消
4.3 数据库操作
查看数据库 show databases;
创建数据库 create database 库名 default charset=utf8;
删除数据库 drop database 库名;
打开数据库 use 库名;
4.4 数据表操作
数据库管理系统中, 可以有很多库, 每个数据库中可以包括多张数据表
查看表: show tables;
创建表: create table 表名(字段名1 类型,字段名2 类型)engine=innodb default charset=utf8;
创建表: 如果表不存在,则创建, 如果存在就不执行这条命令
create table if not exists 表名(字段1 类型,字段2 类型);
create table if not exists users(
id int not null primary key auto_increment,
name varchar(4) not null,
age tinyint,
sex enum('男','女')
)engine=innodb default charset=utf8;
删除表: drop table 表名;
表结构: desc 表名;
查看建表语句:show create table users;
4.5 数据操作 增删查改
插入
- insert into 表名(字段1,字段2,字段3) values(值1,值2,值3);
- insert into 表名(字段1,字段2,字段3) values(a值1,a值2,a值3),(b值1,b值2,b值3);
查询
- select * from 表名;
- select 字段1,字段2,字段3 from 表名;
- select * from 表名 where 字段=某个值;
修改
- update 表名 set 字段=某个值 where 条件;
- update 表名 set 字段1=值1,字段2=值2 where 条件;
- update 表名 set 字段=字段+值 where 条件;
删除
- delete from 表名 where 字段=某个值;
五、MySQL中的数据类型
数据类型是定义列中可以存储什么类型的数据以及该数据实际怎样存储的基本规则
数据类型限制存储在数据列列中的数据。例如,数值数据类型列只能接受数值类型的的数据
在设计表时,应该特别重视所用的数据类型。使用错误的数据类型可能会严重地影响应用程序的功能和性能。
更改包含数据的列不是一件小事(而且这样做可能会导致数据丢失)。
数据类型:整型、浮点型、字符串、日期等
5.1 字符串数据类型
最常用的数据类型是串数据类型。它们存储串,如名字、地址、电话号码、邮政编码等。
不管使用何种形式的串数据类型,串值都必须括在引号内
有两种基本的串类型,分别为定长串和变长串
5.1.1 定长串:char
接受长度固定的字符串,其长度是在创建表时指定的。 定长列不允许存储多于指定长度字符的数据。
指定长度后,就会分配固定的存储空间用于存放数据
char(7) 不管实际插入多少字符,它都会占用7个字符位置
5.1.2 变长串:varchar
存储可变长度的字符串 varchar(7) 如果实际插入4个字符, 那么它只占4个字符位置,当然插入的数据长度不能超过7 个字符
既然变长数据类型这样灵活,为什么还要使用定长数据类型?
回答:因为性能,MySQL处理定长列远比处理变长列快得多。
5.1.3 Text 变长文本类型存储
5.2 数值类型
数值数据类型存储数值。MySQL支持多种数值数据类型,每种存储的数值具有不同的取值范围。支持的取值范围越 大,所需存储空间越多
与字符串不一样,数值不应该括在引号内
decimal(5, 2) 表示数值总共5位, 小数占2位
tinyint 1字节(8位) 无符号0-255。有符号-128-127
int 4字节。0-42亿 , -21亿,21亿。
MySQL中没有专门存储货币的数据类型,一般情况下使用DECIMAL(8, 2)
5.2.1 无符号与有符号数
所有数值数据类型(除BIT和BOOLEAN外)都可以有符号或无符号
有符号数值列可以存储正或负的数值
无符号数值列只能存储正数。
默认情况为有符号,但如果你知道自己不需要存储负值,可以使用UNSIGNED关键字
5.3 日期和时间类型
MySQL使用专门的数据类型来存储日期和时间值
5.4 二进制数据类型(不常用)
二进制数据类型可存储任何数据(甚至包括二进制信息),如图像、多媒体、字处理文档等
六、MySQL中的类型约束和运算
6.1 字段约束
1)unsigned 无符号(给数值类型使用,表示为正数,不写可以表示正负数都可以)
2)字段类型后面加括号限制宽度
- char(5). varchar(7) 在字符类型后面加限制 表示 字符串的长度
- int(4) 没有意义,默认无符号的int为int(11),有符号的int(10)
- int(4) unsigned zerofill只有当给int类型设置有前导零时,设置int的宽度才有意义。
3)not null 不能为空,在操作数据库时如果输入该字段的数据为NULL ,就会报错
4)default 设置默认值
5)primary key 主键不能为空,且唯一.一般和自动递增一起配合使用。
6)auto_increment 定义列为自增属性,一般用于主键,数值会自动加1
7)unique 唯一索引(数据不能重复:用户名)可以增加查询速度,但是会降低插入和更新速度
6.2 主键
1)表中每一行都应该有可以唯一标识自己的一列,用于记录两条记录不能重复,任意两行都不具有相同的主键值
2)应该总是定义主键 虽然并不总是都需要主键,但大多数数据库设计人员都应保证他们创建的每个表具有一个主键,以便于以后的数据操纵和管理。
要求
- 记录一旦插入到表中,主键最好不要再修改
- 不允许NULL
- 不在主键列中使用可能会更改的值。 (例如,如果使用一个名字作为主键以标识某个供应商,当该供应商合并和更改其名字时,必须更改这个主键。)
- 自增整数类型:数据库会在插入数据时自动为每一条记录分配一个自增整数,这样我们就完全不用担心主键 重复,也不用自己预先生成主键
- 可以使用多个列作为联合主键,但联合主键并不常用。使用多列作为主键时,所有列值的组合必须是唯一的
6.3 MySQL运算符
MySQL的运算符
- 算术运算符: +、 -、 *、 /、 %
- 比较运算符: =、 >、 <、 >=、 <=、!=
- 数据库特有的比较: in、not in、is null、is not null、like、between、and
- 逻辑运算符: and、or、not
- like: 支持特殊符号%和_ ;
其中%表示任意数量的任意字符,_表示任意一位字符
七、MySQL数据表操作详解
7.1 数据库操作
7.1.1 创建数据库
# 链接mysql数据库后,进入mysql后可以操作数据
# 1. 创建库
create database if not exists tlxy default charset=utf8;
# 1. 数据库 tlxy 如果不存在则创建数据库,存在则不创建
# 2. 创建 tlxy 数据库,并设置字符集为utf8
# 3. 无特殊情况都要求字符集为utf8或者utf8mb4的字符编码
7.1.2 查看所有库
# 1. 查看所有库
show databases;
7.1.3 打开库/进入库/选择库
# use 库名
use tlxy
7.1.4 删除库
删库有风险,动手需谨慎。
# 删除库,那么库中的所有数据都将在磁盘中删除。
drop database 库名
7.2 数据表操作
7.2.1 创建表
语法格式:
create table 表名(字段名,类型,【字段约束】,。。。);
实例:
# 以下创建一个 users 的表
create table users(
# 创建ID字段,为正整数,不允许为空 主键,自动递增
id int unsigned not null primary key auto_increment,
# 创建 存储 名字的字段,为字符串类型,最大长度 5个字符,不允许为空
username varchar(5) not null,
# 创建存储 密码 的字段,固定长度 32位字符, 不允许为空
# 数据库在存储用户密码时通常存储的是加密后的密码 使用md5加密算法后 密码均为32位 所以这里固定长度为32
password char(32) not null,
# 创建 年龄 字段,不允许为空,默认值为 20
age tinyint not null default 20
)engine=innodb default charset=utf8;
# 查看表结构
desc users;
#查看建表语句
show create table users;
查看表结构
可以通过展示建表语句,复制,运行,来重建相同的数据库
创建表的基本原则:
- 表名和字段名 尽可能的符合命名规范,并且最好能够‘见名之意’
- 表中数据必须有唯一标示,即主键定义。无特殊情况,主键都为数字并自增即可
- 表中字段所对应的类型设置合理,并限制合理长度
- 表引擎推荐使用innodb,并无特殊情况都要求为utf8或者utf8mb4的字符编码
7.2.2 修改表结构
语法格式:alter table 表名 action (更改的选项)
添加字段
# 语法:alter table 表名 add 添加的字段信息
# 在 users 表中 追加 一个 num 字段
alter table users add num int not null;
# 在指定字段后面追加字段 在 users 表中 age字段后面 添加一个 email 字段
# 由于数据一开始没有email字段 添加后会设置默认值 空字符串
alter table users add email varchar(50) after age;
# 在指定字段后面追加字段,在 users 表中 age字段后面 添加一个 phone
alter table users add phone char(11) not null after age;
# 在表的最前面添加一个字段
alter table users add aa int first;
删除字段
# 删除字段 alter table 表名 drop 被删除的字段名
alter table users drop aa;
修改字段
语法格式: alter table 表名 change|modify 被修改的字段信息
- change: 可以修改字段名,
- modify: 不能修改字段名。
# 修改表中的 num 字段 类型,使用 modify 不修改表名
alter table users modify num tinyint not null default 12;
# 修改表中的 num 字段 为 int并且字段名为 nn
alter table users change num nn int;
举例:修改字段类型
修改字段类型后
# 注意:一般情况下,无特殊要求,不要轻易修改表结构
7.2.3 修改表名
语法:alter table 原表名 rename as 新表名
7.2.4 更改表中自增的值
# 在常规情况下,auto_increment 默认从1开始继续递增
alter table users auto_increment = 1000;
7.2.5 修改表引擎
# 推荐在定义表时,表引擎为 innodb。
# 通过查看建表语句获取当前的表引擎
mysql> show create table users\G;
*************************** 1. row ***************************
Table: users
Create Table: CREATE TABLE `users` (
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=1001 DEFAULT CHARSET=utf8
1 row in set (0.00 sec)
# 直接查看当前表状态信息
mysql> show table status from tlxy where name = 'users'\G;
*************************** 1. row ***************************
Name: users
Engine: InnoDB
# 修改表引擎语句
alter table users engine = 'myisam';
7.2.6 删除表
drop table 表名
八、MySQL数据库中的表引擎
8.1 服务器处理客户端请求
其实不论客户端进程和服务器进程是采用哪种方式进行通信,最后实现的效果都是:
客户端进程向服务器进程发送 一段文本(MySQL语句),服务器进程处理后再向客户端进程发送一段文本(处理结果)。
那服务器进程对客户 端进程发送的请求做了什么处理,才能产生最后的处理结果呢?
客户端可以向服务器发送增删改查各类请求,我们 这里以比较复杂的查询请求为例来画个图展示一下大致的过程:
虽然查询缓存有时可以提升系统性能,但也不得不因维护这块缓存而造成一些开销,比如每次都要去查询缓存中检索,查询请求处理完需要更新查询缓存,维护该查询缓存对应的内存区域。
从MySQL 5.7.20开始,不推荐使用查询缓存,并在MySQL 8.0中删除。
8.2 存储引擎
MySQL 服务器把数据的存储和提取操作都封装到了一个叫 存储引擎 的模块里。
- 我们知道 表 是由一行一行的记录 组成的,但这只是一个逻辑上的概念,物理上如何表示记录,怎么从表中读取数据,怎么把数据写入具体的物理存储器上,这都是 存储引擎 负责的事情。
- 为了实现不同的功能, MySQL 提供了各式各样的 存储引擎 ,不同存储引擎管理的表具体的存储结构可能不同,采用的存取算法也可能不同。
存储引擎以前叫做 表处理器 ,它的功能就是接收上层传下来的指令,然后对表中的数据进行提取或写入操 作。 - 为了管理方便,人们把 连接管理 、 查询缓存 、 语法解析 、 查询优化 这些并不涉及真实数据存储的功能划分为 MySQL server 的功能,把真实存取数据的功能划分为 存储引擎 的功能。
各种不同的存储引擎向上边的 MySQL server 层提供统一的调用接口(也就是存储引擎API),包含了几十个底层函数,像"读取索引第一条内容"、“读取 索引下一条内容”、"插入记录"等等。
所以在 MySQL server 完成了查询优化后,只需按照生成的执行计划调用底层存储引擎提供的API,获取到数据后返回给客户端就好了。
MySQL 支持非常多种存储引擎:
8.3 MyISAM和InnoDB表引擎的区别
九、MySQL中的字符集utf8
9.1 字符集简介
我们知道在计算机中只能存储二进制数据,那该怎么存储字符串呢?当然是建立字符与二进制数据的映射关系了, 建立这个关系最起码要搞清楚两件事儿:
1.你要把哪些字符映射成二进制数据?
也就是界定清楚字符范围。
2.怎么映射?
将一个字符映射成一个二进制数据的过程也叫做 编码 ,将一个二进制数据映射到一个字符的过程叫做 解 码 。
人们抽象出一个 字符集 的概念来描述某个字符范围的编码规则
我们看一下一些常用字符集的情况:
ASCII 字符集
共收录128个字符,包括空格、标点符号、数字、大小写字母和一些不可见字符。由于总共才128个字符,所 以可以使用1个字节来进行编码,我们看一些字符的编码方式:
‘L’ -> 01001100(十六进制:0x4C,十进制:76)
‘M’ -> 01001101(十六进制:0x4D,十进制:77)
ISO 8859-1 字符集
共收录256个字符,是在 ASCII 字符集的基础上又扩充了128个西欧常用字符(包括德法两国的字母),也可以 使用1个字节来进行编码。这个字符集也有一个别名 latin1
GB2312 字符集
收录了汉字以及拉丁字母、希腊字母、日文平假名及片假名字母、俄语西里尔字母。其中收录汉字6763个, 其他文字符号682个。同时这种字符集又兼容 ASCII 字符集,所以在编码方式上显得有些奇怪:
- 如果该字符在 ASCII 字符集中,则采用1字节编码。
- 否则采用2字节编码。
这种表示一个字符需要的字节数可能不同的编码方式称为 变长编码方式 。比方说字符串 ‘爱u’ ,其 中 ‘爱’ 需要用2个字节进行编码,编码后的十六进制表示为 0xCED2 , ‘u’ 需要用1个字节进行编码,编码后 的十六进制表示为 0x75 ,所以拼合起来就是 0xCED275 。
小贴士: 我们怎么区分某个字节代表一个单独的字符还是代表某个字符的一部分呢?别忘了 ASCII 字 符集只收录128个字符,使用0~127就可以表示全部字符,所以如果某个字节是在0~127之内的,就意 味着一个字节代表一个单独的字符,否则就是两个字节代表一个单独的字符。
GBK 字符集
GBK 字符集只是在收录字符范围上对 GB2312 字符集作了扩充,编码方式上兼容 GB2312 。
Unicode 字符集
收录地球上能想到的所有字符,而且还在不断扩充。这种字符集兼容 ASCII 字符集,采用变长编码方式,编 码一个字符需要使用1~4个字节,比方说这样
‘L’ -> 01001100(十六进制:0x4C)
‘啊’ -> 111001011001010110001010(十六进制:0xE5958A)
小贴士: 其实准确的说,utf8只是Unicode字符集的一种编码方案,Unicode字符集可以采用utf8、 utf16、utf32这几种编码方案,utf8使用1~4个字节编码一个字符,utf16使用2个或4个字节编码一个 字符,utf32使用4个字节编码一个字符。更详细的Unicode和其编码方案的知识不是本书的重点,大家 上网查查哈~ MySQL中并不区分字符集和编码方案的概念,所以后边唠叨的时候把utf8、utf16、utf32 都当作一种字符集对待。
9.2 MySQL中的utf8和utf8mb4
我们上边说 utf8 字符集表示一个字符需要使用1~4个字节,但是我们常用的一些字符使用1~3个字节就可以表示 了。而在 MySQL 中字符集表示一个字符所用最大字节长度在某些方面会影响系统的存储和性能,所以设计 MySQL 的大叔偷偷的定义了两个概念:
- utf8mb3 :阉割过的 utf8 字符集,只使用1~3个字节表示字符。
- utf8mb4 :正宗的 utf8 字符集,使用1~4个字节表示字符。
有一点需要大家十分的注意,在 MySQL 中 utf8 是 utf8mb3 的别名,所以之后在 MySQL 中提到 utf8 就意味着使用 1~3个字节来表示一个字符,如果大家有使用4字节编码一个字符的情况,比如存储一些emoji表情啥的,那请使 用 utf8mb4 。
9.3 字符集查看
MySQL 支持好多好多种字符集,查看当前 MySQL 中支持的字符集可以用下边这个语句:
show charset;
十、MySQL中的DML操作-数据的增删改
10.1 添加数据
格式: insert into 表名[(字段列表)] values(值列表…);
--标准添加(指定所有字段,给定所有的值)
mysql> insert into stu(id,name,age,sex,classid) values(1,'zhangsan',20,'m','lamp138');
Query OK, 1 row affected (0.13 sec)
--指定部分字段添加值 (前提是其余字段允许不先给出)
mysql> insert into stu(name,classid) value('lisi','lamp138');
Query OK, 1 row affected (0.11 sec)
-- 不指定字段添加值
mysql> insert into stu value(null,'wangwu',21,'w','lamp138');
Query OK, 1 row affected (0.22 sec)
-- 批量添加值
mysql> insert into stu values
-> (null,'zhaoliu',25,'w','lamp94'),
-> (null,'uu01',26,'m','lamp94'),
-> (null,'uu02',28,'w','lamp92'),
-> (null,'qq02',24,'m','lamp92'),
-> (null,'uu03',32,'m','lamp138'),
-> (null,'qq03',23,'w','lamp94'),
-> (null,'aa',19,'m','lamp138');
Query OK, 7 rows affected (0.27 sec)
Records: 7 Duplicates: 0 Warnings: 0
10.2 修改数据
格式:update 表名 set 字段1=值1,字段2=值2,字段n=值n… where 条件
-- 将id为11的age改为35,sex改为m值
mysql> update stu set age=35,sex='m' where id=11;
Query OK, 1 row affected (0.16 sec)
Rows matched: 1 Changed: 1 Warnings: 0
-- 将id值为12和14的数据值sex改为m,classid改为lamp92
mysql> update stu set sex='m',classid='lamp92' where id=12 or id=14 --等价于下面
mysql> update stu set sex='m',classid='lamp92' where id in(12,14);
Query OK, 2 rows affected (0.09 sec)
Rows matched: 2 Changed: 2 Warnings: 0
10.3 删除数据
格式:delete from 表名 [where 条件]
-- 删除stu表中id值为100的数据
mysql> delete from stu where id=100;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值为20到30的数据
mysql> delete from stu where id>=20 and id<=30;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值为20到30的数据(等级于上面写法)
mysql> delete from stu where id between 20 and 30;
Query OK, 0 rows affected (0.00 sec)
-- 删除stu表中id值大于200的数据
mysql> delete from stu where id>200;
Query OK, 0 rows affected (0.00 sec)
十一、MySQL查询
使用图形界面创建表示例
1,选择数据库
2,添加字段、设置主键、属性、是否自动递增
3,修改数据库引擎、字符集、排序规则
4,插入数据
5,查看建表、插入数据操作对应的SQL语句
6,查看对应的SQL语句
使用数据库语句创建表示例
/*
Navicat Premium Data Transfer
Source Server : localhost_3306
Source Server Type : MySQL
Source Server Version : 80017
Source Host : localhost:3306
Source Schema : test
Target Server Type : MySQL
Target Server Version : 80017
File Encoding : 65001
Date: 14/01/2021 11:14:36
*/
SET NAMES utf8mb4;
SET FOREIGN_KEY_CHECKS = 0;
-- ----------------------------
-- Table structure for stu
-- ----------------------------
DROP TABLE IF EXISTS `stu`;
CREATE TABLE `stu` (
`id` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
`name` varchar(10) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`email` char(50) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`phone` char(11) CHARACTER SET utf8 COLLATE utf8_general_ci NOT NULL,
`age` tinyint(4) NOT NULL,
`sex` char(1) CHARACTER SET utf8 COLLATE utf8_general_ci NULL DEFAULT NULL,
`class_id` int(10) NULL DEFAULT NULL,
PRIMARY KEY (`id`) USING BTREE
) ENGINE = MyISAM AUTO_INCREMENT = 2 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
-- ----------------------------
-- Records of stu
-- ----------------------------
INSERT INTO `stu` VALUES (1, '张三', 'zhangsan@qq.com', '13781104321', 21, '男', 1);
INSERT INTO `stu` VALUES (null, '李四', 'lisi@qq.com', '13701104322', 22, '男', 1);
INSERT INTO `stu` VALUES (null, '王五', 'wangwu@qq.com', '13701104323', 20, '女', 1);
INSERT INTO `stu` VALUES (null, '赵六', 'zhaoliu@qq.com', '13701104324', 19, '男', 1);
INSERT INTO `stu` VALUES (null, '田七', 'tianqi@qq.com' , '13701104325', 23, '女', 1);
INSERT INTO `stu` VALUES (null, '王六', 'wangwuliu@qq.com', '13701184326', 23, '女', 1);
INSERT INTO `stu` VALUES (null, '熊大', 'xiongda@qq.com', '13701104327', 25, '男', 2);
INSERT INTO `stu` VALUES (null, '照二', 'xiongereqq.com', '13701104328', 22, '男', 2);
INSERT INTO `stu` VALUES (null, '——', 'yiyi@qq. com', '13701104329', 19, '女', 2);
INSERT INTO `stu` VALUES (null, '岈呀', 'yaya@qq.com', '13701104320', 22, '男', 2);
SET FOREIGN_KEY_CHECKS = 1;
注:通过运行sql文件可以正常建立表、并插入数据。
但通过命令行插入时,会报错,应该是哪里的字符编码设置有问题
可以通过修改my.ini解决问题,参考链接@睡前来杯海飞丝【ERROR 1366 (HY000): Incorrect string value: ‘\xD5\xC5\xD0\xA1\xC3\xF7’ for column ‘NAME’ at row 1解决方】
11.1 检索数据select
11.1.1 检索单个列
select name from stu;
- 如果没有明确排序查询结果(下一 章介绍),则返回的数据的顺序没有特殊意义。
- 返回数据的顺序可能是数据被添加到表中的顺序,也可能不是。只要返回相同数目的行,就是正常的
11.1.2 检索多个列
select name,id,phone from stu;
- 在选择多个列时,一定要在列名之间加上逗号,但最后一个列名后不加。
- 如果在最后一个列名后加了逗号,将出现错误。
11.1.3 检索所有列
select * from stu;
- 使用通配符一般,除非你确实需要表中的每个列,否则最好别使用*通配符。
- 虽然使用通配符可能会省事,不用明确列出所需列,但检索不需要的列通常会降低检索和应用程序的性能。
- 使用通配符有一个大优点。由于不明确指定列名(因为星号检索每个列),所以能检索出名字未知的列。
11.1.4 检索有多少不同的行DISTINCT
select distinct class_id from stu;
- DISTINCT关键字,顾名思义,此关键字指示MySQL只返回不同的值(可以用来去重)
- DISTINCT关键字应用于所有列而不仅是前置它的列。
- 如果给出SELECT DISTINCT vend_id, prod_price, 除非指定的两个列都不同,否则所有行都将被检索出来
11.1.5 限制结果LIMIT
select * from stu limit 3,4;
- 如果数据量到达千万级别,一次select * 很可能会使服务器宕机,这时就需要使用limit控制一次取出的数据数量;
- LIMIT 3, 4的含义是从行3开始的4行.(跳过前3行,取4行)
- 替代语法LIMIT 4 OFFSET 3意为从行3开始取4行,就像LIMIT 3,4一样。
11.1.6 使用完全限定的表名
主要用于多表查询时,限定字段是从哪个表中取出的数据;
11.2 对检索数据进行排序ORDER BY
11.2.1 排序数据ORDER BY
默认查询出的数据,并不是随机排序的,如果没有指定排序,数据一般将以它在底层表中出现的顺序显示
关系数据库设计理论认为,如果不明确规定排序顺序,则不应该假定检索出的数据的顺序有意义
通常,ORDER BY子句中使用的列将是为显示所选择的列。(意思是大多数情况下,只需要将最终显示的列进行排序)
但是,实际上并不一定要这样,用非检索的列排序数据是完全合法的。
11.2.2 按多列进行排序
当所选字段重复时,可以选择参考多个字段进行再次排序;
select * from stu order by classid, age;
- 在需要对多列数据进行排序时,使用逗号分隔列名,井会按照前后顺序依次对比排序
- order by的排序默认升序,可以使用DESC设置降序排列
select * from stu order by classid, age DESC;
- 以上语句就是先对lassid进行升序排序然后在结果中对age进行降序排序
11.2.3 注意
ORDER BY子句的位置,使用子句的次序不对将产生错误消息;
- FROM子句位于ORDER BY子句之前。
- LIMIT必须位于ORDER BY之后。
11.3 数据检索条件过滤Where
11.3.1 WHERE用法
数据库表一般包含大量的数据,很少需要检索表中所有行。通常只会根据特定操作或报告的需要提取表数据的子集。
只检索所需数据需要指定搜索条件(search criteria),搜索条件也称为过滤条件(filter condition)
在SELECT语句中,数据根据WHERE子句中指定的搜索条件进行过滤。
select name from stu where age = 22;
ORDER BY语句应放在WHERE语句之后
11.3.2 WHERE子句操作符
限定边界(between包括边界值)
使用 is null
11.3.3 AND与OR操作符
例如:我需要在数据库中查询出1期或2期的学员,并且要求是女生
select name from stu where class_id=18 or class_id =19 and sex='m'
以上语句不会按照预期检索出正确的数据问题出在哪里?
原因在于计算的次序。SQL在处理OR操作符前,优先处理AND操作符。
当SQL看到上述WHERE子句时,它理解是19期班级的所有女生,或者18期的所有学员,而不分性别。换句话说,由于AND在计算次序中优先级更高,操作符被错误地组合了
因此想要解决就需要提升优先级,使用圆括号明确地分组相应的操作符
select name from stu where (class_id=18 or class_id =19) and sex= 'm'
11.3.4 IN与NOT
IN操作符用来指定条件范围,范围中的每个条件都可以进行匹配。
select name from stu where class_id in (1,2)
IN WHERE子句中用来指定要匹配值的清单的关键字,功能与OR相当
为什么要使用IN操作符?其优点具体如下。
- 在使用长的合法选项清单时,IN操作符的语法更清楚且更直观。
- 在使用IN时,计算的次序更容易管理(因为使用的操作符更少)。
- IN操作符一般比OR操作符清单执行更快。
- IN的最大优点是可以包含其他SELECT语句,使得能够更动态地建立WHERE子句。
NOT WHERE子句中用来否定后跟条件的关键字
select name from stu where class_id not in (18,19)
- 为什么使用NOT?对于简单的WHERE子句,使用NOT确实没有什么优势。
- 但在更复杂的子句中,NOT是非常有用的。
- 例如,在与IN操作符联合使用时,NOT使找出与条件列表不匹配的行非常简单。
11.4 Like与通配符
前面介绍的所有操作符都是针对已知值进行过滤的。但是,这种过滤方法并不是任何时候都好用。
例如,怎样搜索产品名中包含文本anvil的所有产品?用简单的比较操作符肯定不行,必须使用通配符。
为在搜索子句中使用通配符,必须使用LIKE操作符。
LIKE指示MySQL,后跟的搜索模式利用通配符匹配而不是直接相等匹配进行比较。
11.4.1 百分号(%)
通配符在搜索串中,%表示任何字符出现任意次数
- select name from stu where name like ‘a%’
- select name from stu where name like ‘%a’
- select nane from stu where name like ‘%a%’
11.4.2 下划线(_)
通配符下划线的用途与%样,但下划线只匹配单个字符而不是多个字符
使用通配符的技巧
MySQL的通配符很有用。
但这种功能是有代价的:通配符搜索的处理一般要 比前面讨论的其他搜索所花时间更长。
这里给出一些使用通配符要记住的技巧
- 不要过度使用通配符。如果其他操作符能达到相同的目的,应该使用其他操作符。
- 在确实需要使用通配符时,除非绝对有必要,否则不要把它们用在搜索模式的开始处。把通配符置于搜索模式的开始处,搜索起来是最慢的。
- 仔细注意通配符的位置。如果放错地方,可能不会返回想要的数据
11.4.3 了解MySql的正则REGEXP
所有种类的程序设计语言、文本编辑器、操作系统等都支持正则表达式
select name from stu where name regexp '[0-5]abc'
11.5 字段计算
11.5.1 简介
存储在数据库表中的数据一般不是应用程序所需要的格式。下面举几个例子
- 如果想在一个字段中既显示用户名,又显示班级号,但这两个信息一般包含在不同的表列中。
- 同时姓名、手机号和地址存储在不同的列中(应该这样),但快递单打印程序却需要把它们作为一个恰当格式的字段检索出来。
- 列数据是大小写混合的,但报表程序需要把所有数据按大写表示出来。
- 物品订单表存储物品的价格和数量,但不需要存储每个物品的总价格(用价格乘以数量即可)。为打印发票,需要物品的总价格。
- 需要根据表数据进行总数、平均数计算或其他计算
计算字段并不实际存在于数据库表中。计算字段是运行时在SELECT语句内创建的
11.5.2 字段拼接concat
stu表包含用户名和手机号码信息。假如要生成一个学生报表, 需要在学生的名字中按照name(phone)这样的格式列出。
解决办法是把两个列拼接起来。在MySQL的SELECT语句中,可使用Concat()函数来拼接两个列
select concat(name, '(', phone')') from stu
11.5.3 使用别名AS
SELECT语句拼接字段可以完成。但此新计算列的名字是什么呢?实际上它没有名字,它只是一个值。
如果仅在SQL查询工具中查看一下结果, 这样没有什么不好。
但是,一个未命名的列不能用于客户机应用中,因为客户机没有办法引用它。
为了解决这个问题,SQL支持列别名。别名(alias) 是一个字段或值的替换名。别名用AS关键字赋予
select concat(name, '(', phone')') from stu as name_phone from stu
11.6 常用函数介绍
官方文档https://dev.mysql.com/doc/refman/5.7/en/string-functions.html
11.6.1 文本处理函数
select left('123456',2);
select left(name,1) from stu;
select substring('123456',2,3);
11.6.2 日期和时间处理函数
select now();
select date(now());
select time(now());
select time(now());
select addtime(now(),'2:2:2');
11.6.3 数值处理函数
11.7 聚集函数与GroupBy分组
11.7.1 聚集函数的使用
我们经常需要汇总数据而不用把它们实际检索出来,为此MySQL提供了 专门的函数。
使用这些函数,MySQL查询可用于检索数据,以便分析和报表生成
- 确定表中行数(或者满足某个条件或包含某个特定值的行数)。
- 获得表中行组的和。
- 找出表列(或所有行或某些特定的行)的最大值、最小值和平均值。
上述例子都需要对表中数据(而不是实际数据本身)汇总。
因此,返回实际表数据是对时间和处理资源的一种浪费
在使用count时,如果指定列名,则指定列的值为空的行被忽略,但如果COUNT()函数中用的是星号(*) ,则不忽略
select count(id),max(age),min(age),sum(age),avg(age) from stu;
select count(id) as num,max(age) as max_age,min(age) as min_age,sum(age) as sum_age,avg(age) as avg_age from stu;
使用别名时,也可以用空格代替as
11.7.2 数据分组GROUP BY 与HAVING
group by
SQL聚集函数可用来汇总数据。这使我们能够对行进行计数,计算和与平均数,获得最大和最小值而不用检索所有数据
目前为止的所有计算都是在表的所有数据或匹配特定的WHERE子句的数据上进行的。
例如我们需要获取某个班级的学员人数:
select count(*) as nums from stu where class_id = 2
但如果要返回每个班级的人数怎么办?
此时就需要使用分组了,分组允许把数据分为多个逻辑组,以便能对每个组进行聚集计算。
select class_id, count(*) as nums from stu group by class_id;
select class_id, count(*) as nums, avg(age) avg_age from stu group by class_id;
那么如果需要返回人数少于5人的班级怎么办?
或返回班级人数大于5人的班级怎么办?
HAVING
除了能用GROUP BY分组数据外,MySQL还允许过滤分组,规定包括哪些分组,排除哪些分组。
例如,可能想要需要获取班级人数小于等于5人的班级。。为得出这种数据,必须基于完整的分组而不是个别的行进行过滤
事实上,目前为止所学过的所有类型的WHERE子句都可以用HAVING来替代。
唯一的差别是WHERE过滤行,而HAVING过滤分组。
select class_id, count(*) as nums from stu group by class_id;
select class_id, count(*) as nums from stu group by class_id having nums >= 5;
注意
在使用group by进行分组时,按照标准的SQL模式,需要把select查询中的所有列(除了聚集函数外)全部都列在group by后面
十二、MySQL数据库数据的导入导出
12.1 数据导出
12.2 将数据库中的表导出
12.3 数据导入
十三、MySQL数据库权限管理
mysql中的root用户是数据库中权限最高的用户,千万不要用在项目中。
可以给不同的用户,或者项目,创建不同的mysql用户,并适当的授权,完成数据库的相关操作,这样就一定程度 上保证了数据库的安全。
创建用户的语法格式:
grant 授权的操作 on 授权的库.授权的表 to 账户@登录地址 identified by '密码';
示例:
#在mysql中 创建一个zhangsan 用户,授权可以对chuange这个库中的所有表进行添加和查询的权限
grant select, insert on chuange.* to zhangsan@'%' identified by '123456';
#用户lisi.密码 123456 可以对chuange库中的所有表有所有操作权限
grant all on chuange.* to lisi@'%' identified by '123456';
#删除用户
drop user 'lisi'@'%';