目录
- 数据库概述
- SQL与NoSQL对比
- 关系型数据库管理系统的常用实例
- MySQL
- 介绍
- 安装
- 数据库的连接
- SQL
- DDL
- DML
- DQL
- 单表查询
- 多表查询
- 多表关系
- 连接查询
- 连接分类
- 内连接 JOIN
- 外连接
- 左外连接 LEFT JOIN
- 右外连接 RIGHT JOIN
- 自连接 JOIN
- 联合查询 UNION
- 子查询
- 标量子查询
- 列子查询
- 行子查询
- 表子查询
- DCL
- 函数
- 字符串函数
- 数值型函数
- 日期函数
- 流程函数
- 约束
- 约束类型
- 外键
数据库概述
为什么要使用数据库存储数据,而不是直接用各种格式的文件存储? 例如 想要存储 name=‘zs’,age=20,使用数据库建库建表可以存储,使用.txt文件一样可以存储?
- 使用数据库搭配上
数据库管理系统
相比于直接操作文件大大提升数据管理效率、能够存储更多的数据、确保数据的一致性,完成性,安全性的同时降低数据冗余、数据方便共享等等好处。 - 例如,我要查询上面的数据中所有名为‘zs’人员的年龄,使用java操作数据库,只需要写一条SQL使用固定的流程即可查询,而使用文件存储,可能还要获取多个文件的IO流读取数据,遍历数据在进行判断等等,十分的麻烦,效率极低,对于有成千上万的数据来说,简直天差地别。
既然数据库存储优点这么多,为什么不使用数据库存储所有文本文件? 或者说 为什么不使用DBMS系统代替文件系统?
- 文件支持各种格式的数据,而数据库对数据有太多的约束
- 数据库也要依赖于文件系统
- 文件的读取不需要其他中间件参与,更适合存储相对独立,量少,格式多样,不需要频繁操作的数据。例如,用文件格式存储一个软件的配置信息,总不能在所有软件启动时去连接指定的数据库读取数据,或者内置一个数据吧
数据库、数据库管理系统、结构化查询语言(DB、DBMS、SQL)
数据库
:存储数据的仓库,将数据有组织的进行存储数据库管理系统
:既然已经指定仓库了,但怎样将数据放入仓库,怎样按条件从仓库中获取数据呢?这就需要一个管理软件
。类似于菜鸟驿站,整个驿站的货架作为仓库,但收快递、取出快递则需要一套管理系统。日常常说的数据库如Mysql、Oracle等指的是数据库管理系统。结构化查询语言
:结构化查询语言即SQL
,是在所有关系型数据库
之间流通的通过数据库管理系统操作数据库的编程语言
。这也是关系性数据库的一大优势,不同关系型数据库之间如Oracle
、MySQL
、SQL Server
等,都可以使用SQL这一种语言操作,只有个别细小的地方需要改动
SQL与NoSQL对比
数据结构化
: SQL中的数据存储有边边框框的限制,例如指定字段、指定数据类型等,而NoSQL是格式非常松散,例如 redis的键值对存储,对V的数据结构没有要求数据关联性
:SQL表和表之间可以存在联系,像一对多、一多一、多对多,通常还要考虑数据一致性。 而NoSQL每条数据是独立存在的,删除这一条不用去考虑其他数据是否依赖于此数据。查询方式
:SQL数据库之间有统一的查询语言,而NoSQL每个厂商都有自己的语言存储方式
:SQL绝大多数要操作的数据在磁盘中,而NoSQL绝大数要操作的数据存储在内存中,磁盘用来存储备份的数据
关系型数据库以 行 和 列的形式存储数据,形成一个二维表
,最大的优势是支持复杂的查询
、方便维护
、支持事务
关系型数据库管理系统的常用实例
按市场占有率进行排名
Oracle
: 1972年诞生成为第一个商用的数据库,适用于大型
数据库。其公司也改名为Oracle公司 。2009年收购Sun(含有MySQL)公司,所以Oracle公司目前同时拥有Oracle
数据库(收费
)和MySQL
数据库(分为社区版和商业版
)。MySQL
:开源免费
的数据库,适用于中小型
数据库,1995年开发,2008年被Sun收购,2009年Sun被Oracle收购,所以目前归属于Oracle。Oracle将MySQL分为免费的社区版和付费的商业版SQL Server
: 微软公司推出的中型
数据库,C#和.NET常用PostgreSQL
:开源免费的中小型数据库DB2
:IBM公司的大型收费数据库产品,常用于银行SQLLite
:嵌入式的微型数据库,常用于手机端MariaDB
:开源免费的中小型数据库,MySQL 的创始人担心 MySQL被收购后有闭源的风险,因此创建了 MySQL 的分支项目 MariaDB,与MySQL有很好的的兼容性。
MySQL
介绍
- MySQL目前属于
Oracle
公司(前世今生上面已经介绍,这里不加赘述)。 - 是一套开源、免费、可定制的数据库管理系统。
- 支持管理
千万条数据的
大型数据库,32位系统最大表文件支持4GB
,64位系统最大表文件支持8TB
- 采用标准的
SQL数据语言
- 允许运行在多个系统上,并且支持多种语言如:C、C++、Java、python、Php、Ruby等。
- 2016年发布里程碑版本
MySQL8.0
,在功能上做了显著增强
优点:
- 开源免费,使用成本低
- 性能好,服务稳定
- 体积小,使用简单
- 老牌且社区活跃
安装
Win版与Linux版安装方式不同,安装以8版本为例
win版只需要点击msi
文件然后下一步即可,在安装时可以指定连接的端口
、root用户密码
,服务名称
,是否自启动
。在安装后,要记得配环境变量,方便能够任意位置使用sql命令。
linux版 linux版下载的包需要解压,然后使用rpm -ivh
一步步的安装包内文件,最后再启动MySQL服务systemctl start mysqld
MySQL初次启动会默认有一个密码,需要在启动日志中查询默认生成的密码 grep 'temporary password' /var/log/mysqld.log
使用root身份登录后需要进行修改密码 ,MySQL的默认密码是严格模式,即要大于8位有数字和字母
如果不想这样,可以进行修改MySQL的全局变量
例如 采用弱模式,将要求的密码位数改为大于4
set global validate_password.policy = 0;
set global validate_password.length = 4;
默认的root用户的主机名是localhost,就代表只能使用本机进行连接,即不能使用其他设备登录连接,需要修改用户对应的登录ip
update user set host='%' where user ='root'; 使用通配符% 改为了任意连接ip
配置这一切后重启即可
数据库的连接
-
开启
数据库服务:net start mysql80
安装时默认会自启动,服务名如果不变是sql80,如果修改需要使用自己的 -
关闭
数据库服务:net stop mysql80
命令行 -
在cmd窗口输入:mysql 【-h
主机地址
】【-P端口
】-u用户名(通常为root)
-p (指定密码模式):如果数据库在本机且没有修改端口,则【】中的内容可省略。-p的密码为了安全不在命令中直接填入,而是输入命令后回车,再去输入密码
客户端连接 -
sqlyog
- Navicate:(个人最爱)
- dataGrip:
Idea的连接数据库插件也可简单连接
SQL
SQL是一种结构类数据库统一的数据语言,为操作关系性数据库定义了统一标准 根据功能的不同共分为四种
类名 | 说明 |
---|---|
DDL | 数据库定义语言 ,如创建库、修改库、删除库、创建表、修改表(即修改字段)、删除表等。总之就是创建一个结构约束,等待数据的插入 |
DML | 数据操作语言 ,对表的数据进行增、删、改 的操作,会对结构中的数据进行改动 |
DQL | 数据查询语言 ,对表的数据进行各种查 ,不会对数据发生改动。 |
DCL | 数据权限控制语言 ,控制数据的某些权限,保障数据系统的安全性 |
通用语法:
- 多个SQL语句间使用
;
进行分隔 - 在
win版
对大小写不敏感,但在Linux版大小写敏感
(可以去设置),所以按照大小写敏感去开发 ,关键字、函数名、变量名使用大写
;数据库名、表名、字段名使用小写
阿里开发公约【强制】
表名、字段名必须使用小写字母或数字 ,
禁止出现数字开头,禁止两个下划线中间只 出现数字。
数据库字段名的修改代价很大,因为无法进行预发布,所以字段名称需要慎重考虑。
- 注释:
- 单行:
#
或--
- 多行:
/*注释内容*/
- 单行:
DDL
数据库操作
- 查询
- 查询所有数据库
show DATABASES;
- 查询当前数据库,使用函数
SELECT DATABASE();
- 查询所有数据库
- 增加
- 创建数据库
CREATE DATABASE 数据库名
,当数据库存在时会报错 - 如果数据库
不存在再创建
:CREATE DATABASE IF NOT EXISTS 数据库名
- 在创建数据库时,指定
字符集
:CREATE DATABASE 数据库名 DEFAULT CHARSET utf8mb4
,在创建数据库语句后面加上 默认的字符编码,编码使用utf8mb4
,这种编码包含于utf8
,但其还可以存放4个字节的编码,使之能够存放移动端的表情等
- 创建数据库
- 删除
- 删除数据库:
DROP DATABASE 【IF EXISTS】 数据库名
-其他: - 切换数据库:
USE 数据库名
:在操作数据时,一定要切换到其数据库
- 删除数据库:
数据表操作
- 查询
- 查询当前
库所有表
:SHOW TABLES;
- 查看
表结构
:DESC 表名
- 查询指定表的建表语句:
SHOW CREATE TABLE 表名
- 查询当前
- 建表 CREATE
- 创建一张表
CREATE TABLE 表名(字段1 类型 【comment 字段注释】,字段2 类型 【comment 字段注释】)【comment 表注释】
表的数据类型
- 数值型
- 创建一张表
类型 | 字节数 | 有符号范围 |
---|---|---|
tinyInt | 1 | 负的(2的(8 -1)次方除以2)~正的((2的(8 -1)次方除以2)-1) |
smallInt | 2 | 负的(2的(16 -1)次方除以2)~正的((2的(16 -1)次方除以2)-1) |
mediumInt | 3 | 负的(2的(24 -1)次方除以2)~正的((2的(24 -1)次方除以2)-1) |
int | 4 | 负的(2的(32 -1)次方除以2)~正的((2的(32 -1)次方除以2)-1) |
bigInt | 8 | 负的(2的(64 -1)次方除以2)~正的((2的(64 -1)次方除以2)-1) |
float | 4 | |
double | 8 | |
decimal(M,D) | M+2个字节 | 定点数 手动指定精度和标度 精度=小数位+整数位 标度=小数位 十分精准,但占用空间 |
数值型要注意符号位,在整数类型有一个bit用作符号位,若不使用符号,则表示范围从(0,2的bit位数次方-1)
浮点数类型无符号只是取有符号的0和正数位,实际范围并未扩大
,只是将小数部分省去
- 字符型
类型 | 字节大小 | 描述 |
---|---|---|
char | 0~255 | 定长字符串,需要指定长度指定多长,就占用多少字符空间 但效率高 |
varchar | 0~65535 | 变长字符串,需要指定长度最为最大限制。 占用多少字符空间,与具体存储有关 相比于Char更加灵活,但效率低 |
text | 0~65535 | 适用于长文本的数据 |
能够固定长度的使用char 因为其效率更高 |
- 日期时间型
类型 | 占用字节数 | 描述 |
---|---|---|
Date | 3 | 日期值 YYYY-MM-DD |
Time | 3 | 时间值 HH:MM:ss |
Year | 1 | 年份值YYYY 范围 1901~2155 |
DateTime | 8 | 日期和时间值 YYYY-MM-DD HH:MM:SS 范围 1000-01-01 00:00:00 至 9999-12-31 23:59:59 |
TIMESTAMP | 4 | 日期和时间值 YYYY-MM-DD HH:MM:SS 1970-01-01 00:00:01 至 2038-01-19 03:14:07 采用时间戳的方式存储,会自动根据当前时区进行转换 |
修改表 ALTER
- 增加字段
ADD
:ALTER TABLE 表名 ADD 字段名 类型 【注释】【约束】
- 修改字段类型
MODIFY
:ALTER TABLE 表名 MODIFY 字段名 类型
- 修改字段名和字段类型
CHANGE
:ALTER TABLE 表名 CHANGE 旧字段 新字段 类型 【注释】【约束】
- 删除字段
DROP
:ALTER TABLE 表名 DROP 字段名
- 修改表名
RENAME
:ALTER TABLE 表名 RENAME TO 新表名
删除 DROP
-删除表
:DROP TABLE 【IF EXISTS】表名
-删除后再创建表,相当于对表的数据进行一个截断
:TRUNCATE TABLE 表名
DML
添加数据 INSERT
VALUE与VALUES无大区别,可混用
- 给
指定字段
添加数据INSERT INTO 表名(字段1,字段2,字段3) VALUES(字段1的值,字段2的值,字段3的值)
- 给全部字段添加数据
- 将全部字段写入
INSERT INTO 表名(字段1,字段2,字段3) VALUES(字段1的值,字段2的值,字段3的值)
- 省略字段名,直接写入表名
INSERT INTO 表名 VALUES(字段1的值,字段2的值,字段3的值)
- 将全部字段写入
- 批量添加数据 前面不变,后面
VALUES(第一组值),(第二组值),(第三组值)...
注意事项:
- VALUES中值的顺序要与数据表字段(没有指定字段时)或指定的
字段顺序一一对应
- 字符串日期函数要加上
''
号 - 插入数据大小要符合设定的数据类型范围
删除数据
- 删除数据:
DELETE FROM 表名 【WHERE 条件】
删除数据只能删除一行,而不能删除某个字段的数据。整个字段数据全部删除可以使用DDL语句ALTER TABLE 表名 DROP 字段名
,删除字段的某一个值可以使用UPDATE语句将其置空
修改数据 UPDATE
- 修改数据:
UPDATE 表名 SET 字段1=值1,字段2=值2... FROM 表名 【WHERE 条件】
;若不写条件条件则修改整张表的数据,若写明条件,只会修改符号条件的数据
DQL
单表查询
查询语句结构
SELECT 字段列表 FROM 表名 WHERE 条件 GROUP BY 分组条件 HAVING 分组后的条件 ORDER BY 根据哪些字段排序 LIMIT 分页参数
简单查询
- 查询多个字段
SELECT 字段1、字段2 FROM 表名 WHERE 条件
不建议使用SELECT * FORM 表名..
因为*
查询效率低 - 为字段设置表名
- 可以在要查询的字段后 一个空格直接添加上别名
SELECT 字段1 别名1
- 在要查询的字段后 添加上
SELECT 字段1 AS 别名1
- 可以在要查询的字段后 一个空格直接添加上别名
- 在查询时去除重复记录
SELECT DISTINCT 字段列表 FROM 表名
注意
_
代表匹配单
个字符,%
代表匹配任意个
字符- 为空或者不为空要用
IS NULL
和IS NOT NULL
来表示 BETWEEN x AND y
范围包括x
和y
聚合函数
把整个字段作为一个整体进行纵向计算
函数名 | 作用 |
---|---|
count() | 统计某一字段纵向数据的个数 |
max() | 统计这一字段(列)最大的值 |
min() | 统计这一字段(列)最小的值 |
avg() | 统计这一字段(列)平均值 |
sum() | 统计这一字段(列)总和 |
分组查询
把where
条件查询后的数据 跟据某一字段按照相同值进行分组,分组后的数据可以使用HAVING
进行过滤
HAVING
与WHERE
的区别
- 执行的先后顺序不一样,HAVING执行在分组后,分组又在
WHRER
查询后 HAING
可以使用聚合函数进行再一次过滤
分组字段数据相同的有几组,结果就会显示几条数据
注意:
1、分组查询的字段应为聚合函数和用来分组的字段 ,否则无意义
要在每个分组中只能查询出一行数据,和聚合函数是对每组数据进行压缩成一个数据,每组字段每组也只有一个
例:统计男女生人数 :按照性别进行分组,最后只会有两行数据 在字段中使用聚合函数的COUNT(*)将每组数据进行统计个数
最后显示两行数据,一行是分组的男生数据,另一行是女生数据 。 字段只适合符合分组条件,例如字段加上一个姓名,男生组中出现一个姓名,女生组出现一个姓名 ,只有两行数据毫无意义
2、可以根据多个字段进行分组 GROUP BY 字段1 ,字段2 ,最后数据个数为 字段1*字段2
3、HAVING必须要跟在GROUP By之后
排序方式
-
ASC 升序 (默认)
-
DESC 降序
-
按照某个字段1进行
升序
排序,顺序相同时,在按照字段2进行降序排序ORDER BY 字段1 ASC,字段2 DESC
分页查询
SELECT 字段列表FROM 表名 LIMIT 起始索引,数据条数
注意
1、若不指定起始索引,默认为0
2、起始索引=(页数-1)* 每页显示条数
3、LIMIT是MySQL的方言,不同的数据库分页有不同的实现方法
例如:查询第三页人员的姓名,每页显示5条数据
这里第三页起始页数,根据起始索引=(起始页数-1) * 每页的大小
,每页的大小为5 即可获取起始索引,所以在查询语句后面添上LIMI 起始索引,每页大小
总结
执行顺序:
先要知道从哪张表查,数据条件过滤,要查询哪些字段?将查询的出的数据按照什么顺序排列?要几个数据?
例
多表查询
利用表与表的关系,通过一条SQL语句查询多张表的数据
多表关系
一对一
表中一条数据对应另一张表的一条数据,
那么为什么不合为一张表呢?
- 将单表进行拆分,既能提升查询效率 也方便管理。例如将用户表分为用户基础信息表和用户详情表,这样在可以根据需求进行不同粒度的查询,提升效率
怎样实现一对一的关系呢?
- 一张表的字段关联着另一张表的主键,且子表的该字段唯一,这样就能确保一张表中只有一条数据与另一张表中的一条数据相对应
使用外键是确定表中数据间的关系从而确保数据完整性,使用唯一约束是确保只有一条数据(唯一)对应另一条数据(主键唯一)
多对一、一对多
这种比较常见,比如图书一个管理员要保管多个图书,一个部门对应多个员工,如果把他们放在一张表,那么多的一方字段会大量的冗余。
怎样实现多对一的关系呢?
多对一和一对多是同一种关系,只是主体不同罢了。实现使用多
的一方外建于一
的一方的主键,并保存一
的一方的主键。
这样就能确保数据完整性的同时,也能通过多的一方找到一的一方。
例如,员工表保存部门的id。
- 查询员工的部们信息时,通过其字段保存的部门主键去部门表中查找对应数据即可
- 查询此部门对用所有的员工信息,也同样去员工表查询保存部们的字段=此部门id即可
多对多
一张表的多数据可能对应另一张的多条数据,没有一
的一方了,这时就需要一张表单独去保存他们的对应关系。例如课程
与学生
,一个学生对应多个课程,一个课程也对应多个学生,这时就不需要这两张表建立关联,只需要再去创建一张学生课程关系表
去记录哪一学生有哪一门课
例如:
连接查询
如果直接去查询两张表,那么将会形成笛卡尔积
两张表没有关系的数据内容也会在一条数据显示
例
那么怎样解决呢? 过滤!
在将这些数据按照条件就行过滤,条件就是这两张表的关系 。例如在语句后面添加上WHERE tbl_cla.id= tbl_stu.class_id
,这样就成功查出了学生信息与其对应的班级信息
而这种两张表连接的方式也叫隐式内连接
,此外还有多种不同的方式
连接分类
在表连接时建议给表起别名,但一但起别名就不能使用原表名。在指定两张表的连接条件时,不能使用字段的别名,要使用表名/表的别名.字段原名
,因为根据SQL的执行顺序,在执行WHERE语句时还没有执行到SELECT,对于字段的别名来说是未知的
内连接 JOIN
内连接相当于求两张表的交集部分
例如:有员工表和部门表,那么通过内连接能够查询出每一个员工对应的部门,对于有部门没有员工和有员工没有部门的将会被舍去
隐式内连接
SELECT 字段列表 FROM 表1 ,表2 WHERE 连接条件
把两张表的数据全部查取出来,再通过字段共同部分进行过滤,从而查取出两张表中每条关联的数据。没有关联的数据将会被过滤掉,所以是两张表的交集
显式内连接
SELECT 字段 FROM 表1 (INNER)JOIN 表2 ON 连接条件
求两张表的交集部分的另一种写法
外连接
左外连接 LEFT JOIN
例如 ,同样是员工表和部门表,如果员工表左外连接部门表,则会查询所有
员工以及对应的部门,当然这样就会包含
没有部门的员工,会省略
没有员工的部门
SELECT 字段 FROM 表1 LEFT(OUTER)JOIN 表2 ON 连接条件
右外连接 RIGHT JOIN
同左外连接,只是这次是去查询右表与左表的公共部分
例 :员工表和部门表,如果员工表右外连接查询部门表,则查询的数据是每个部门包含的员工信息,也包括
没有员工的部门,省略
没有部门的员工
SELECT 字段 FROM 表1 RIGHT (OUTER)JOIN 表2 ON 连接条件
左外连接和右外连接可以通过改变表的连接顺序实现转换,例如:上面的例子也可以通过部门表左外连接员工表实现
,多数时使用的是左外连接
自连接 JOIN
同一张表再次连接自己,查询一张表中数据有关联的部分。例如,一张员工表,表中记录着员工的信息和领导的id,而领导也在这张表。一张表中数据和数据存在关联部分,通过自连接即可查询到每一个领导对应的员工的信息等
自连接一定要给表起别名,否则都是一张表怎样去区分是哪张表呢?
SELECT 字段 FROM 表1 别名 JOIN 表1 别名 ON 表中数据关系部分
,自连接的语法同内连接,只是同一张表间的连接
联合查询 UNION
联合查询相当于把两次查询的数据进行纵向的拼接,条件是表的字段列数以及类型
必须一一对应,否则纵向拼接怎样对齐数据呢?分为两种方式,一种是允许重复即允许一条数据多次显示 关键字UNION ALL
;一种是拼接后进行去重 ,关键字UNION
同样是员工表,我想要查询员工年龄大于30 的,在查询工资大于1万的,将查询的数据进行纵向拼接,则可能会出现年龄既大于30工资又大于1万的重复显示,忽视则UNION ALL
,去重则UNION
查询的语法就像条SQL通过一个关键字UNION
/UNION ALL
进行连接
SELECT 字段 FORM 表
UNION
SELECT 字段 FROM 表
为什么不使用一条语句呢?因为是要求的是查询字段类表即类型相同,而不是表的所有字段,这样就会出现不同的表,每张表满足不同的条件进行相同字段的连接
同样是员工表与部门表,要查询员工表人数大于20 的部门的id和位置在北京的部门id,两张不同表通过不同的条件查询出相同的字段进行拼接即可得出 位置在北京同时人数大于20的部门id
子查询
SQL语句中将另一条SQL的查询结果作为条件进行查询,SQL嵌套
标量子查询
返回的数据为单个值
常用的查询条件:= <> > >= < <=
例如:查询A班级的所有学生信息 。 学生表中存放的是班级的id字段,通过班级id作为条件,就要查询A班级对应的id,只能有一个数据所以是标量子查询
列子查询
查询一列数据,即一个字段的多条数据,通常是作为一个字段的条件范围
常用的查询条件:IN 、NOT IN 、 ANY 、SOME 、 ALL
例如:查询班级编号为A和B的所有学生信息。A和B会查询出两条id数据,只要在查询学生表时要求学生的班级id在这班级id范围内即可
行子查询
查询一行的可能多个字段的数据
常用的查询条件:= 、<> 、IN 、NOT IN
用于要查询的数据需要多个有关子查询的条件
例如 有两张表,要查询A部门的员工家庭住址和A部门所在地相同的员工信息
要先查询A部门对应的部门id,和A部门的地址。子查询是一行有多个字段的数据作为条件,这就是 行子查询
语句就为 SELECT * FROM emp WHERE (dep_id,addr)=(SELECT id,addr FROM dpt WHERE name='A')
表子查询
行子查询有多条数据或者说列子查询有多个字段,多条数据多个字段,子查询查询出的即是一张表
例如:查询所有 员工的家庭地址与其所在部门地址相同的员工信息
首先就要查询所以部门的id以及地址,多个字段多条数据相当于一张表 作为查询员工表的条件。
常用的查询条件:in
语句就为 SELECT * FROM emp WHERE (dep_id,addr) in (SELECT id,addr FROM dpt)
DCL
数据库权限管理语句,对系统的管理不止可以使用语句,还可以使用命令行,由于对于开发,这里只做了解,只介绍部分使用语句的情况
认证管理
系统中所有的用户信息(用户名、密码等)也放在了一张表中,此表在系统数据库,库名为mysql
,库表为user
查询
- 查询此系统中的所有用户:查询所有用户即要查询
user
表中所有的数据SELECT * FROM mysql.user
添加
-
注册一个用户:
注意
注册用户并不是向表中添加一条数据,而是由专门的语句CREATE USER '用户名'@'登录时指定的ip' IDENTIFIED BY '密码'
- 值的注意的是
- 主机ip使用来限制用户可以从哪台主机进行登录,可以使用通配符
%
,代表任意主机 - 用户登录要满足三个条件,
用户名正确
,在指定的ip登录
,密码正确
- 用户创建完成后,没有任何权限,需要后面的赋值操作,否则登录后只会显示一张表
information_schema
- 主机ip使用来限制用户可以从哪台主机进行登录,可以使用通配符
- 值的注意的是
修改
- 修改用户密码:
ALTER USER '用户名'@'主机ip' IDENTIFIED WITH mysql_native_password BY '新密码'
也可修改主机名、用户名,这里不再介绍
删除
- 删除用户
DROP USER '用户名'@'主机名'
授权管理
除了root用户其他用户注册后必须还有为其授权权限,否则没有只能登录,登录后只能看到一张系统的表,上面已经介绍过。
权限是精确到表的
权限都有哪些常见的、可供授予的呢?
权限名称 | 描述 |
---|---|
SELECT | 查询权限 |
INSERT | 插入权限 |
UPDATE | 修改数据 权限 |
DELETE | 删除权限 |
CREATE | 创建库表 权限 |
ALTER | 修改表 权限 |
DROP | 删除表、库、视图 权限 |
ALL, ALL PRIVILEGES | 所有权限 |
查询谁哪些权限 SHOW GRANTS FOR '用户名'@‘主机名’
授权谁哪些权限 GRANT 权限1 , 权限2 .. ON 数据库名.表名 TO ‘用户名’@‘主机名’
撤销谁哪些权限REVOKE 权限1 , 权限2 .. ON 数据库名.表名 FROM ‘用户名’@‘主机名’
数据库和数据表可以使用通配符*
代表所有,所有权限可以使用ALL
, ALL PRIVILEGES
总结
函数
函数是SQL数据库管理系统中自己封装的一段SQL语句,可以直接调用其去执行相应的功能
这里列举一些常见函数
字符串函数
对字符串类型的数据进行处理,最后返回一个字符串
-
CONTANT(‘a1’,‘a2’,‘a3’):
字符串拼接
,放在参数列表中的各个参数将会按照先后顺序被拼接成一个字符串返回
- 例:
- 例:
-
LOWER(‘xxx’) :
全部转为小写
将参数中所有字母
全部转为小写返回- 例
- 例
-
UPPER(‘xxx’):
全部转为大写
,将函数参数列表中所有字母
全部转为大写- 例
- 例
-
LPAD(‘str’,n,‘xxx’):
字符串左填充
,参数列表分别是 要进行填充的字符串、一共要达到的个数、用什么填充 ,最后返回一个处理后的字符串- 例:
- 例:
-
RLAD(‘str’,n,‘xxx’):
字符串右填充
,与上面不同的是,当原字符串没有满足指定的个数时,将会从右边进行填充
-
TRIM(‘str’):
去除左右两边的空格
,注意是不能去除中间空格的- 例
- SUBSTRING(‘str’,startNum,截取长度):
指定从哪个位置截取几个字符
,注意:是从1开始查到startNum,截取包含startNum位置的字符- 例
- 例
- 例
数值型函数
-
CEIL(num):
向上取整,小数一律进一法取整
CEIL翻译为:天花板- 例
- 例
-
FLOOR(num):
向下取整
,只要整数部分 FLOOR翻译为:地板- 例
- 例
-
MOD(x,y):
取模运算
,相当于将x/y
,取模即取前者除以后者的余数
- 例
- 表示除法不用去使用函数,直接使用运算法即可
- 例
-
RAND():
生成0~1之间的随机数
rand 翻译为:胡乱的,随机的- 例
- 例
-
ROUND(num,y):
将小数进行四舍五入
,y指的是小数要保留的小数
位数- 例
练习小案例:通过数据库的函数,生成一个六位数的随机验证码。
随机数乘上1000000,会取得6位数的整数和一堆小数,采用ROUD()进行四舍五入或 CEIL()进一、或FLOOR()取整 等。总之要去掉小数 考虑到可能会有 0.0xxxxxxxx 通过乘和去小数后变为 0xxxxx,0又会自动省略,造成最后不满足6位,所以要对生成的整数进行填充。 使用LPAD()、RPAD()都可以。 SELECT LPAD(ROUND(RAND()*1000000),6,'0')
- 例
日期函数
-
CURDATE():
获取当前日期
CUR即current(翻译为 当前的)的简写,拼上DATE即日期- 例
- 例
-
CURTIME() :
获取当前时间
同理,CUR+TIME- 例
- 例
-
NOW():
当前的日期和时间
,相当于 CURDTAE()+CURTIME()- 例
- 例
-
YEAR(date)、MONTH(date)、DAY(date):
根据日期获取年份、月份、天数
- 例
- 例
- 例
时间类型的计算函数
- DATE_ADD(date,INTERVAL num 时间单位):
计算指定间隔后的日期/时间
INTERVAL 是固定的 后面接上 值 和 单位- 计算日期 则第一个参数传递的是 DATE型, 时间单位有
YEAR
,MONTH
,DAY
,返回的是DATE类型- 例
- 例
- 计算日期 则第一个参数传递的是 DATE型, 时间单位有
- 计算时间 则第一个参数传递的是
DATETIME
型或TIME
型, 单位还可以为HOUR
、MINUTE
、SECOND
- 例
- 例
- DATEDIFF(date1,date2):
计算时间间隔
,返回天数 是前面的日期-后面日期的天数- 例
- 例
- TIMEDIFF(time1,time2):同理,返回的是时分秒
- 例:
- 例:
流程函数
- IF(bool,v1,v2): 如果
bool
如果为true,则返回v1,false则返回v2。相当于一个三目运算- 例
- IFNULL(v1,v2):
如果为v1不为空则返回v1,反之返回v2
- 例:
- 例:
- 例
- CASE 字段 WHEN ‘值1’ THEN ‘返回值1’ WHEN ‘值2’ THEN ‘返回值2’…ELSE ‘返回值3’ END
当这个字段的值等于某个值时,返回什么值,如果都前面的值都不符合,就返回一个ELSE中的值
- 例
- 例
- CASE WHEN(bool)THEN ‘返回值1’ WHEN (bool) THEN ‘返回值2’ ELSE ‘返回值3’ END
满足哪个条件就返回哪个值,都不满足返回false
与前者的不同之处是,前者是用一个字段去挨个与WHEN去比较,这个要比较的值在一个CASE中可以不是固定的,它的特点是可以比较灵活,字段也可以多个
总结
约束
约束用来限制某个字段中应该插入什么样的数据(作用单位是字段),确保表中数据的正确性(如检查约束
、非空约束
、唯一约束
),完整性(如 外键约束
、默认约束
),
约束类型
约束名称 | 描述 |
---|---|
主键约束 primary key | 每一行数据的标识 非空且唯一 |
唯一约束 unique | 在一张表中该字段所有数据不能重复 |
非空约束 not null | 该字段不能为null (可以为空格) |
默认约束 default | 如果不指定值,则自定填土设定好的默认值 |
检查约束 check 该功能在sql8.0.16 版本后才有 | 该字段的数据要满足的一定的条件 |
外键约束 foreign key | 建立表与表之间的联系 ,字表的某个字段的数据要在父表某个字段数据的范围内 |
主键添加时机
- 可以在创建表时,在
字段类型
后面指定约束 。例如创建一张表,将id设定为主键,将姓名设置为唯一
create TABLE tbl_user (id int primary key comment '编号',name varchar(20) unique comment '姓名')
- 创建表时在末尾补上
create Table tbl_user (id int comment '编号',name varchar(20) unique comment '姓名' ,primary key(id))
- 在创建表后,进行修改表添加字段约束 。
alter table tbl_user add primary key
主键删除时 alter table tbl_user drop primary
外键
外键使得两张表之间数据完整性。例如有一个班级表,有一个学生表,学生表中有一个字段时学生的班级,其字段值的范围肯定要在班级编号的范围内。所以建立外键约束,在插入时要检查学生表的班级id字段是否在班级id字段范围内。其中班级表就为父表
,学生表就为字表
外键添加时机
- 在创建表的末尾 指明此表的哪个字段要外键与哪张表的哪个字段
create table tbl_stu (id int PRIMARY KEY auto_increment ,class_id int ,FOREIGN KEY(id) REFERENCES tbl_class(id))
- 修改表 时添加外键
ALTER TABLE tbl_stu Add constraint 外键名称 FOREIGN KEY(id) REFERENCES 主表 (外键的字段)
外键的删除
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称
删除表外键的时候要指定外键的名称,而在创建外键时如果不指定外键名称,系统会自动生成,但生成的不知道是啥,那怎么删除呢?(不使用客户端工具情况下)
使用一个命令那就查看建表语句,在语句中会显示外键的名称show create table 表名
使用开头的例子,既然学生表的班级字段已经外键于班级表的id字段,那么如果班级表被删除了,学生表的班级字段怎么办呢?如果父表被删除了,子表毫无变化,那么子表的这个字段将找不到对应的信息,造成数据的不完整性。
那么该如何解决呢?
父表删除/更新行为对子表的影响
策略 | 描述 |
---|---|
NO ACTION RESTRICT mySQL默认 | 在修改/删除 父表时,如果此条数据已经被其他子表作为外键约束,则父表的此条数据不允许删除 (解决方法:把对应的子表数据删除) |
CASCADE | 在父表被删除后,对应的子表数据也会被删除 ,与上面方法不同的是,上面的方法 子表只能先删除,父表才可以删除。而这个是父表先会删除,再删除子表对应的数据 |
SET NULL | 删除父表后,子表中对应的整条数据不会被删除,而是将对应字段的值置空 |
SET DEFAULT Innodb不支持 | 与上面不同的是,不会被置空,而是可以指定设置为一个默认值 ,但数据库引擎 Innodb不支持 |
具体选择哪一个可以在配置外键时指定,在指定时,又分为修改和删除,不指定则默认是NO ACTION
例如 :ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段)REFERENCES 主表名(字段) ON UPDATE xxx ON DELETE xxx