问: 什么是SQL?
答:
Structured Query Language
结构化查询语言;其实就是定义了操作所有关系型数据库的规则。每一种数据库操作的方式存在不一样的地方,称为方言
。
通用语法
- SQL 语句可以单行或多行书写,以分号结尾。
- 可使用空格和缩进来增强语句的可读性。
- MYSQL 数据库的 SQL 语句不区分大小写,关键字建议使用大写。
- 3 种注释
- 单行注释:
-- 注释内容
或# 注释内容(mysql 特有)
- 多行注释:
/* 注释 */
- 单行注释:
SQL分类
DDL(Data Definition Language)
数据定义语言
用来定义数据库对象(数据库、表、列)等。关键字: CREATE、DROP、ALTER 等DML(Data Manipulation Language)
数据操作语言
用来对数据库中表的数据进行增删改。关键字: INSERT、DELETE、UPDATE 等DQL(Data Query Language)
数据查询语言
用来查询数据库中表的记录(数据)。关键字: SELECT、WHERE 等DCL(Data Control Language)
数据控制语言
用来定义数据库的访问权限和安全级别及创建用户。关键字: GRANT、REVOKE 等
一、DDL(操作数据库、表)
1.1 操作数据库CRUD
C(Create)-创建
sql
-- 创建数据库
CREATE DATABASE 数据库名称;
-- 创建数据库, 判断不存在, 再创建
CREATE DATABASE IF NOT EXISTS 数据库名称;
-- 创建数据库, 并指定字符集
CREATE DATABASE 数据库名称 CHARACTER SET 字符集名;
-- 练习: 创建zhinian_db数据库, 判断是否存在, 并制定字符集为utf8mb4
CREATE DATABASE IF NOT EXISTS zhinian_db CHARACTER SET utf8mb4;
R(Retrieve)-查询
sql
-- 查询所有数据库的名称
SHOW DATABASES;
-- 查询某个数据库的字符集: 查询某个数据库的创建语句
SHOW CREATE DATABASE 数据库名称;
U(Update)-修改
sql
-- 修改数据库的字符集
ALTER DATABASE 数据库名称 CHARACTER SET 字符集名称;
D(Delete)-删除
sql
-- 删除数据库
DROP DATABASE 数据库名称;
-- 判断数据库存在, 存在再删除
DROP DATABASE IF EXISTS 数据库名称;
注: 使用数据库
sql
-- 查询当前正在使用的数据库名称
SELECT DATABASE();
-- 使用数据库
USE 数据库名称;
1.2 操作表
C(Create)-创建
-
数据库字段类型
INT
-整数类型DOUBLE
-小数类型DATE
-日期(只包含年月日yyyy-MM-dd
)DATETIME
-日期(包含年月日时分秒yyyy-MM-dd HH:mm:ss
)TIMESTAMP
-时间戳(包含年月日时分秒yyyy-MM-dd HH:mm:ss
)- 如果将来不给这个字段赋值或赋值为null,则默认使用当前的系统时间,来自动赋值
VARCHAR
-字符串
-
建表语法
sql-- 语法 CREATE TABLE 表名( 列名1 数据类型1, 列名2 数据类型2, .... 列名n 数据类型n ); -- MYSQL CREATE TABLE示例 CREATE TABLE minio_file_upload_info( `id` BIGINT(20) PRIMARY KEY AUTO_INCREMENT NOT NULL COMMENT '自增主键', `file_name` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '文件名称', `file_md5` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '文件MD5', `upload_id` VARCHAR(128) NOT NULL DEFAULT '' COMMENT '文件上传Id', `file_url` VARCHAR(255) NOT NULL DEFAULT '' COMMENT '文件路径', `total_chunk` INT(10) NOT NULL DEFAULT 0 COMMENT '文件总分块数', `file_status` VARCHAR(50) NOT NULL DEFAULT '' COMMENT '文件状态', `update_time` DATETIME DEFAULT NULL COMMENT '修改时间' ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci COMMENT='文件上传信息';
-
复制表
sqlCREATE TABLE 表名 LIKE 被复制的表名;
R(Retrieve)-查询
-
查询某个数据库中所有的表名称
sqlSHOW TABLES;
-
查询表结构
sqlDESC 表名;
U(Update)-修改
-
修改表名
sqlALTER TABLE 表名 RENAME TO 新的表名;
-
修改表的字符集
sqlALTER TABLE 表名 CHARACTER SET 字符集名称;
-
添加一列
sqlALTER TABLE 表名 ADD 列名 数据类型;
-
修改列名称 类型
sqlALTER TABLE 表名 CHANGE 列名 新列别 新数据类型; ALTER TABLE 表名 MODIFY 列名 新数据类型;
-
删除列
sqlALTER TABLE 表名 DROP 列名;
D(Delete)-删除
-
删除
sqlDROP TABLE 表名; DROP TABLE IF EXISTS 表名;
二、DML(增删改表中数据)
2.1 添加数据
语法
sql
INSERT INTO 表名(列名1,列名2,...列名n) VALUES(值1,值2,...值n);
注: ① 列名和值要一一对应。② 如果表名后,不定义列名,则默认给所有列添加值 insert into 表名 values(值1,值2,...值n);
③ 除了数字类型,其他类型需要使用引号(单双都可以)引起来。
2.2 删除数据
语法
sql
DELETE FROM 表名 [WHERE 条件]
注: ① 如果不加条件,则删除表中所有记录。
② 如果要删除所有记录。DELETE FROM 表名; -- 不推荐使用。
有多少条记录就会执行多少次删除操作;TRUNCATE TABLE 表名; -- 推荐使用
,效率更高 先删除表,然后再创建一张一样的表。
2.3 修改数据
语法
sql
UPDATE 表名 SET 列名1 = 值1, 列名2 = 值2,... [WHERE 条件];
注: 如果不加任何条件,则会将表中所有记录全部修改。
三、DQL(查询表中的记录)
sql
SELECT * FROM 表名;
语法
sql
SELECT
字段列表
FROM
表名列表
WHERE
条件列表
GROUP BY
分组字段
HAVING
分组之后的条件
ORDER BY
排序
LIMIT
分页限定
3.1 基础查询
- 多个字段的查询:
SELECT 字段名1,字段名2... FROM 表名;
注: 如果查询所有字段,则可以使用*
来替代字段列表。 - 去重
DISTINCT
- 计算列: 四则运算、
IFNULL(表达式1,表达式2)
。 - 别名: AS 或 空格。
3.2 条件查询
WHERE
子句后跟条件
运算符
<
>
<=
>=
=
<>
BETWEEN...AND
IN(集合)
LIKE
(占位符: _☞单个任意字符 %☞多个任意字符)IS NULL
AND 或 &&
OR 或 ||
NOT 或 !
例
sql
-- 查询姓马的有哪些? like
SELECT * FROM student WHERE NAME LIKE '马%';
-- 查询姓名第二个字是化的人
SELECT * FROM student WHERE NAME LIKE "_化%";
-- 查询姓名是3个字的人
SELECT * FROM student WHERE NAME LIKE '___';
3.3 排序查询
语法: order by 子句
sql
order by 排序字段1 排序方式1, 排序字段2 排序方式2...
- 排序方式:
- ASC:升序(默认)
- DESC:降序
注: 如果有多个排序条件,则当前边的条件值一样时,才会判断第二条件。
3.4 聚合查询
将一列数据作为一个整体,进行纵向的计算。
COUNT
MAX
MIN
SUM
AVG
3.5 分组查询
语法:GROUP BY 分组字段;
注: 分组之后查询的字段:分组字段、聚合函数
WHERE 和 HAVING 的区别?
- WHERE 在分组之前进行限定,如果不满足条件,则不参与分组。HAVING在分组之后进行限定,如果不满足结果,则不会被查询出来
- WHERE 后不可以跟聚合函数,HAVING可以进行聚合函数的判断。
3.6 分页查询
语法:LIMIT 开始的索引,每页查询的条数;
公式:开始的索引 = (当前的页码 - 1) * 每页显示的条数
注: LIMIT 是一个MySQL 方言
3.7 多表查询
笛卡尔积:有两个集合A&B取这两个集合的所有组成情况。
注: 要完成多表查询,需要消除无用的数据
- 内连接
- 隐式内连接
- 显示内连接
- 外连接
- 左外连接
- 右外连接
- 子查询
四、DCL(管理用户&授权)
4.1 用户管理
添加用户
sql
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
删除用户
sql
DROP USER '用户名'@'主机名';
修改用户密码
sql
UPDATE USER SET PASSWORD = PASSWORD('新密码') WHERE USER = '用户名';
UPDATE USER SET PASSWORD = PASSWORD('123') WHERE USER = 'zhinian';
SET PASSWORD FOR '用户名'@'主机名' = PASSWORD('新密码');
SET PASSWORD FOR 'root'@'localhost' = PASSWORD('123456');
mysql中忘记了root用户的密码?
① 停止MYSQL服务
② 使用无验证方式启动MYSQL服务: mysqld --skip-grant-tables
③ 直接输入mysql命令,敲回车。就可以登录成功
④ use mysql;
⑤ update user set password = password('你的新密码') where user = 'root';
⑥ 重启MYSQL
查询用户
sql
USE myql;
SELECT * FROM USER;
注: 通配符%
表示可以在任意主机使用用户登录数据库
4.2 权限管理
查询权限
sql
-- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';
SHOW GRANTS FOR 'zhinian'@'%';
授予权限
sql
-- 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
-- 给只年用户授予所有权限,在任意数据库任意表上
GRANT ALL ON *.* TO 'zhinian'@'localhost';
撤销权限
sql
-- 撤销权限:
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
REVOKE UPDATE ON zhinian_db.`account` FROM 'zhinian'@'%';
五、约束
对表中的数据进行限定,保证数据的正确性、有效性和完整性。
非空约束: NOT NULL
某一列的值不能为NULL
sql
-- 建表时
CREATE TABLE employee (
`id` INT,
`name` VARCHAR(20) NOT NULL -- name为非空
);
-- 建表后
ALTER TABLE employee MODIFY `name` VARCHAR(20) NOT NULL;
-- 删除name的非空约束
ALTER TABLE employee MODIFY `name` VARCHAR(20);
唯一约束: UNIQUE
某一列的值不能重复
注: 唯一约束可以有NULL值,但是只能有一条记录NULL
sql
-- 建表时
CREATE TABLE employee (
`id` INT,
`phone_number` VARCHAR(20) UNIQUE -- 手机号
);
-- 建表后
ALTER TABLE employee MODIFY `phone_number` VARCHAR(20) UNIQUE;
-- 删除唯一约束
ALTER TABLE employee DROP INDEX `phone_number`;
主键约束: PRIMARY KEY
① 非空且唯一;②一张表只能有一个主键;③主键就是表中记录的唯一标识
sql
-- 建表时
CREATE TABLE employee (
`id` INT PRIMARY KEY,-- 给id添加主键约束
`name` VARCHAR(20)
);
-- 建表后
ALTER TABLE employee MODIFY `id` INT PRIMARY KEY;
-- 删除主键约束
ALTER TABLE employee DROP PRIMARY KEY;
外键约束: FOREIGN KEY
FOREIGN KEY,让表于表产生关系,从而保证数据的正确性。
sql
-- 建表时
create table 表名(
....
外键列
constraint 外键名称 foreign key (外键列名称) references 主表名称(主表列名称)
);
-- 建表后
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称);
-- 删除自动增长
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
-- 级联操作(级联更新:ON UPDATE CASCADE 、级联删除:ON DELETE CASCADE )
ALTER TABLE 表名 ADD CONSTRAINT 外键名称
FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表列名称) ON UPDATE CASCADE ON DELETE CASCADE;
字段自动增长: AUTO_INCREMENT
如果某一列是数值类型的,使用 AUTO_INCREMENT 可以来完成值得自动增长
sql
-- 建表时
CREATE TABLE employee (
`id` INT PRIMARY KEY AUTO_INCREMENT,-- 给id添加主键约束
`name` VARCHAR(20)
);
-- 建表后
ALTER TABLE employee MODIFY `id` INT AUTO_INCREMENT;
-- 删除自动增长
ALTER TABLE employee MODIFY `id` INT;
六、数据库事务
如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败。
开启事务: START TRANSACTION;
回滚:ROLLBACK;
提交:COMMIT;
七、数据库设计
一对一、一对多/多对一、多对多(借助中间表)
设计范式
设计数据库时,需要遵循的一些规范。要遵循后边的范式要求,必须先遵循前边的所有范式要求
设计关系数据库时,遵从不同的规范要求,设计出合理的关系型数据库,这些不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库冗余越小。
目前关系数据库有六种范式:第一范式(1NF)、第二范式(2NF)、第三范式(3NF)、巴斯-科德范式(BCNF)、第四范式(4NF)和第五范式(5NF,又称完美范式)。
- 第一范式(1NF):每一列都是不可分割的原子数据项
- 第二范式(2NF):在1NF的基础上,非码属性必须完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)
- 函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
- 例如:学号 ☞ 姓名。 (学号,课程名称)☞ 分数
- 完全函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值。
- 例如:(学号,课程名称)☞ 分数
- 部分函数依赖:A-->B, 如果A是一个属性组,则B属性值得确定只需要依赖于A属性组中某一些值即可。
- 例如:(学号,课程名称)☞ 姓名
- 传递函数依赖:A-->B, B -- >C . 如果通过A属性(属性组)的值,可以确定唯一B属性的值,在通过B属性(属性组)的值可以确定唯一C属性的值,则称 C 传递函数依赖于A
- 例如:学号 ☞ 系名,系名 ☞ 系主任
- 码:如果在一张表中,一个属性或属性组,被其他所有属性所完全依赖,则称这个属性(属性组)为该表的码,例如:该表中码为:(学号,课程名称)
- 主属性:码属性组中的所有属性
- 非主属性:除过码属性组的属性
- 函数依赖:A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A
- 第三范式(3NF):在2NF基础上,任何非主属性不依赖于其它非主属性(在2NF基础上消除传递依赖)
八、还原和备份
备份: mysqldump -u用户名 -p密码 数据库名称 > 保存的路径
还原: ① 登录数据库; ② 创建数据库;③ 使用数据库;④ 执行文件。source 文件路径
九、存储过程
sql
待续...
客户端图形化工具
- SQLYog
- Navicat
- DBeaverEE
- Sequel-Ace