MySQL
SQL分类
DDL
这里只讲常用的定义语句
创建数据库
|
|
删除数据库
|
|
创建表
|
|
删除表
|
|
COMMENT
后面加注释信息用单引号
表增加注释
|
|
表增加注释
|
|
查看注释信息
SHOW FULL COLUMNS FROM 表名;
增加/删除/修改列
增加
|
|
删除
|
|
修改
暂时都可以设置默认值
修改列的属性和设置默认值,不可以修改列的名字
1 2 3
#修改不为空且默认值是100 alter table jdbc_demo01.demo10_spring_boot_example modify column twd DEC default '100' ;
使用 CHANGE 子句, 语法有很大的不同。 在 CHANGE 关键字之后,紧跟着的是你要修改的字段名,然后指定新字段名及类型。
可以修改列名和属性和设置默认值
1
ALTER TABLE testalter_tbl CHANGE i j BIGINT default 'user' ; #设置默认值
DML
SELECT
查询都需要注意分页
|
|
INSERT
表中插入数据(insert):values插入多行/单行 value 插入单行
|
|
DELETE
|
|
UPDATE
|
|
MySQL关键字
AUTO_INCREMENT
主键自增长,默认第一个为1,每增加一条数据加1,int类型才可以
START TRANSACTION
开启事务,写SQL文件的时候可以用上
SHOW FULL PROCESSLIST
直接执行的MySQL命令,显示用户正在运行的线程 ,KILL id:杀死进程
WHERE
条件某某不在某某之间,where后面是条件表达式
|
|
not、or、and
and与,两者都为true才是true
|
|
or或,其中一个为true就是true
|
|
not非,返回不符合条件的条目
|
|
in
|
|
CONSTRAINT
- 约束用于预防破坏表之间连接的行为。
- 约束也能防止非法数据插入外键列,因为它必须是它指向的那个表中的值之一。
FOREIGN
FOREIGN KEY
在A表中指向B表的某个列,如果一张表增加外键就使用foreign key,
其实强关联(使用FOREIGN KEY),也可以使用弱关联(列就是别的表的一列)但是无法保证数据的完整性
REFERENCES
跟FOREIGN KEY连用,用于指向B表的某个列(主键)例如
|
|
BETWEEN
|
|
SHOW
- 查看数据库
|
|
- 查看数据库表
|
|
COUNT
返回一个表中的所有数据行数
|
|
HAVING
HAVING 是 SQL 中用于筛选分组结果的子句。它与 WHERE 子句类似,但主要区别在于 HAVING 是在 GROUP BY 之后对分组的数据进行过滤,而 WHERE 是在分组之前过滤原始数据。 HAVING 子句用于限制 GROUP BY 后的结果集,只返回满足特定条件的分组。它通常与聚合函数(如 COUNT、SUM、AVG、MAX、MIN 等)一起使用。
|
|
DISTINCT
指定某个列,去重
|
|
外键
MySQL 的外键(Foreign Key)是一种关系型数据库中用于建立表与表之间关联关系的重要工具。 外键定义了两个表之间的引用关系,它连接了两个表,使它们之间建立起一定的联系。 外键用于维护表与表之间的一致性和完整性,确保数据的准确性和可靠性
- 把A表中B表ID指定外键(B表的Id是A表一个字段),删除A表一行数据之后,B表中关联A表的字段自动删除
索引
索引 是数据库中用于提高查询速度的数据结构。它类似于书籍的目录,可以帮助快速定位到所需的数据,而无需扫描整个表。
- 把某个字段变成索引可以让他拥有和主键一样得效果就是不能重复出现
- 索引的作用
- 提高数据检索速度,减少数据库查询的 I/O 操作。
- 常用于加速 SELECT 查询和 WHERE 子句中的条件判断。
- 索引的使用
- 创建索引:CREATE INDEX index_name ON table_name(column_name);
- 删除索引:DROP INDEX index_name ON table_name;
- MySQL 中,索引自动用于优化查询,无需手动指定。
- 索引的种类
- 普通索引(Normal Index): 最基本的索引类型,没有唯一性限制。
- 唯一索引(Unique Index): 索引列的值必须唯一,允许有一个 NULL 值。
- 主键索引(Primary Key): 一种特殊的唯一索引,不允许 NULL 值,一个表只能有一个主键索引。
- 全文索引(Full-text Index): 用于全文搜索,适合较长文本字段的搜索操作。
- 组合索引(Composite Index): 由多个列组合而成的索引,优化多列查询。
- 注意事项
- 索引可以加速查询,但也会增加插入、更新、删除操作的时间成本。
- 不宜对频繁更新的列或小表创建过多索引。
MYSQL注意点
数据长度问题
存的数据超过数据库规定的字符限制就会被截断
时间类型问题
|
|
连表查询
分页
|
|
分页+排序
|
|
排序
|
|
二级排序(可以多级排序)
|
|
模糊查询
全模糊%%
方式1
|
|
方式2
|
|
%value%、%value、value%的区别
value%
:这种模式表示以指定的值开头的匹配项。例如,如果使用SELECT * FROM table WHERE column LIKE 'abc%'
,它将匹配以 “abc” 开头的所有值,如 “abc123”、“abcdef” 等。%value%
:这种模式表示包含指定值的匹配项。例如,如果使用SELECT * FROM table WHERE column LIKE '%abc%'
,它将匹配任何位置包含 “abc” 的值,如 “123abc456”、“abcdefg” 等。%value
:这种模式表示以指定的值结尾的匹配项。例如,如果使用SELECT * FROM table WHERE column LIKE '%abc'
,它将匹配以 “abc” 结尾的所有值,如 “123abc”、“defabc” 等。
多表查询
简单多表查询
以下展示也可以称之为隐式内连接
|
|
连表写法
有n个表实现多表查询,则至少需要n-1的连接条件,可以有多个
非等值连接 vs 等值连接
1 2 3 4 5 6 7 8 9 10
#等值连接 连接条件等于 = SELECT u.userName,u.userRole,r.roleCode,r.roleName,r.creationDate FROM smbms_user u,smbms_role r WHERE u.`userRole` = r.`roleCode`; #非等值连接 > < != #第一种写法 条件:返回d3.salary符合在d4.lowSalary和d4.highSalary的之间的条件的条目 SELECT d3.name,d3.salary,d4.grade FROM demo03 d3,demo04 d4 WHERE d3.salary BETWEEN d4.lowSalary AND d4.highSalary; #第二种写法 注意and没有它就会出现笛卡尔积错误 SELECT d3.name,d3.salary,d4.grade FROM demo03 d3,demo04 d4 WHERE d4.lowSalary <= d3.salary AND d3.salary <= d4.highSalary;
自连接 vs 非自连接
1 2 3 4 5
#自连接 自己连接自己 eg:查询自己的上司是谁 SELECT d3.`name`,d3.boss,d4.`name`,d4.boss FROM demo03 d3,demo03 d4 WHERE d3.name = d4.boss; #非自连接 和其他表连接 SELECT d3.name,d3.salary,d4.grade FROM demo03 d3,demo04 d4 WHERE d4.lowSalary <= d3.salary AND d3.salary <= d4.highSalary;
内连接 vs 外连接
1 2
#内连接(之前写的都是内连接):合并具有同一列的两个以上的表的行,结果集中不包含一个表于另一个表的不匹配的行 结果集就是红色部分 SELECT d3.`name`,d3.boss,d4.`name`,d4.boss FROM demo03 d3,demo03 d4 WHERE d3.name = d4.boss;
|
|
右连接
|
|
左连接
|
|
满连接:使用UNION(将多个select语句的结果集合并成一个结果集)关键字
|
|
join…0N的7 种实现
左一,右一
1 2 3 4
#左上(左连接),右上(右连接) SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 LEFT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary; SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 RIGHT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary;
左中,右中
1 2 3 4 5 6 7 8 9 10 11 12
#左中,右中 SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 LEFT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary WHERE d3.salary IS NULL; SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 RIGHT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary WHERE d3.salary IS NULL;
左下,右下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
#左下(满链接),右下 SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 LEFT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary UNION ALL SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 RIGHT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary WHERE d3.salary IS NULL; SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 LEFT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary WHERE d3.salary IS NULL UNION ALL SELECT d3.name,d3.salary,d4.grade FROM demo03 d3 RIGHT OUTER JOIN demo04 d4 ON d3.salary BETWEEN d4.lowSalary AND d4.highSalary WHERE d3.salary IS NULL;
子查询
子查询(内查询)在主查询之前执行一次查询 子查询的结果主查询使用
注意点
- 子查询要被包括在括号内
- 将子查询放在比较条件的右侧
- 单行操作符对应单行子查询(子查询的结果为一个),多行操作符对应多行子查询(子查询的结果为多个)
示例
|
|
子查询分类
角度1:内查询的结果返回值
- 单行子查询
- 返回一个结果就为单行子查询
- 多行子查询
- 返回多个结果就为多行子查询
角度2:内查询是否被执行多次
- 相关子查询
- 返回的结果为一样
- 不相关子查询
- 返回的结果不一样
6:其他的数据库操作
查看表的结构
|
|
笛卡尔积
|
|
char和varchar
|
|
varchar(10)和char(10)的区别
存储方式
CHAR:
固定长度:
CHAR 类型的字段总是分配固定长度的存储空间。
如果存储的字符串长度小于定义的长度,MySQL 会在字符串后面自动填充空格以达到固定长度。
例如,定义了 CHAR(10) 的字段,如果你插入了字符串 ‘abc’,它将被存储为 ‘abc ‘(后面有7个空格)。
VARCHAR:
可变长度:
VARCHAR 类型的字段根据实际存储的字符串长度分配存储空间,最多不会超过定义的最大长度。
不会自动填充空格,存储的字符串长度就是实际长度,再加上1个或2个字节用于存储长度信息。
例如,定义了 VARCHAR(10) 的字段,如果你插入字符串 ‘abc’,它将被存储为 ‘abc’,不附加空格。
存储效率
CHAR:
- 由于是固定长度,存储效率较高,特别适合存储长度一致的数据,如固定格式的代码(如国家代码、邮政编码等)。
- 因为不需要存储长度信息,所以检索时可能比 VARCHAR 更快。
VARCHAR:
- 对于长度不确定的字符串,VARCHAR 更节省空间,因为它只存储实际的数据长度。
- 但是由于需要额外的字节来存储字符串的长度信息,性能上在某些情况下可能会略低于 CHAR。
数据类型
VARCHAR和TEXT类型是变长类型,其存储需求取决于列值的实际长度(在前面的表格中用L表示),而不是取决于类型的最大可能尺寸。
假如一个VARCHAR(10)列能保存一个最大长度为10个字符的字符串,实际的存储需要字符串的长度L加上一个字节以记录字符串的长度。对于字符abcd,L是4,而存储要求5个字节。
E-R图
ER图是一种用于描述实体-关系模型(Entity-Relationship Model)的图形化工具。它由实体、属性和关系三部分组成,能够清晰地表示不同实体之间的关系。
下面是ER图的画法:
- 确定实体:根据系统需求,确定需要建模的实体,并在ER图中画出它们的框架。
- 确定属性:在实体框架内写下它们的属性,并用椭圆形将它们圈起来。
- 确定关系:在实体之间确定关系,并用菱形标记它们。关系可以是一对一、一对多或多对多。
- 确定关系的基数:在菱形中标记关系的基数,即一个实体在关系中的最小和最大出现次数。可以用“1”表示最小基数,用“*”表示最大基数。
- 确定外键:在相关的实体之间画出箭头,并在箭头的对应端口写下外键。
- 检查ER图:检查ER图是否符合设计需求和规范,并进行必要的修改和调整。
在绘制ER图时,需要遵循一些基本的规则,如实体、属性和关系的命名应该清晰明了,关系的基数应该符合实际需求等。同时,还需要注意ER图的简洁性和易读性,避免冗余和复杂的关系。
案例:将下图表格合理拆分为表,并画出ER图
函数
字符串函数
菜鸟教程:MySQL 函数 | 菜鸟教程 (runoob.com)
|
|
日期函数
获取时间
例子
|
|
获取日期和时间戳的转换
列子
|
|
获取月份,星期、星期数、天数
例子
|
|
时间函数计算
例子
|
|
日期格式化
MySQL小知识点
myisam和innodb
MyISAM 和 InnoDB 是 MySQL 中的两种存储引擎,它们之间的主要区别如下:
- 事务支持
- InnoDB: 支持事务,提供 ACID 特性(原子性、一致性、隔离性、持久性),可以使用 COMMIT 和 ROLLBACK 控制事务。
- MyISAM: 不支持事务,因此无法回滚或提交多条语句作为一个整体。
- 外键支持
- InnoDB: 支持外键约束,保证数据的参照完整性。
- MyISAM: 不支持外键。
- 锁机制
- InnoDB: 使用行级锁(row-level locking),适合高并发的读写操作myisam:表锁,innodb:行锁。
- MyISAM: 使用表级锁(table-level locking),在高并发写操作时容易导致锁争用。
- 性能
- InnoDB: 由于支持事务和行级锁,适合需要高并发和数据完整性的应用,但在某些场景下可能会略微影响性能。
- MyISAM: 由于没有事务和外键支持,性能在简单查询或数据仓库场景中可能会更好。
- 数据恢复
- InnoDB: 提供崩溃恢复功能,自动恢复未完成的事务。
- MyISAM: 不提供自动崩溃恢复,数据损坏后可能需要手动修复。
- 全文索引
- InnoDB: 从 MySQL 5.6 开始支持全文索引。
- MyISAM: 原生支持全文索引,适合全文搜索场景。
查询插入
查询出一个结果,并插入到另一个表中
|
|
分组增加条件
|
|
分组,重复项合并
|
|
事务
隔离级别
当我们进行数据库操作时,有时需要保证数据的一致性和可靠性。MySQL事务的隔离级别就是为了解决多个并发事务之间可能出现的问题。
想象一下你正在和朋友玩一个多人游戏,每个人都在进行自己的操作。事务的隔离级别就是定义了每个人操作时的"可见度"和"影响力",以确保游戏的公平性和数据的准确性。
MySQL定义了四种事务隔离级别,简单介绍如下:
读未提交(Read Uncommitted): 最宽松的级别。一个事务可以读取另一个事务尚未提交的数据。这可能会导致一些问题,例如读取到不完整或错误的数据。
读已提交(Read Committed): 这个级别要求一个事务只能读取已经提交的数据。这样可以避免读取到未提交的脏数据,但是在同一个事务内部,可能会遇到某个查询在不同时间返回不同结果的问题。
可重复读(Repeatable Read): 这个级别确保同一个事务内部的多个查询会返回一致的结果。即使其他事务在执行期间进行了数据更改,事务内部的查询结果也不会受到影响。
串行化(Serializable): 最严格的级别。它通过强制事务之间的串行执行来避免任何并发问题。这意味着每个事务必须按顺序执行,而不会相互干扰。这种级别可以解决所有并发问题,但可能会影响系统的性能。
Case When
在 MySQL 中,
CASE
表达式用于实现条件逻辑,从而在查询中返回不同的结果。它类似于编程语言中的if-else
或switch-case
结构。CASE
表达式非常灵活,可以在SELECT
、INSERT
、UPDATE
和DELETE
语句中使用。
- 列使用:
case when DQZT = '0' then '在籍' when DQZT = '1' then '未在籍' else '未知' end
|
|
With
公用表表达式(CTE)是一个命名的临时结果集,它在执行查询时仅存在。CTE通过
WITH
关键字引入,紧接着是CTE名称和作为CTE内容的子查询。优点:
- 代码可读性:使用CTE可以提高查询的可读性和可维护性,特别是当子查询非常复杂或在查询中多次使用时。
- 结构化查询:CTE允许你将查询分解成更小的部分,使得复杂查询更易于理解和管理。
- 复用查询:CTE可以在主查询中多次引用,避免重复代码。
|
|
IF
IF语句
IF
语句: 用于存储过程和函数中的流程控制。
IF函数
|
|