- 在windows系统下,mysql数据库不区分大小写。
- 在linux系统下,mysql数据库区分大小写的!
即使你在Windows下使用MySQL,为了养成良好习惯,还是区分大小写,方便代码迁移!关键字全部使用大写
单行注释:
--
或者#
(#是MySQL特有的)多行注释:
/**/
备注:
[]
这在本文中表示可要可不要,这是博主自己的标记!- 表中的列称属性,也称字段、数据项
- 表中的行称元组,也称记录、分量
推荐阅读:
- 数据库系统概论
- Redis学习笔记
PS:从这张图,你应该就能猜到我是从哪里学习的MySQL了吧(●ˇ∀ˇ●)
DDL(Data Definition Language):数据定义语言,用来对数据库中的数据对象的组成和结构进行定义。
操作对象 | 操作方式 | ||
创建 | 删除 | 修改 | |
模式 | CREATE SCHEMA | DROP SCHEMA | —————— |
表 | CREATE TABLE | DROP TABLE | ALTER TABLE |
视图 | CREATE VIEW | DROP VIEW | —————— |
索引 | CREATE INDEX | DROP INDEX | ALTER INDEX |
#1.查询MySQL中所有的数据库
SHOW DATABASES;
#2.查询当前正在使用的数据库
SELECT DATABASE();
#1.普通创建(创建已经存在的数据库会报错)
CREATE DATABASE 数据库名称;
#2.创建并判断(该数据库不存在才创建)
CREATE DATABASE IF NOT EXISTS 数据库名称;
# 创建一个数据库,并指定字符集
create database itheima default charset utf8mb4;
#1.普通删除(删除不存在的数据库会报错)
DROP DATABASE 数据库名称;
#2.删除并判断(该数据库存在才删除)
DROP DATABASE IF EXISTS 数据库名称;
USE 数据库名称;
CREATE TABLE 表名(
字段名1 数据类型,
字段名2 数据类型,
...
字段名n 数据类型 -- 最后一行不能加逗号!
);
#1.查询当前数据库中所有表的名称
SHOW TABLES;
#2.查询表的结构
DESC 表名;
#3.查看建表语句(还能查看到建表时没写的默认参数)
show create table 表名;
#1.修改表名
ALTER TABLE 表名 RENAME TO 新的表名;
#2.添加一列
ALTER TABLE 表名 ADD 列名 数据类型 [ COMMENT 注释 ];
#3.修改某列(字段)数据类型
ALTER TABLE 表名 MODIFY 列名 新的数据类型;
#4.修改列名和数据数据类型
ALTER TABLE 表名 CHANGE 旧列名 新列名 新数据类型 [ COMMENT 注释 ];
#5.删除列(字段)
ALTER TABLE 表名 DROP 列名;
#1.普通删除(删除不存在的表会报错)
DROP TABLE 表名;
#2.删除并判断(该表存在才删除)
DROP TABLE IF EXISTS 表名;
#3.删除指定表并重新创建(相当于清空表中的数据)
TRUNCATE TABLE 表名;
DML(Data Manipulation Language):数据操作语言,用来对数据库库中表的数据进行增、删、改
#1.给指定列添加数据
INSERT INTO 表名(列名1,[列名2],[...)VALUES(值1,[值2],[...]); -- 值1对应列名1,...
#给全部列添加数据(相当于添加新的一行)
INSERT INTO 表名[所有列名] VALUES(值1,值2,...);
-- []中表示可以省略,省略时默认按顺序填写字段,不建议省略
#3.批量添加数据
INSERT INTO 表名(列名1,[列名2],[...])VALUES(值1,值2,...),[(值1,值2,...)],[...];
#批量给全部列添加数据(相当于添加新的多行)
INSERT INTO 表名[所有列名] VALUES(值1,值2,...),(值1,值2,...),...;
#1.修改数据
UPDATE 表名 SET 列名1=值1,[列名2=值2],[...][WHERE 条件];
-- 注意:如果不使用WHERE条件,会将表中所有数据进行修改!
DELETE FROM 表名 [WHERE 条件];
-- 注意:如果不使用WHERE条件,会将表中所有的数据删除!
DQL(Data Query Language):数据查询语言,用来查询数据库中表的数据。
DQL编写顺序:
#查询语法:
SELECT 字段列表
FROM 表名列表
WHERE 条件列表
GROUP BY 分组字段
HAVING 分组后条件
ORDER 排序字段
LIMIT 分页限定
DQL执行顺序:
#1.查询字段
SELECT 字段1,[字段2],[...] FROM 表名;
SELECT * FROM 表名 ;-- 查询表中所有字段
-- 注意:查询表中所有字段虽然可以使用*,但是推荐使用字段列表(更加清晰)
#2.去除重复记录
SELECT DISTINCT 字段1,[字段2],[...] FROM 表名;
#3.起别名
SELECT 字段1 AS 别名1,[字段2 AS 别名2],[...] FROM 表名;
-- 注意:起别名的关键字AS可以省略,但是别名和字段名要有空格隔开
AS
:可以给字段或表起别名,通常该关键字可以省略,但是要别名和 字段/表 要用空格隔开
SELECT 字段1,[字段2],[...] FROM 表名 WHERE 条件列表;
条件运算符:
模糊查询使用关键字
LIKE
,同时需要了解常用的通配符:
%
(百分号):表示任意长度的字符串,例如:a%表示,以a开始后面接任意长度的字符串_
(下划线):表示任意单个字符,例如:a_表示,以a开始后面只能接一个字符
示例:
#从Student表中查询姓马的人
SELECT * FROM Student WHERE Name LIKE '马%';
#从Student表中查询名字第二个字是花的人
SELECT * FROM Student WHERE Name LIKE '_花%';
##从Student表中查询名字中含有疼字的人
SELECT * FROM Student WHERE Name LIKE '%疼%'
排序查询使用关键字
ORDER BY
,同时需要了解常用的排序方式:
ASC
(ascending order):升序排序(MySQL默认的排序方式)DESC
(descending order):降序排序备注:升序、降序是自上而下的。当使用两个排序条件时,只有前面的条件值一样时,才会根据第二个排序条件进行排序
SELECT 字段1,[字段2],[...] FROM 表名 ORDER BY 排序字段1 排序方式,[排序字段2 排序方式],[...]
-- 注意:排序字段1不等于字段1,排序字段1是从前面的查询的字段中选中一个出来,然后按照排序方式显示出来
示例:
#从sudent表中查询学生信息,按照年龄进行升序排列
SELECT * FROM student ORDER BY Sage [ASC];
#从sudent表中查询学生信息,按照年龄进行降序排列
SELECT * FROM student ORDER BY Sage DESC;
#从sudent表中查询学生信息,按照数学成绩进行升序排列,如果遇到多个学生数学成绩一样,就按找英语成绩进行降序排列
SELECT * FROM student ORDER BY Math DESC,English ASC;
在学习分组查询前,我们需要先了解聚合函数,聚合函数的作用就是:是查询功能更加强大,同时方便用户使用。
函数名 | 功能 |
---|---|
`COUNT([DISTINCT | ALL] 列名)` |
`MAX([DISTINCT | ALL] 列名)` |
`MIN([DISTINCT | ALL] 列名)` |
`SUM([DISTINCT | ALL] 列名)` |
`AVG([DISTINCT | ALL] 列名)` |
备注:null不参与所有聚合函数的运算!!!
COUNT(*)
表示统计表的总行数,也可以使用主键的字段名
DISTINCT
:去除重复的值,即遇到重复的值不会加1ALL
:不去重(MySQL默认)#聚合函数语法:
SELECT 聚合函数名([DISTINCT|ALL] 列名) FROM 表;
示例:
#从student表中查询所有学生的个数
SELECT COUNT(*) FROM student;-- 或者使用:SELECT COUNT(Sno) FROM student;
#从student表中查询参加了考试的人数
SELECT COUNT(Score) FROM student;-- 没参加考试,成绩就为null
#查询student表中,数学成绩最高分
SELECT MAX(Math) FROM student;
#查询student表中,数学成绩最低分
SELECT MIN(Math) FROM student;
#查询student表中,数学成绩平均分
SELECT AVG(Math) FROM student;
#查询student表中,全班数学成绩的总分
SELECT SUM(Math) FROM student;
分组查询使用关键字
GROUP BY
,可以让查询结果按照某一列或多列的值进行分组。分组的目的:为了细化聚合函数的作用对象
#分组查询的语法:
SELECT 字段列表 FROM 表名 [WHERE 分组前条件限定] GROUP BY 分组字段名 [HAVING 分组后条件过滤];
注意:分组之后,查询的字段为聚合函数和分组字段,查询其他字段无任何意义!!!原因很简单,假如我们查询了其他字段,例如我们对性别进行了分组,然后查询名字,那么它最终只会显示两个名字,我们本意查名字是查全部名字,使用分组后只有两个,和我们的本意相违背
WHERE和HAVING的区别:
示例:
#查询男同学和女同学各自的数学平均分
SELECT sex, AVG(math) FROM stu GROUP BY sex;
SELECT name, sex, AVG(math) FROM stu GROUP BY sex; -- 这里查询name字段就没有任何意义
#查询男同学和女同学各自的数学平均分,以及各自人数
SELECT sex, AVG(math),COUNT(*) FROM stu GROUP BY sex;
#查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组
SELECT sex, AVG(math),COUNT(*) FROM stu WHERE math > 70 GROUP BY sex;
#查询男同学和女同学各自的数学平均分,以及各自人数,要求:分数低于70分的不参与分组,分组之后人数大于2个的
SELECT sex, AVG(math),COUNT(*) FROM stu WHERE math > 70 GROUP BY sex HAVING COUNT(*) > 2;
分页查询使用关键字
LIMIT
,该关键字是MySQL数据库的方言,在Oracle中分页查询使用关键字ROWNUMBER
,SQL Server分页查询使用关键字TOP
。
SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询条目数;
注意:索引是从0开始的,和数组中的索引是一样的
示例:
#查询student表中前三条记录
SELECT * FROM student LIMIT 0,3;
在实际工作中多表查询是最最最常见的,在学习多表查询前需要先了解一下关系代数。
推荐阅读:数据库学习之关系代数
#查询多张表的所有数据
SELECT * FROM 表1,表2,... [WHERE 条件];
-- 查询结果是多张表的笛卡尔积
内连接是查询多张表的交集数据。它是从多张表中查询出满足条件的待查询字段数据,就是多张表先要满足给定的条件,等条件筛选后再进行查询。
#隐式内连接
SELECT 字段列表 FROM 表1,表2… WHERE 条件;
#显示内连接
SELECT 字段列表 FROM 表1 [INNER] JOIN 表2 [JOIN ...] ON 条件;
外连接就算查询一个表的所有数据和满足条件的其他表数据。
外连接分为:
- 左外连接:查询A集合的所有数据以及满足条件的B集合数据
- 右外连接:查询B集合的所有数据以及满足条件的A集合数据
备注:两者可以互换
#左外连接
SELECT 字段列表 FROM 表1 LEFT [OUTER] JOIN 表2 ON 条件;
#右外连接
SELECT 字段列表 FROM 表1 RIGHT [OUTER] JOIN 表2 ON 条件;
查询中嵌套查询,我们称之为嵌套查询也称子查询。使用子查询可以减少SQL语句。
子查询返回的结果是单个值(数字、字符串、日期等),最简单的形式,这种子查询称为标量子查询。
子查询返回的结果是一列(可以是多行),这种子查询称为列子查询
子查询返回的结果是一行(可以是多列),这种子查询称为行子查询。
子查询返回的结果是多行多列,这种子查询称为表子查询。
子查询根据查询结果不同,作用不同:
子查询语句结果是单行单列,子查询语句作为条件值,使用 = 、 != 、 > 、 < 等进行条件判断
SELECT 字段列表 FROM 表 WHERE 字段名 条件符 (子查询);
-- 如果条件判断使用or则是多行单列
-- 如果字段列表使用*则是多行多列
子查询语句结果是多行单列,子查询语句作为条件值,使用 IN
等关键字进行条件判断
SELECT 字段列表 FROM 表 WHERE 字段名 IN (子查询);
-- 如果字段列表使用*则是多行多列
子查询语句结果是多行多列,子查询语句作为虚拟表
SELECT 字段列表 FROM (子查询) WHERE 条件;
示例:
#单行单列
-- 查询 '财务部'的员工的姓名
select name emp where id = (select did from dept where dname = '财务部');
#多行单列
-- 查询 '财务部' 或者 '市场部' 的员工的部门姓名
select name from emp where dep_id in (select did from dept where dname = '财务部' or dname = '市场部');
#多行多列
-- 查询入职日期是 '2011-11-11' 之后的员工信息,使用*结果是多行多列
select * from emp where join_date > '2011-11-11' ;
-- 将上面语句的结果作为虚拟表和dept表进行内连接查询
select * from (select * from emp where join_date > '2011-11-11' ) t1, dept where t1.dep_id = dept.did;
DCL(Data Control Language):数据控制语言,用来定义数据库中的访问权限和安全即别,以及创建用户
备注:这类SQL开发人员用的比较少,主要是DBA(数据库管理员)使用
# 查询用户
select * from mysql.user;
# 创建用户
CREATE USER '用户名'@'主机名' IDENTIFIED BY '密码';
# 修改用户密码
ALTER USER '用户名'@'主机名' IDENTIFIED WITH mysql_native_password BY '新密码' ;
# 删除用户
DROP USER '用户名'@'主机名' ;
MySQL中定义了很多种权限,但是常用的就以下几种:
# 查询权限
SHOW GRANTS FOR '用户名'@'主机名' ;
# 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
# 撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
约束就是对表中列上的数据进行相应的约束,确保数据的正确性,有效性和完整性。约束语句可归为DDL。
SQL约束分类:
约束名 | 作用 | 关键字 |
---|---|---|
非空约束 | 保证列的所有数据不能为null | NOT NULL |
唯一约束 | 保证列的所有数据不重复 | UNIQUE |
主键约束 | 保证列的所有数据非空且唯一(主键是一行数据的唯一标识) | PRIMARY KEY |
检查约束 | 保证列中的值满足某一条件 | CHECK |
默认约束 | 设置列中数据的默认值 | DEFAULT |
外键约束 | 保证数据的一致性和完整性(外键用来连接两个表) | FOREIGN KEY |
AUTO_INCREMENT
:自动增长,当列是数字类型并且具有唯一约束时可以使用自增约束
注意:
MySQL不支持检查约束!!!
默认约束只有在不给值时才会采用默认值,如果给了null,那值就是null值(null也是一个值,只是为空而已)
外键:用来让两张表的数据之间建立连接,从而保证数据的一致性和完整性
外键约束的常用作用:
示例:
# 建表时添加约束
-- 员工表emp
CREATE TABLE emp (
id INT PRIMARY KEY AUTO_INCREMENT, -- 员工id,主键且自增长
ename VARCHAR(50) NOT NULL UNIQUE, -- 员工姓名,非空并且唯一
joindate DATE NOT NULL , -- 入职日期,非空
salary DOUBLE(7,2) NOT NULL , -- 工资,非空
bonus DOUBLE(7,2) DEFAULT 0, -- 奖金,如果没有奖金默认为0
/*[CONSTRAINT] [外键名称] FOREIGN KEY(外键列名) REFERENCES 主表(主表列名)*/
CONSTRAINT deptID FOREIGN KEY(id) REFERENCES dept(id)
-- 注意:使用外键约束,必须先创建主表,添加、删除数据时也是一样,否则会报错
);
# 建表后添加约束(只能一次给一个字段的添加一个约束)
#非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 NOT NULL; -- 添加非空约束
ALTER TABLE 表名 MODIFY 字段名 数据类型; -- 删除非空约束
#唯一约束
ALTER TABLE 表名 MODIFY 字段名 数据类型 UNIQUE; -- 添加唯一约束
ALTER TABLE 表名 DROP INDEX 字段名; -- 删除唯一约束
#主键约束
ALTER TABLE 表名 ADD PRIMARY KEY(字段名); -- 添加主键约束
ALTER TABLE 表名 DROP PRIMARY KEY; -- 删除主键约束
#默认约束
ALTER TABLE 表名 ALTER 字段名 SET DEFAULT 默认值; -- 设置默认值约束
ALTER TABLE 表名 ALTER 字段名 DROP DEFAULT; -- 删除默认值约束
#外键约束
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN KEY (外键字段名称) REFERENCES 主表名称(主表字段名称); -- 添加外键约束
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称; -- 删除外键约束
数据库的事务(Transaction)是一种机制、一个操作序列,这些操作要么全做,要么全不做,是一个不可分割的工作单位,同时事务也是并发控制的基本单位。
注意:MySQL的事务是跟引擎有直接关系的,一般带事务的MySQL使用的引擎都是InnoDB,MySQL5.5版本后默认都是使用InnoDB存储引擎
事物的ACID特性:
# 查看事务的提交方式
SELECT @@autocommit ;
# 设置事务的提交方式(0表示手动提交事务)
SET @@autocommit = 0 ;
# 开启事务
START TRANSACTION 或 BEGIN ;
#开启事务
BEGIN; -- 或者使用START TRANSACTION开启事务
#提交事务
COMMIT;
#回滚事务
ROLLBACK; -- 恢复到事物开始前
备注:MySQL的事务默认是自动提交的,Oracle的事务默认是手动提交的
SET @@AUTOCOMMIT = 0|1
:设置事务的默认提交方式
1
:表示事务自动提交0
:表示事务手动提交SELECT @@AUTOCOMMIT
:查询事务的默认提交方式
示例:
begin;
# --------------开始事务-----------------------
update account set money = money - 500 where name = "张三";
if((select money from account where name = "张三")<500) then
rollback; -- 撤销掉开始事物后的更新操作,将表恢复到事物前的状态
else -- 如果张三的账户余额大于等于500就进行转账操作
update account set money = money + 500 where name = "李四";
# --------------结束事务-----------------------
commit; # 事务执行过程中没有出现异常,则直接提交事务,数据库更新数据
rollback; # 事务执行过程中没有出现异常,回滚事务(回答事务执行前的状态)
MySQL中事务拥有四种隔离级别,在并发场景下,不同的隔离级别存在不同的问题
# 查看事务的隔离级别
SELECT @@TRANSACTION_ISOLATION;
# 设置事务的隔离级别
SET [ SESSION | GLOBAL ] TRANSACTION ISOLATION LEVEL { READ UNCOMMITTED |
READ COMMITTED | REPEATABLE READ | SERIALIZABLE }
-- 示例
set session transaction isolation level 设置事务隔离级别
# 设置read uncommitted级别:
set session transaction isolation level read uncommitted;
# 设置read committed级别:
set session transaction isolation level read committed;
# 设置repeatable read级别:
set session transaction isolation level repeatable read;
# 设置serializable级别:
set session transaction isolation level serializable;
设存在一个事务A,一个事务B
从上往下,隔离强度逐渐增强,性能逐渐变差。MySQL默认的隔离级别是可重复读,而Oracle的默认隔离级别是读已提交
参考文章:
- Mysql各种存储引擎对比总结(常用几种) - 知乎 (zhihu.com)
必备站点:
- MySQL 教程 (w3schools.cn)
- MySQL 教程 | 菜鸟教程 (runoob.com)
最后在此致谢黑马,本笔记是依据黑马程序员 MySQL数据库入门到精通-哔哩哔哩编写的(其中的一些截图也是摘抄自黑马的),这个课程质量不错,讲的也挺细,值得推荐,最后送还在迷茫的你一句话“肝就完了”