第三篇:复习MySQL

这里写目录标题

  • 一、啥是mysql?
  • 二、MySQL安装
  • 三、数据库操作
    • 1. 数据库的操作
      • 1. 创建数据库
      • 2. 删除数据库
      • 3. 选择数据库
    • 2. 数据类型
      • 1. 数值类型
      • 2.日期和时间类型
      • 3. 字符串类型
    • 3. 数据表操作
      • 1. 创建数据表
      • 2. 删除数据表
    • 3. 数据操作-增删改
      • 1. 插入数据
      • 2. 删除数据
      • 3. 修改数据
    • 4. 数据操作-语句查询
      • 1. where 子句
      • 2. 查询数据
      • 3. like 子句
      • 4. order by 排序
      • 5. group by 分组
    • 5. 表连接
      • 1. inner join 内连接
      • 2. left join 左连接
      • 3. right join 右连接
    • 6. MySQL 正则表达式
    • 7. 事务
    • 8. 索引
      • 1. 创建索引
      • 2. 修改表结构(添加索引)
      • 3. 唯一索引
    • 9. SQL注入
  • 小结

一、啥是mysql?

MySQL是一个关系型数据库管理系统,由瑞典 MySQL AB 公司开发,属于 Oracle 旗下产品。MySQL是最流行的关系型数据库管理系统之一,在 WEB 应用方面,MySQL是最好的RDBMS (Relational Database Management System,关系数据库管理系统)应用软件之一

MySQL是一种关系型数据库管理系统,关系数据库将数据保存在不同的表中,而不是将所有数据放在一个大仓库内,这样就增加了速度并提高了灵活性。

MySQL所使用的 SQL 语言是用于访问数据库的最常用标准化语言。MySQL 软件采用了双授权政策,分为社区版和商业版,由于其体积小速度快、总体拥有成本低,尤其是开放源码这一特点,一般中小型和大型网站的开发都选择 MySQL作为网站数据库。

二、MySQL安装

mysql下载地址:https://dev.mysql.com/downloads/mysql/

具体下载详情看:https://www.runoob.com/mysql/mysql-install.html

三、数据库操作

1. 数据库的操作

1. 创建数据库

可以在登录MySQL服务之后,使用create命令创建数据库,语法如下:

	CREATE DATABASE 数据库名;

也可以创建数据库时指定一些选项,可以使用 CREATE DATABASE 语句的其他参数,例如,指定字符集和排序规则:

	CREATE DATABASE 数据库名
  	CHARACTER SET utf8mb4
  	COLLATE utf8mb4_general_ci;

如果数据库已经存在,执行 CREATE DATABASE 将导致错误。
这时候就需要在语句中添加 IF NOT EXISTS子句,如果不存在,在创建数据库

2. 删除数据库

drop命令格式:

	DROP DATABASE 数据库名;        -- 直接删除数据库,不检查是否存在DROP DATABASE [IF EXISTS] 	数据库名;
  • IF EXISTS 是一个可选的子句,表示如果数据库存在才执行删除操作,避免因为数据库不存在而引发错误。

3. 选择数据库

在 MySQL 中,要选择要使用的数据库,可以使用 USE 语句,以下是基本的语法:

	USE 数据库名;

2. 数据类型

MySQL 支持多种类型,大致可以分为三类:数值、日期/时间和字符串(字符)类型。

1. 数值类型

MySQL 支持所有标准 SQL 数值数据类型。

