数据库笔记(1)
文章目录
- 1.SQL的通用语法
- 2.四类SQL语句
- 2.1DDL语句
- 2.2.1数据库操作
- 2.1.2表操作
- 2.2DML语句
- 2.2.1添加数据(INSERT)
- 2.2.2修改数据(UPDATE)
- 2.2.3删除数据(DELETE)
- 2.3DQL语句
- 2.3.1DQL语法
- 2.3.2基本查询
- 2.3.3条件查询
- 2.3.4分组查询
- 2.3.5排序查询
- 2.3.6分页查询
- 2.3.7DQL语句的执行顺序
- 2.4DCL语句
- 2.4.1用户管理
- 2.4.2权限控制
- 4.函数
- 4.1字符串函数
- 4.2数值函数
- 4.3日期函数
- 4.4流程函数
- 5.约束
- 5.1约束的分类
- 5.2外键约束
- 5.2.1添加外键
- 5.2.2外键的删除和更新行为
1.SQL的通用语法
- SQL语句可以单行或者多行书写,以分号结尾
- SQL语句可以使用空格/缩进来增强语句的可读性
- MySQL数据库的SQL语句不区分大小写,关键字建议使用大写
- 注释:
- 单行注释:
-- 注释内容
或# 注释内容
(MySQL特有) - 多行注释:
/*注释内容*/
- 单行注释:
2.四类SQL语句
DDL语句
-Data Definition Language-数据定义语言,用来定义数据库对象(数据库,表,字段)DML语句
-Data Manipulation Language-数据操作语句,用来对数据库表中的数据进行增删改DQL语句
-Data Query Language-数据查询语句,用来查询数据库中表的记录DCL语句
-Data Control Language-数据控制语句,用来创建数据库用户,控制数据库的访问权限
2.1DDL语句
DDL:(Data Definition Language)-数据定义语言,用来定义数据库对象(数据库,表,字段)
2.2.1数据库操作
- 查询所有数据库
SHOW DATABASE;
- 查询当前数据库
SELECT DATABASE();
- 创建
CREATE DATABASE[IF NOT EXISTS]数据库名[DEFAULT CHARSET字符集][COLLATE排序规则];
- 删除
DROP DATABASE[IF EXISTS]数据库名;
- 使用
USE 数据库名;
2.1.2表操作
- 查询
- 查询当前数据库所有表
SHOW TABLES;
- 查询表结构
DESC 表名;
- 查询指定表的建表语句
SHOW CREATE TABLE 表名;
- 创建表
CREATE TABLE 表名(字段1 字段类型[COMMENT 字段1注释],字段2 字段类型[COMMENT 字段2注释],字段3 字段类型[COMMENT 字段3注释],...字段n 字段类型[COMMENT 字段n注释]
)[COMMENT 表注释];
- 修改表结构
-- 添加字段
ALTER TABLE 表名 ADD 字段名 类型(长度)[COMMENT 注释][约束]
-- 修改字段类型
ALTER TABLE 表名 MODIFY 旧字段名 新字段名 类型(长度)[COMMENT 注释][约束]
-- 修改字段名和字段类型
ALTER TABLE 表名 CHANGE 旧字段名 新字段名 类型(长度)[COMMENT 注释][约束]
-- 删除字段
ALTER TABLE表名 DROP COLUMN字段名
-- 修改表名
RENAME TABLE 表名 TO 新表名
- 删除表结构
DROP TABLE [IF EXISTS]表名;
2.2DML语句
DML:DML的英文全称是Data Manipulate Language(数据操作语言),用于对数据库中表的记录进行增删改操作
2.2.1添加数据(INSERT)
- 指定字段添加数据:INSERT INTO 表名(字段名1,字段名2) VALUES(值1,值2)
- 全部字段添加数据:INSERT INTO 表名 VALUES(值1,值2…)
- 批量添加数据(指定字段):INSERT INTO表名(字段名1,字段名2) VALUES(值1,值2)(值1,值2)
- 批量添加数据(全部字段):INSERT INTO表名 VALUES1(值1,值2…)(值1,值2…)
-- DML:数据操作语言
-- DML:插入数据:insert
-- 1.为tb_staff表中的username,name,gender字段插入值
-- 使用now()函数把当前时间赋值给创建时间和更新时间
insert into tb_staff(username,name,gender,create_time,` update_time`)
values ('liangmou2121','梁某',1,now(),now()); -- 2.为tb_staff表中的所有字段插入值
insert into tb_staff values(null,'limou3434','123','李某',1,'1.jpg',2,'2004-09-23',now(),now()); -- 3.批量为tb_staff表中的username,name,gender字段插入数据
insert into tb_staff(username,name,gender,create_time,` update_time`)
values ('zhangsan','张三',1,now(),now()),('lisi','李四',2,now(),now());
注意:
1)插入数据时,指定的字段顺序需要与值的顺序是一一对应的
2)字符串和日期型数据应该包含在引导中
3)插入的数据大小,应该在字段的规定范围内
2.2.2修改数据(UPDATE)
- 修改数据:UPDATE 表名 set 字段名1=值1,字段名2=值2,…
[WHERE 条件]
-- DML:更新数据
-- 1.将tb_staff表中id为1员工的姓名name字段更新为张三
-- 更新时间也需要修改
update tb_staff set name ='张三' ,` update_time` = now() where id = 1; -- 2.将tb_staff表的所有员工的入职日期更新为'2010-01-01'
update tb_staff set entrydate = '2010-01-01',` update_time` = now();
注意:修改语句的条件可以有,也可以没有,如果没有条件,则会修改整张表的数据
2.2.3删除数据(DELETE)
- 删除数据:DELETE FROM 表名
[WHERE 条件]
-- DML:删除数据-delete
-- 1.删除tb_staff表中id为1的员工
delete from tb_staff where id = 1; -- 2.删除tb_staff表中的所有员工
delete from tb_staff;
注意:1)DELETE语句的条件可以有,也可以没有,如果没有条件,则会删除整张表的所有数据
2)DELETE语句不能删除某一个字段的值,如果要操作可以使用UPDATE,将该字段的值置为NULL
2.3DQL语句
DQL:DQL英文全称是Data Query Language(数据查询语言),用来查询数据库表中的记录
关键字:SELETE
2.3.1DQL语法
- 基本查询
- SELECT:字段列表
- fFROM:表名列表
- 条件查询
- WHERE:条件列表
- 分组查询
- GROUP BY:分组字段列表
- HAVING:分组后条件列表
- 排序查询
- ORDER BY:排序字段列表
- 分页查询
- LIMIT:分页参数
2.3.2基本查询
基本查询的语法:
- 查询多个字段:SELECT 字段1,字段2,字段3 FROM 表名;
- 查询所有字段(通配符):SELECT * FROM 表名;
- 设置别名:SEELCT 字段1
[AS 别名1]
,字段2[AS 别名2]
from 表名; - 去除重复记录:SEELECT DISTINCT 字段列表 FROM 表名;
-- 基本查询
-- 1.查询指定字段,name,workid,age,返回
SELECT name,workid,age FROM emp; -- 2.查询所有字段返回
-- 在工作中尽量使用所有字段,而不使用*,*不够直观
SELECT workid, name, id, gender, idcard, age, wordaddress, entrydate FROM emp;
SELECT * FROM emp; -- 3.查询所有员工的地址,起别名
-- 给工作地址起名别为工作地址
SELECT wordaddress as '工作地址' FROM emp;
SELECT wordaddress 工作地址 FROM emp; -- 4.查询公司所有员工的上班地址(不重复)-去除重复记录,使用distinct关键字
SELECT DISTINCT wordaddress FROM emp;
注意:1)*
代表所有字段,在实际开发中尽量少用(不直观,影响效率)
2)as关键字可以省略
2.3.3条件查询
条件查询的语法:
- 条件查询:SELECT字段列表 FROM 表名 WHERE 条件列表;
比较运算符
>
-大于>=
-大于等于>
-小于<=
-小于等于=
-等于<>
或者!=
-不等于between...and
-在某个范围之内(含最小,最大值)in(...)
-在in之后的列表中的值,多选一like 占位符
-模糊匹配(_
匹配单个字符,%
匹配任意个字符)is null
-是nulland或&&
-并且(多个条件同时成立)or或||
-或者(多个条件任意一个成立)not或!
-非,不是
-- 条件查询
-- 1.查询年龄等于30的员工信息
SELECT * FROM emp WHERE age = 30; -- 2.查询年龄小于30的员工信息
SELECT * FROM emp WHERE age < 30; -- 3.查询年龄小于等于30的员工信息
SELECT * FROM emp WHERE age <= 30; -- 4.查询没有身份证号的员工信息
SELECT * FROM emp WHERE idcard is null; -- 5.查询有身份证号的员工信息
SELECT * FROM emp WHERE idcard is not null; -- 6.查询年龄不等于25的员工信息
SELECT * FROM emp WHERE age != 25;
SELECT * FROM emp WHERE age <> 25; -- 7.查询年龄在25岁(包含)到30岁(包含)之间的员工信息
SELECT * FROM emp WHERE age >= 25 and age <= 30 ;
SELECT * FROM emp WHERE age >= 25 && age <= 30 ;
SELECT * FROM emp WHERE age between 25 and 30; -- 8.查询性别为女且年龄小于35的员工信息
SELECT * FROM emp WHERE gender = '女' and age < 35;
SELECT * FROM emp WHERE gender = '女' && age < 35; -- 9.查询年龄等于20或25或30的员工信息
SELECT * FROM emp WHERE age = 20 || age = 25 || age = 30;
SELECT * FROM emp WHERE age = 20 or age = 25 or age = 30;
SELECT * FROM emp WHERE age IN(20,25,30); -- 10.查询名字为两个字的员工信息
SELECT * FROM emp WHERE name like '__'; -- 11.查询身份证最后一位为x的员工信息
SELECT * FROM emp WHERE idcard like '%X';
2.3.4分组查询
聚合函数:将一列数据作为一个整体,进行纵向计算
语法1:SELECT 聚合函数(字段列表) FROM 表名;
count
:统计数量max
:最大值min
:最小值2avg
:平均值sum
:求和
-- 聚合函数
-- 1.统计该企业的员工数量
SELECT COUNT(*) FROM emp;
SELECT COUNT(id) FROM emp; -- 2.统计该企业员工的平均年龄
SELECT avg(age) FROM emp; -- 3.统计该企业员工的最大年龄
SELECT max(age) FROM emp; -- 4.统计该企业员工的最小年龄
SELECT min(age) FROM emp;
注意:
- null值不参与所有聚合函数运算
- 统计数量可以使用:count(
*
),count(字段),count(常量),推荐使用count(*
)
语法2:分组查询 SELECT 字段列表 FROM 表名[WHERE 条件]
GROUP BY 分组字段名 [HAVING 分组后过滤条件]
-- 分组查询
-- 1.根据性别分组,统计男性员工和女性员工的数量 SELECT gender,count(*) FROM emp GROUP BY gender; -- 2.根据性别分组,统计男性员工和女性员工的平均年龄
SELECT gender,avg(age) FROM emp GROUP BY gender; -- 3.查询年龄小于30的员工,并根据工作地址分组,获取员工数量大于3的工作地址
SELECT wordaddress,count(*) FROM emp WHERE age < 30 GROUP BY wordaddress having count(*) >= 2;
注意:where和having的区别
- 执行时机不同:where是分组之前进行过滤,不满足where条件,不参与分组,而having是分组之后对结果进行过滤
- 判断条件不同,where不能对聚合函数进行判断,而having可以
- 分组之后,查询的字段一般为聚合函数和分组字段,查询其他字段无任何意义
- 执行顺序:where>聚合函数>having
2.3.5排序查询
条件查询:SELECT 字段列表 FROM 表名[WHERE 条件列表]``[GROUP BY 分组字段]
ORDER BY 字段1 排序方式1,字段2,排序方式2…;
排序方式:
- ASC:升序(默认值)
- DESC:降序
-- 排序查询
-- 1.根据年龄对公司员工进行升序排序
SELECT * FROM emp ORDER BY age asc; -- 2.根据入职时间对员工进行降序排序
SELECT * FROM emp ORDER BY entrydate DESC; -- 3.根据年龄对公司的员工进行升序排序,年龄相同,再按照入职时间进行降序排序
SELECT * FROM emp ORDER BY age ASC,entrydate DESC;
注意:如果是多字段排序,当第一个字段值相同时,才会根据第二个字段进行排序
2.3.6分页查询
分页查询:SELECT 字段列表 FROM 表名 LIMIT 起始索引,查询记录数;
起始索引:从哪一条记录往后进行查询(从0开始)
起始索引 = (页码 - 1) *
每页展示的记录数
查询记录数:每一页需要展示多少条数据
-- 分页查询
-- 1.查询第一页员工数据,每页展示10条记录
SELECT * FROM emp LIMIT 0,10;
-- 起始索引从0开始,0可以省略
SELECT * FROM emp LIMIT 10;
-- 2.查询第2页员工数据,每页展示10条记录-起始索引(页码-1)*查询的记录数 (2-1)*10SELECT * FROM emp LIMIT 10,10;
注意:
- 起始索引从0开始,起始索引=(查询页码-1)
*
每页显示记录数 - 分页查询时数据库的方言,不同的数据库有不同的实现,在MySQL中是LIMIT
- 如果查询的是第一页的数据,起始索引可以省略,直接简写为limit 查询记录数
2.3.7DQL语句的执行顺序
编写顺序:
SELECT
-字段列表FROM
-表名列表WHERE
-条件列表GROUP BY
-分组字段列表HVAING
-分组后条件列表ORDER BY
-排序字段列表LIMIT
-分页参数
执行顺序:
FROM
-表名列表WHERE
-条件列表GROUP BY
-分组字段列表HVAING
-分组后条件列表SELECT
-字段列表ORDER BY
-排序字段列表LIMIT
-分页参数
2.4DCL语句
DCL语句-Data Control Language-数据控制语句,用来创建数据库用户,控制数据库的访问权限
2.4.1用户管理
- 查询用户
USE mysql;SELECT * FROM user;
- 创建用户
CREATE USER '用户名'@'机主名' INDENTIFIED by 2'密码';
- 修改用户密码
ALTER USER '用户名'@'机主名' INDENTIFIED BY '新密码';
- 删除用户
DROP USER '用户名'@'机主名';
例:
-- CML语句
-- 创建用户itcase,只能够在当前机主localhost访问,密码123456
CREATE USER 'itcase'@'localhost' IDENTIFIED BY '123456'; -- 创建用户heima,可以在任意主机访问数据库,密码123456
CREATE USER 'heima'@'%' IDENTIFIED BY '123456'; -- 修改用户heima的访问密码1234
ALTER USER 'heima'@'%' IDENTIFIED BY '1234'; -- 删除itacse@localhost用户
DROP USER 'itcase'@'localhost'; -- 删除黑马@localhost用户
DROP USER 'heima'@'%
注意:
- 主机名可以用
%
通配 - 这类SQL开发人员操作的比较少,主要是DBA(Database Administrator 数据库管理员)使用
2.4.2权限控制
ALL,ALL PRIVILEGES
-所有权限SELECT
-查询数据INSERT
-插入数据UPDATE
-修改数据DELETE
-删除数据ALTER
-修改表DROP
-删除数据库/表/视图CREATE
-创建数据库/表
- 查询权限
SHOW GRANTS FOR '用户名'@'主机名';
- 授予权限
GRANT 权限列表 ON 数据库名.表名 TO '用户名'@'主机名';
- 撤销权限
REVOKE 权限列表 ON 数据库名.表名 FROM '用户名'@'主机名';
注意:
- 多个权限之间,使用逗号分隔
- 授权时,数据库名和表名可以使用
*
进行通配,代表所有
4.函数
4.1字符串函数
CONCAT(S1,S2...,Sn)
-字符串拼接,将S1,S2…Sn拼接成一个字符串LOWER(str)
-将字符串str全部转为小写UPPER(str)
-将字符串全部转为大写LPAD(str,n,pad)
-左填充,用字符串pad对str的左边进行填充达到n个字符串长度RPAD(str,n,pad)
-右填充,用字符串pad对str的右边进行填充达到n个字符串长度TRIM(str)
-去掉字符串头部和尾部的空格SUBSTRING(str,start,len)
-返回字符串str从start位置七的len个长度的字符串
SELECT 函数(函数参数);
例:
-- concat函数
-- 结果为Hello Mysql
SELECT CONCAT('Hello',' Mysql'); -- lower
-- 结果为liangmou
SELECT LOWER('LIANGMOU'); -- lpad
-- 结果为'___01'
SELECT LPAD('01',5,'_'); -- rpad
-- 结果为'01___'
SELECT RPAD('01',5,'_'); -- substring
-- 从第一个字符H开始截取 截取5个字符 结果为Hello
SELECT SUBSTRING('Hello Mysql',1,5);-- 把所有员工的工号更新为5位,不够的用0补齐
UPDATE emp SET workid = LPAD(workid,5,'0');
4.2数值函数
CELF(x)
-向上取整FLOOR(X)
-向下取整MOD(X,Y)
-返回x/y的模RAND()
-返回0~1的随机数ROUND(x,y)
-求参数x四舍五入的值,保留y位小数
-- ceil-向上取整
-- 结果为2
SELECT CEIL(1.5); -- floor-向下取整
-- 结果为1
SELECT FLOOR(1.5); -- mod(1,2)-取1/2的模
-- 结果为1
SELECT MOD(1,2); -- rand-生成0~1之间的随机数
SELECT RAND(); -- round(x,y) -对x四舍五入保留y位小数
-- 结果为0.5710
SELECT ROUND(0.5709658,4);-- 通过数据库函数,生成一个六位数的随机验证码
SELECT ROUND(RAND() * 1000000,0);
4.3日期函数
CURDATE()
-返回当前日期CURTIME()
-返回当前时间NOW()
-返回当前日期和时间YEAR(date)
-获取指定date的年份MONTH(date)
-获取指定date的月份DAY(date)
-获取指定date的日期DATE_ADD(date,INTERRVAL expr type)
-返回一个日期/时间加上一个时间间隔expr后的时间值DATEDIFF(date1,date2)
-返回起始时间date1和结束时间date2之间的天数
-- 日期函数
-- curdate(); 获取当前日期 2025-05-06SELECT CURDATE();
-- curtime(); 获取当前时间 08:09:36SELECT CURTIME();
-- now(); 获取当前日期和时间 2025-05-06 08:10:29SELECT NOW(); -- YEAR(); MONTH(); DAY();
-- 获取年 月 日
-- 传递NOW()函数获取当前的年 月 日
SELECT YEAR(NOW()); -- 2025 -- DATE_ADD();
-- 间隔的时间单位可以是 YEAR MONTH DAY
SELECT DATE_ADD(NOW(),INTERVAL 60 DAY ); -- DATEDIFF
-- 返回结果为第一个参数减去第二个参数 如果第一个参数比较小会出现负数
SELECT DATEDIFF('2025-05-01','2025-04-01'); --30-- 查询所有员工的入职天数,并根据入职天数倒序排序
SELECT name,DATEDIFF(CURDATE(),entrydate) AS entrydates FROM emp ORDER BY entrydates DESC ;
4.4流程函数
流程函数用于在SQL语句中实现条件筛选,从而提高语句的效率
IF(value,t,f)
-如果value为true,则返回t,否则返回fIFNULL(value1,value2)
-如果value不为空,返回value1,否则返回value2CASE WHEN[val1] THEN[res1]...ELSE[default] END
-如果val1为true,返货resl1,…否则返回default默认值CASE[expr] WHEN[val1] THEN[res1]...ELSE[default] END
-如果expr的值等于val1,返回res1,…否则返回default默认值2
-- 流程控制函数
-- IF();
-- 一般来说,第一个参数为一个条件表达式
SELECT IF(true,'Ok','Error'); -- IFNULL(val1,val2);
-- 共有两个参数,判断第一个参数是否为为空,如果不为空返回val1,如果为空则返回val2
SELECT IFNULL(NULL,'default'); -- CASE WHEN THEN ELSE END
-- 查询员工表的姓名和工作地址(北京/上海-一线城市,其他-二线城市)
SELECT name, (CASE wordaddress WHEN '广州' THEN '一线城市' WHEN '杭州' THEN '一线城市' ELSE '二线城市' END) AS 工作地址
FROM emp;
5.约束
约束是作用与表中字段上的规则,用于限制存储在表中的数据,可以用于保证数据的正确性,有效性和完整性
5.1约束的分类
- NOT NULL-
非空约束
-限制该字段所有数据不能为NULL - UNIQUE-
唯一约束
-保证该字段中所有数据都是唯一的,不重复的 - PRIMARY KEY-
主键约束
-主键是一行数据的唯一标识,要求非空且唯一 - DEFAULT-
默认约束
-保存数据时,如果未指定该字段的值,则使用默认值 - CGECK-
检查约束
-保证字段值满足某一个条件 - FOREIGN KEY-
外键约束
-用来让两张表之间建立连接,保证数据的一致性和完整性
注意:约束是作用与表中字段上的,可以在创建表/修改表的时候添加约束
CREATE TABLE user( id int AUTO_INCREMENT PRIMARY KEY COMMENT '用户id', name varchar(10) NOT NULL UNIQUE COMMENT '姓名', -- 创建的年龄字段需要大于0小于等于120 age int CHECK (age > 0 && age <= 120) COMMENT '年龄', statu char(1) DEFAULT '1' COMMENT '状态', gender char(1) COMMENT '性别'
) comment '用户表';
5.2外键约束
外键约束用于让两张表数据之间建立连接,从而保证数据的一致性和完整性
具有外键的表称为子表
,子表中外键关联的表称为父表
以员工表和部门表为例,员工表中的外键为dept_id,关联部门表中的id,所以员工表为子表,部门表为父表
5.2.1添加外键
-- 表结构创建时添加
CREATE TABLE 表名(字段名 数据类型;
[CONSTRAINT][外键名称] FOREIGN KEY(外键字段名) 主表(主表列名)
);-- 表结构创建好后添加
ALTER TABLE 表名 ADD CONSTRAINT 外键名称 FOREIGN(外键字段名) REFERENCES 主表(主表列名);
例
:
-- 添加外键-给emp子表的部门id创建外键关联dept父表的id
-- ALTER TABLE (要给哪张表添加外键)-CON 外键名称 FOREIGN KEY(要添加的外键的字段名) 关联的父表(关联的外表的字段) 2
ALTER TABLE emp ADD CONSTRAINT FK_emp_dept_id FOREIGN KEY (dept_id) REFERENCES dept(id);
5.2.2外键的删除和更新行为
删除外键的语法
ALTER TABLE 表名 DROP FOREIGN KEY 外键名称;
NO ACTION
-当父表在删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与RESTRICT
一致)RESTRICT
-当父表在删除/更新对应记录时,首先检查该记录是否有对应外键,如果有则不允许删除/更新(与NO ACTION
一致)CASCADE
-当父表在删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则也删除/更新在子表中的记录SET NULL
-当父表在删除/更新对应记录时,首先检查该记录是否有对应外键,如果有,则设置子表中该外键的值为NULL(要求改外键允许取NULL)SET DEFAULT
-父表有变更时,子表将外键这只成一个默认的值(Innodb不支持)