类型 大小 范围(有符号) 范围(无符号) 用途
TINYINT 1 Bytes (-128,127) (0,255) 小整数值
SMALLINT 2 Bytes (-32 768,32 767) (0,65 535) 大整数值
MEDIUMINT 3 Bytes (-8 388 608,8 388 607) (0,16 777 215) 大整数值
INT或INTEGER 4 Bytes (-2 147 483 648,2 147 483 647) (0,4 294 967 295) 大整数值
BIGINT 8 Bytes (-9,223,372,036,854,775,808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值
FLOAT 4 Bytes (-3.402 823 466 E+38,-1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175 494 351 E-38,3.402 823 466 E+38) 单精度浮点数值
DOUBLE 8 Bytes (-1.797 693 134 862 315 7 E+308,-2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度浮点数值
DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值

2.日期和时间类型

类型 大小( bytes) 范围 格式 用途
DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值
TIME 3 ‘-838:59:59’/‘838:59:59’ HH:MM:SS 时间值或持续时间
YEAR 1 1901/2155 YYYY 年份值
DATETIME 8 ‘1000-01-01 00:00:00’ 到 ‘9999-12-31 23:59:59’ YYYY-MM-DD hh:mm:ss 混合日期和时间值
TIMESTAMP 4 ‘1970-01-01 00:00:01’ UTC 到 ‘2038-01-19 03:14:07’ UTC结束时间是第 2147483647 秒,北京时间 2038-1-19 11:14:07,格林尼治时间 2038年1月19日 凌晨 03:14:07 YYYY-MM-DD hh:mm:ss 混合日期和时间值,时间戳

3. 字符串类型

类型 大小 用途
CHAR 0-255 bytes 定长字符串
VARCHAR 0-65535 bytes 变长字符串
TINYBLOB 0-255 bytes 不超过 255 个字符的二进制字符串
TINYTEXT 0-255 bytes 短文本字符串
BLOB 0-65 535 bytes 二进制形式的长文本数据
TEXT 0-65 535 bytes 长文本数据
MEDIUMBLOB 0-16 777 215 bytes 二进制形式的中等长度文本数据
MEDIUMTEXT 0-16 777 215 bytes 中等长度文本数据
LONGBLOB 0-4 294 967 295 bytes 二进制形式的极大文本数据
LONGTEXT 0-4 294 967 295 bytes 极大文本数据
  • CHAR 和 VARCHAR 类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。

3. 数据表操作

1. 创建数据表

创建mysql表需要以下信息:

  • 表名
  • 名字段名
  • 定义每个表字段的数据类型

以下为创建 MySQL 数据表的 SQL 通用语法:

	CREATE TABLE 表名 (
    	字段名1 数据类型,
    	字段名2 数据类型,
	);

以菜品分类表为例子:

create table category(
                         id int unsigned primary key auto_increment comment '主键ID',
                         name varchar(20) not null unique comment '分类名称',
                         type tinyint unsigned not null comment '类型 1 菜品分类 2 套餐分类',
                         sort tinyint unsigned not null comment '顺序',
                         status tinyint unsigned not null default 0 comment '状态 0 禁用,1 启用',
                         create_time datetime not null comment '创建时间',
                         update_time datetime not null comment '更新时间'
) comment '分类' engine=InnoDB default charset=utf8;
  • not null 不为空,指定的列中,不可以为空值
  • 如果不想设定的id列中存在负数加上unsigned,指定数值类型只能是非负数和零
  • unique 唯一约束
  • auto_increment 定义列为自增的属性,一般用于主键,数值会自动加 1。
  • primary key 关键字用于定义列为主键。
  • commet 是给设定的列 起一个备注
  • defaul 是设定一个默认值
  • engine 设置存储引擎
  • default charset 设置编码。

2. 删除数据表

以下为删除 MySQL 数据表的通用语法:

DROP TABLE 数据表名 ;    -- 直接删除表,不检查是否存在DROP TABLE [IF EXISTS] 数据表名;

3. 数据操作-增删改

1. 插入数据

MySQL 表中使用 insert into 语句来插入数据。
以下为向MySQL数据表插入数据通用的 inser into SQL语法

insert [into] 表名 (列名1, 列名2, 列名3, ...)
values(1,2,3, ...);
  • 其中 into 可以省略
  • 列名也可以省略,但是不建议

如果数据是字符型,必须使用单引号 ’ 或者双引号 ",如: ‘value1’, “value1”。

2. 删除数据

MySQL 表中使用 delete 语句来删除数据。

delete from 表名
where 条件;

delete删除数据是将Mysql表中的数据一行一行的删除,不删除表的结构,也不释放表的空间,可以事务回滚(rollback)

3. 修改数据

MySQL 表中使用 update 语句来修改数据。

update 表名
set 列名1 =1,列名2 =2
where 条件;

4. 数据操作-语句查询

1. where 子句

where语句用于在 MySQL 中过滤查询结果,可以用于删,改,查,只返回满足特定条件的行。

  • 查询语句中可以使用一个或者多个表,表之间使用逗号, 分割,并使用where语句来设定查询条件。
  • 可以在 where子句中指定任何条件。
  • 可以使用 and 或者 or 指定一个或多个条件。
  • where子句也可以运用于 SQL 的 delete 或者 update 命令。
  • where子句类似于程序语言中的 if 条件,只有满足条件的才可以被查询出来

以下为操作符列表,可用于 WHERE 子句中。

下表中实例假定 A 为 10, B 为 20

操作符 描述 实例
= 等号,检测两个值是否相等,如果相等返回true (A = B) 返回false。
<>, != 不等于,检测两个值是否相等,如果不相等返回true (A != B) 返回 true。
> 大于号,检测左边的值是否大于右边的值, 如果左边的值大于右边的值返回true (A > B) 返回false。
< 小于号,检测左边的值是否小于右边的值, 如果左边的值小于右边的值返回true (A < B) 返回 true。
>= 大于等于号,检测左边的值是否大于或等于右边的值, 如果左边的值大于或等于右边的值返回true (A >= B) 返回false。
<= 小于等于号,检测左边的值是否小于或等于右边的值, 如果左边的值小于或等于右边的值返回true (A <= B) 返回 true。

2. 查询数据

MySQL 表中使用 select 语句来查询数据。

select 列名1,列名2
from 表名
where 条件;

简单查询实例

  1. 等于条件:
SELECT * FROM users WHERE username = 'test';
  1. 不等于条件:
SELECT * FROM users WHERE username != 'runoob';
  1. 大于条件:
SELECT * FROM products WHERE price > 50.00;
  1. 小于条件:
SELECT * FROM orders WHERE order_date < '2023-01-01';
  1. 大于等于条件:
SELECT * FROM employees WHERE salary >= 50000;
  1. 小于等于条件:
SELECT * FROM students WHERE age <= 21;
  1. 组合条件(AND、OR):
SELECT * FROM products WHERE category = 'Electronics' AND price > 100.00;

SELECT * FROM orders WHERE order_date >= '2023-01-01' OR total_amount > 1000.00;
  1. 模糊匹配条件(LIKE):
SELECT * FROM customers WHERE first_name LIKE 'J%';
  1. IN 条件:
SELECT * FROM countries WHERE country_code IN ('US', 'CA', 'MX');
  1. NOT 条件:
SELECT * FROM products WHERE NOT category = 'Clothing';
  1. BETWEEN 条件:
SELECT * FROM orders WHERE order_date BETWEEN '2023-01-01' AND '2023-12-31';
  1. IS NULL 条件
SELECT * FROM employees WHERE department IS NULL;
  1. IS NOT NULL 条件:
SELECT * FROM customers WHERE email IS NOT NULL;

3. like 子句

like子句是在 MySQL 中用于在 where子句中进行模糊匹配的关键字。它通常与通配符一起使用,用于搜索符合某种模式的字符串。

以下是 SQL select语句使用 LIKE 子句从数据表中读取数据的通用语法:

select 列名1, 列名2, ...
FROM 表名
WHERE 需要查找的列名 LIKE 模糊查询的条件(搭配通配符);
  • 可以在 WHERE 子句中指定任何条件。
  • 可以在 WHERE 子句中使用LIKE子句。
  • 可以使用LIKE子句代替等号 =。
  • like 通常与 % 一同使用,类似于一个元字符的搜索。
  • 可以使用 and 或者 or 指定一个或多个条件。
  • 你可以在 delete 或 update 命令中使用where…like子句来指定条件。

通配符:

  1. 百分号通配符 %:
    % 通配符表示零个或多个字符。例如,‘a%’ 匹配以字母 ‘a’ 开头的任何字符串。

  2. 下划线通配符 _:
    _ 通配符表示一个字符。例如,‘_r%’ 匹配第二个字母为 ‘r’ 的任何字符串。

  3. 组合使用 % 和 _:

select* from users where username LIKE 'a%o_';
  • 以上 SQL 语句将选择用户名以 ‘a’ 开头、以 ‘o’ 结尾,并且长度为三个字符的所有用户。

4. order by 排序

MySQL order by(排序) 语句可以按照一个或多个列的值进行升序(asc)或降序(desc)排序默认是升序(asc)。

以下是 select 语句使用 order by 子句将查询数据排序后再返回数据:

select 列名1, 列名2, ...
from 表名
order by 列名1 [asc | desc],
         列名2 [asc | desc], ...;

5. group by 分组

group by 语句根据一个或多个列对结果集进行分组。

在分组的列上我们可以使用 count, sum, avg,等函数。

select 列名1,聚合函数(列名2from 表名
where 条件
group by 列名1

注意:

  • group by 子句通常与聚合函数一起使用,因为分组后需要对每个组进行聚合操作。
  • select 子句中的列通常要么是分组列,要么是聚合函数的参数。
  • 可以使用多个列进行分组,只需在 group by 子句中用逗号分隔列名即可。

5. 表连接

1. inner join 内连接

inner join (内连接,或等值连接):获取两个表中字段匹配关系的记录。

inner join返回两个表中满足连接条件的匹配行,以下是 inner join 语句的基本语法:

select 列名1,列名2,...
from 表名1 as 别名1
inner join 表名2 as 别名2 on 别名1.id = 别名2.id

用as起的别名=对应的表名

inner join 可以多表使用,可以继续往下 inner join

2. left join 左连接

left join 返回左表的所有行,并包括右表中匹配的行,如果右表中没有匹配的行,将返回 null 值,以下是 left join 语句的基本语法:

select 列名1,列名2...
from1
left join2 on1.id =2.id;

3. right join 右连接

右连接和左连接会一个就行,都用左连接,把表名换一下位置,就可以实现右连接的效果

6. MySQL 正则表达式

MySQL 同样也支持其他正则表达式的匹配, MySQL 中使用 regexprlike操作符来进行正则表达式匹配。

模式 描述
^ 匹配输入字符串的开始位置。如果设置了 RegExp 对象的 Multiline 属性,^ 也匹配 ‘\n’ 或 ‘\r’ 之后的位置。
$ 匹配输入字符串的结束位置。如果设置了RegExp 对象的 Multiline 属性,$ 也匹配 ‘\n’ 或 ‘\r’ 之前的位置。
. 匹配除 “\n” 之外的任何单个字符。要匹配包括 ‘\n’ 在内的任何字符,请使用像 ‘[.\n]’ 的模式。
[…] 字符集合。匹配所包含的任意一个字符。例如, ‘[abc]’ 可以匹配 “plain” 中的 ‘a’。
[^…] 负值字符集合。匹配未包含的任意字符。例如, ‘[^abc]’ 可以匹配 “plain” 中的’p’。
p1|p2|p3 匹配 p1 或 p2 或 p3。例如,'z
* 匹配前面的子表达式零次或多次。例如,zo* 能匹配 “z” 以及 “zoo”。* 等价于{0,}。
+ 匹配前面的子表达式一次或多次。例如,‘zo+’ 能匹配 “zo” 以及 “zoo”,但不能匹配 “z”。+ 等价于 {1,}。
{n} n 是一个非负整数。匹配确定的 n 次。例如,‘o{2}’ 不能匹配 “Bob” 中的 ‘o’,但是能匹配 “food” 中的两个 o。
{n,m} m 和 n 均为非负整数,其中n <= m。最少匹配 n 次且最多匹配 m 次。

正则表达式匹配的字符类:

  • .:匹配任意单个字符。
  • ^:匹配字符串的开始。
  • $:匹配字符串的结束。
  • *:匹配零个或多个前面的元素。
  • +:匹配一个或多个前面的元素。
  • ?:匹配零个或一个前面的元素。
  • [abc]:匹配字符集中的任意一个字符。
  • [^abc]:匹配除了字符集中的任意一个字符以外的字符。
  • [a-z]:匹配范围内的任意一个小写字母。
  • \d:匹配一个数字字符。
  • \w:匹配一个字母数字字符(包括下划线)。
  • \s:匹配一个空白字符。

使用 regexp 进行模式匹配
regexp 是用于进行正则表达式匹配的运算符。

regexp 用于检查一个字符串是否匹配指定的正则表达式模式,以下是 regexp 运算符的基本语法:

select 列名1,列名2...
from 表名1
where 要进行匹配的列名 regexp 正则表达式的模式

例子如下:

# 查找 name 字段中以 'st' 为开头的所有数据:
SELECT name FROM person_tbl WHERE name REGEXP '^st';

# 查找 name 字段中以 'ok' 为结尾的所有数据:
SELECT name FROM person_tbl WHERE name REGEXP 'ok$';

# 查找 name 字段中包含 'mar' 字符串的所有数据:
SELECT name FROM person_tbl WHERE name REGEXP 'mar';

# 查找 name 字段中以元音字符开头或以 'ok' 字符串结尾的所有数据:
SELECT name FROM person_tbl WHERE name REGEXP '^[aeiou]|ok$';

# 选择订单表中描述中包含 "item" 后跟一个或多个数字的记录。
SELECT * FROM orders WHERE order_description REGEXP 'item[0-9]+';

# 使用 BINARY 关键字,使得匹配区分大小写:
SELECT * FROM products WHERE product_name REGEXP BINARY 'apple';

# 使用 OR 进行多个匹配条件,以下将选择姓氏为 "Smith" 或 "Johnson" 的员工记录:
SELECT * FROM employees WHERE last_name REGEXP 'Smith|Johnson';

使用 rlike 进行模式匹配
rlike 是 MySQL 中用于进行正则表达式匹配的运算符,与 regexp 是一样的,rlike 和 regexp 可以互换使用,没有区别。
以下是使用 RLIKE 进行正则表达式匹配的基本语法:

select 列名1,列名2...
from 表名
where 要进行匹配的列名 rlike 正则表达式的模式

7. 事务

在 MySQL 中,事务是一组操作的集合,它是一个不可分割的工作单位,事务会把所有的操作作为一个整体向系统提交,或者撤销操作做出请求

  • 即要么共同成功,要么一起失败

在 MySQL 中只有使用了 Innodb 数据库引擎的数据库或表才支持事务。

事务处理可以用来维护数据库的完整性,保证成批的 SQL 语句要么全部执行,要么全部不执行
事务用来管理 insertupdatedelete 语句

一般来说,事务是必须满足4个条件(ACID)

  • 原子性:一个事务(transaction)中的所有操作,要么全部完成,要么全部不完成,不会结束在中间某个环节。事务在执行过程中发生错误,会被回滚(Rollback)到事务开始前的状态,就像这个事务从来没有执行过一样。

  • 一致性:在事务开始之前和事务结束以后,数据库的完整性没有被破坏。这表示写入的资料必须完全符合所有的预设规则,这包含资料的精确度、串联性以及后续数据库可以自发性地完成预定的工作。

  • 隔离性:数据库允许多个并发事务同时对其数据进行读写和修改的能力,隔离性可以防止多个事务并发执行时由于交叉执行而导致数据的不一致。事务隔离分为不同级别,包括读未提交(Read uncommitted)、读提交(read committed)、可重复读(repeatable read)和串行化(Serializable)。

  • 持久性:事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。

在 MySQL 命令行的默认设置下,事务都是自动提交的,即执行 SQL 语句后就会马上执行 COMMIT 操作。因此要显式地开启一个事务务须使用命令 BEGIN 或 START TRANSACTION,或者执行命令 SET AUTOCOMMIT=0,用来禁止使用当前会话的自动提交。

事务控制语句:

  • begin 或 start transaction 显式地开启一个事务;

  • rollback 回滚会结束用户的事务,并撤销正在进行的所有未提交的修改;

  • commit 会提交事务,并使已对数据库进行的所有修改成为永久性的;

  • savepoint identifier,savepoint 允许在事务中创建一个保存点,一个事务中可以有多个 savepoint ;

  • release savepoint identifier 删除一个事务的保存点,当没有指定的保存点时,执行该语句会抛出一个异常;

  • rollback to identifier 把事务回滚到标记点;

MYSQL 事务处理主要有两种方法:

1、用 begin , rollback, commit 来实现

begin 或 start transaction:开用于开始一个事务。
rollback事务回滚,取消之前的更改。
commit :事务确认,提交事务,使更改永久生效。

2、直接用 set 来改变 MySQL 的自动提交模式:

set autocommit = 0 禁止自动提交
set autocommit = 1 开启自动提交

简单例子:
begin 或 start transaction – 用于开始一个事务:

begin ; – 或者使用 start transaction

commit – 用于提交事务,将所有的修改永久保存到数据库:

commit ;

rollback-- 用于回滚事务,撤销自上次提交以来所做的所有更改:

rollback;

savepoint-- 用于在事务中设置保存点,以便稍后能够回滚到该点:

savepoint 保存点名字;

ROLLBACK TO SAVEPOINT – 用于回滚到之前设置的保存点:

rllback to savepoint 保存点名字;

8. 索引

MySQL 索引是一种数据结构,用于加快数据库查询的速度和性能。

MySQL 索引类似于书籍的索引,通过存储指向数据行的指针,可以快速定位和访问表中的特定数据。
打个比方,如果合理的设计且使用索引的 MySQL 是一辆兰博基尼的话,那么没有设计和使用索引的 MySQL 就是一个人力三轮车。
拿汉语字典的目录页(索引)打比方,我们可以按拼音、笔画、偏旁部首等排序的目录(索引)快速查找到需要的字。

索引分单列索引和组合索引:

  • 单列索引,即一个索引只包含单个列,一个表可以有多个单列索引。
  • 组合索引,即一个索引包含多个列。

创建索引时,需要确保该索引是应用在 SQL 查询语句的条件(一般作为 where 子句的条件)。

索引虽然能够提高查询性能,但也需要注意以下几点:

  • 索引需要占用额外的存储空间。
  • 对表进行插入、更新和删除操作时,索引需要维护,可能会影响性能。
  • 过多或不合理的索引可能会导致性能下降,因此需要谨慎选择和规划索引

1. 创建索引

使用 create index 语句可以创建普通索引。
普通索引是最常见的索引类型,用于加速对表中数据的查询
create index 的语法:

create  index  索引名
on 表名(列名1 [asc|desc], 列名2 [asc|desc], ...);

2. 修改表结构(添加索引)

可以使用 alter table 命令可以在已有的表中创建索引。
alter table 允许修改表的结构,包括添加、修改或删除索引。
alter table 创建索引的语法:

alter table 表名
add index 索引名 (列名1 [ asc | desc], 列名2 [ asc | desc], ...);

创建表的时候直接指定

creat table 表名 (
  列名1 数据类型,
  列名2 数据类型,
  ...,
  index 索引名 (列名1 [ asc | desc], 列名2 [ asc | desc], ...);

3. 唯一索引

在 MySQL 中,可以使用 create unique index 语句来创建唯一索引。

唯一索引确保索引中的值是唯一的,不允许有重复值。

 create unique index 索引名
on 表名(列名1 [asc|desc], 列名2 [asc|desc], ...); ...);

添加方法和普通索引一样

9. SQL注入

所谓 SQL 注入,就是通过把 SQL 命令插入到 Web 表单递交或输入域名或页面请求的查询字符串,最终达到欺骗服务器执行恶意的 SQL 命令。
MySQL 注入是指攻击者通过恶意构造的输入,成功地执行恶意的 SQL 查询,这通常发生在用户输入未经适当验证或转义的情况下,攻击者试图在输入中插入 SQL 代码,以执行意外的查询或破坏数据库。
永远不要信任用户的输入,必须认定用户输入的数据都是不安全的,所以都需要对用户输入的数据进行过滤处理。

假设有一个登录系统,用户通过输入用户名和密码进行身份验证:

select * from users where username = 'input_username' and password = 'input_password';

如果没有正确的输入验证和防范措施,攻击者可以输入类似于以下内容的用户名:

' or'1'='1'; 

在这种情况下,就会被注入成功
建议全部使用预编译SQL,性能更高,更安全

详情见https://www.runoob.com/mysql/mysql-sql-injection.html

小结

写本文主要是为了分享我的学习过程,也是给自己记个笔记,哪里忘记了,回来再看一眼,也可以很快的回想起来

注:本文主要供自己学习练习使用,大部分内容是从第三方平台截图复制而来(究极缝合怪),如有侵权请联系删除

你可能感兴趣的:(mysql,数据库)