目录

1)创建数据库

2)查看、删除数据库

3)备份恢复数据库

 4)创建表

5)MySQL数据类型

6)数据类型之整型

 7)数据类型之bit

8)数据类型之小数

1)近似小数类型(浮点数)

2)精确小数类型(固定精度) 

9)数据类型之字符串

1. 定长字符串类型

2. 变长字符串类型

10)数据类型之日期

 11)修改表

1.添加列

2.删除列

3.修改列定义

4.修改表选项

5.重命名表

6.多组合操作

7.查看表结构

12)insert语句

13)update语句

 14)delete语句

15)select语句

16)where子句中的运算符

1.比较运算符

2.逻辑运算符

 3.模糊匹配运算符

4.其他 

 17)聚合函数

1.count() 计数

2.sum() 求和

3.avg() 平均值

4.max() 最大值

5.min() 最小值

18)分组统计

19)字符串函数

20)数学函数

21)日期函数

22)加密函数

23)流程控制函数

24)分页查询

25)all、any的使用

26)表复制操作

27)左外连、右外连

28)primary key

29)unique 

30)foreign key

31)check 

32)default

33)auto_increment

34)索引

35)删除索引

36)事务

37)事务隔离级别

38)事务并发问题

 39)存储引擎

 40)视图

41)用户管理

42)权限管理


1)创建数据库

        在MySQL里进入“新建查询”,输入

//数据库名称
CREATE DATABASE my_new_database
//字符集
CHARACTER SET utf8mb4
//排序规则 
COLLATE utf8mb4_unicode_ci;

2)查看、删除数据库

  • 显示数据库:
    SHOW DATABASES
  • 显示创建数据库语句:
    //在创建数据库的时候,为了规避关键字,可以使用反引号``
    SHOW CREATE DATABASE (`name`)
  • 删除数据库:
        DROP DATABASE [IF EXISTS] (name)

3)备份恢复数据库

        备份命令要在命令行下进行:

  1. 备份特定表:
    mysqldump -u 用户名 -p 数据库名 表名1 表名2 > 表备份.sql
  2. 备份单个数据库:
    mysqldump -u 用户名 -p 数据库名 > 备份文件.sql
  3. 备份所有数据库
    mysqldump -u 用户名 -p --all-databases > 完整备份.sql

         恢复命令要在MySQL命令行中进行:

  1. 恢复完整备份:
    mysql -u 用户名 -p 数据库名 < 备份文件.sql
  2. 从完整备份中恢复单个数据库:
    mysql -u 用户名 -p --one-database 数据库名 < 完整备份.sql

4)创建表

        语法:

CREATE TABLE _name(
    field1 datatype,
    field2 datatype,
    field3 datatype
)character set   collate   engine

//field:制定列名 
//datatype:指定列类型(字段类型) 
//character set 字符集
//collate 校对规则
//engine 引擎

5)MySQL数据类型

MySQL数据类型
├── 数值类型
│   ├── 整数类型
│   │   ├── TINYINT (1字节)
│   │   ├── SMALLINT (2字节)
│   │   ├── MEDIUMINT (3字节)
│   │   ├── INT/INTEGER (4字节)
│   │   └── BIGINT (8字节)
│   │
│   └── 小数类型
│       ├── 精确小数
│       │   └── DECIMAL[M,D]
│       │
│       └── 近似小数
│           ├── FLOAT (单精度 4字节)
│           └── DOUBLE (双精度 8字节)
│
├── 字符串类型
│   ├── 文本字符串
│   │   ├── CHAR (定长 0-255)
│   │   ├── VARCHAR (变长 0-65535(2^16-1))
│   │   ├── TINYTEXT
│   │   ├── TEXT(0-65535(2^16-1))
│   │   ├── MEDIUMTEXT
│   │   └── LONGTEXT(0-2^32-1)
│   │
│   └── 二进制字符串
│       ├── BINARY (定长)
│       ├── VARBINARY (变长)
│       ├── TINYBLOB
│       ├── BLOB(0-2^16-1)
│       ├── MEDIUMBLOB
│       └── LONGBLOB(0-2^32-1)
│
├── 日期时间类型
│   ├── DATE (年月日 YYYY-MM-DD)
│   ├── TIME (时分秒 HH:MM:SS)
│   ├── DATETIME (年月日时分秒 YYYY-MM-DD HH:MM:SS)
│   ├── TIMESTAMP (时间戳)
│   └── YEAR (年份)
│
├── 位类型
│   └── BIT (位字段)
│
└── 特殊类型
    ├── ENUM (枚举)
    ├── SET (集合)
    ├── JSON (JSON数据)
    └── GEOMETRY (空间数据)
        ├── POINT
        ├── LINESTRING
        ├── POLYGON
        ├── MULTIPOINT
        ├── MULTILINESTRING
        ├── MULTIPOLYGON
        └── GEOMETRYCOLLECTION

6)数据类型之整型

无符号的最大值是有符号最大值的*2 - 1。

  1. TINYINT

    • 存储空间:1字节

    • 有符号范围:-128 到 127

    • 无符号范围:0 到 255

    • 常用于小范围数值或布尔值表示

  2. SMALLINT

    • 存储空间:2字节

    • 有符号范围:-32,768 到 32,767

    • 无符号范围:0 到 65,535

  3. MEDIUMINT

    • 存储空间:3字节

    • 有符号范围:-8,388,608 到 8,388,607

    • 无符号范围:0 到 16,777,215

  4. INT (INTEGER)

    • 存储空间:4字节

    • 有符号范围:-2,147,483,648 到 2,147,483,647

    • 无符号范围:0 到 4,294,967,295

    • 最常用的整型类型

  5. BIGINT

    • 存储空间:8字节

    • 有符号范围:-9,223,372,036,854,775,808 到 9,223,372,036,854,775,807

    • 无符号范围:0 到 18,446,744,073,709,551,615

    • 用于极大整数

CREATE TABLE zheng_xing(
		#使用unsigned修饰则为无符号
		id01 INT UNSIGNED,
		#不修饰的话默认为有符号(包含负数)
		id02 INT)

7)数据类型之bit

        BIT 是 MySQL 中用于存储位值的数据类型,适合存储二进制标志位或位掩码

基本语法:

BIT[(M)]
  • M表示位数(1-64),默认为1。例如BIT,BIT(8),BIT(64)。

存储空间:                                      1byte = 8bit

  • 1-8位:占用1字节

  • 9-16位:占用2字节

  • 17-24位:占用3字节

  • 以此类推,最多8字节(64位)

取值范围

  • BIT(1):0或1

  • BIT(8):0到255 (2^8-1)

  • BIT(64):0到2^64-1

 与TINYINT比较:

特性 BIT(8) TINYINT UNSIGNED
存储空间 1字节 1字节
取值范围 0-255 0-255
语义 位集合 数值
位操作效率 更高 较低
数值运算 需要转换 直接支持

BIT类型在需要位级操作时更高效,而TINYINT在需要数值运算时更方便。

8)数据类型之小数

MySQL 提供了多种存储小数的数据类型,主要分为近似小数类型精确小数类型两大类。

1)近似小数类型(浮点数)

FLOAT:

FLOAT(M,D)  -- 单精度浮点数

特点

  • 4字节存储

  • 约7位有效数字

  • 有精度损失,计算速度快

DOUBLE:

DOUBLE(M, D)  -- 双精度浮点数

特点

  • 8字节存储

  • 约15位有效数字

  • 比FLOAT精度高,仍有精度损失

2)精确小数类型(固定精度) 

DECIMAL:

DECIMAL(M, D) 
  • M:总位数(精度),范围 1-65

  • D:小数点后的位数(标度),范围 0-30 且 D ≤ M

特点

  • 精确存储,无精度损失

  • 适合财务数据等需要精确计算的场景

  • 存储空间可变:每9位数字占用4字节,剩余位数需要额外空间

类型 存储空间 精确性 适用场景
DECIMAL 可变 精确 财务计算、货币值
FLOAT 4字节 近似 科学数据、不需要精确的值
DOUBLE 8字节 近似 需要更大范围的科学计算

9)数据类型之字符串

1. 定长字符串类型

CHAR:

  • 语法CHAR(M)

  • 特点:

    • 固定长度,M 范围为 0-255 个字符

    • 存储时总是占用 M 个字符的空间(不足用空格填充)

    • 检索时会自动删除尾部空格

  • 适用场景: 存储长度固定的数据(如国家代码、性别、MD5哈希值等)

CREATE TABLE users (
    gender CHAR(1)  -- 存储 'M' 或 'F'
);

2. 变长字符串类型

VARCHAR:

  • 语法VARCHAR(M)

  • 特点:

    • 可变长度,M 范围为 0-65,535 个字符(实际限制受行大小限制)

    • 只占用实际数据长度+1或+2字节的长度前缀

    • 不会自动删除尾部空格

  • 适用场景: 存储长度变化较大的数据(如用户名、地址等)

utf8编码最大21844(65535-3)/3字符,有1-3个字符用于记录大小。

CREATE TABLE products (
    name VARCHAR(100)  -- 存储产品名称
);

字符串使用细节:

1)

        char(4)、varchar(4):这个4都表示字符数,不是字节数,不管是中文还是字母都是放4个,按字符计算。

2)

        char(4)是定长,即时插入'aa',也会占用分配的4个字符的空间

        varchar(4)是变长,,如果插入了'aa',实际占用空间大小并不是4个字符,而是按照实际占用空间来分配(varchar本身还需要占用1-3个字节来记录存放内容长度)

3)

        如何选择char、varchar?

        如果定长选char,比如身份证、手机号。

        不定长选varchar,文章等。

查询速度:char>varchar

4)

        在存放文本时,也可以使用Text数据类型,Text没有默认值,大小为0-2^16字节。MEDIUMTEXT为2^24,LONGTEXT为2^32。

       

10)数据类型之日期

DATE:

  • 格式YYYY-MM-DD

  • 范围: '1000-01-01' 到 '9999-12-31'

  • 存储空间: 3字节

  • 用途: 仅存储日期,不包含时间部分

CREATE TABLE events (
    event_date DATE  -- 存储如 '2023-05-15'
);

TIME:

  • 格式HH:MM:SS 或 HHH:MM:SS

  • 范围: '-838:59:59' 到 '838:59:59'

  • 存储空间: 3字节

  • 用途: 存储时间或时间间隔

CREATE TABLE schedules (
    start_time TIME  -- 存储如 '14:30:00' 或 '120:00:00'(120小时)
);

DATETIME:

  • 格式YYYY-MM-DD HH:MM:SS

  • 范围: '1000-01-01 00:00:00' 到 '9999-12-31 23:59:59'

  • 存储空间: 8字节

  • 用途: 存储日期和时间组合

CREATE TABLE orders (
    order_time DATETIME  -- 存储如 '2023-05-15 14:30:45'
);

TIMESTAMP:

  • 格式YYYY-MM-DD HH:MM:SS

  • 范围: '1970-01-01 00:00:01' UTC 到 '2038-01-19 03:14:07' UTC

  • 存储空间: 4字节

  • 特点:

    • 自动转换为UTC存储,检索时转换回当前时区

    • 可自动初始化和更新(见下文)

    • 受2038年问题限制

CREATE TABLE logs (
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

11)修改表

1.添加列

ALTER TABLE 表名 ADD COLUMN 列名 数据类型 [约束条件] [FIRST|AFTER 现有列名];
-- 在users表末尾添加age列
ALTER TABLE users ADD COLUMN age INT;

-- 在users表的username列后添加email列
ALTER TABLE users ADD COLUMN email VARCHAR(100) AFTER username;

-- 在users表开头添加id列
ALTER TABLE users ADD COLUMN id INT FIRST;

2.删除列

ALTER TABLE 表名 DROP COLUMN 列名;
-- 删除users表中的age列
ALTER TABLE users DROP COLUMN age;

3.修改列定义

ALTER TABLE 表名 MODIFY COLUMN 列名 新数据类型 [约束条件];
-- 修改users表的email列长度为150
ALTER TABLE users MODIFY COLUMN email VARCHAR(150);

重命名列并修改定义:

ALTER TABLE 表名 CHANGE COLUMN 旧列名 新列名 数据类型 [约束条件];
-- 将users表的phone列改名为mobile并修改数据类型
ALTER TABLE users CHANGE COLUMN phone mobile VARCHAR(20);

4.修改表选项

ALTER TABLE 表名 表选项;

5.重命名表

ALTER TABLE 旧表名 RENAME TO 新表名;
-- 或
RENAME TABLE 旧表名 TO 新表名;
-- 将users表重命名为customers
ALTER TABLE users RENAME TO customers;
-- 或
RENAME TABLE users TO customers;

6.多组合操作

ALTER TABLE users
    ADD COLUMN age INT AFTER email,
    MODIFY COLUMN username VARCHAR(50) NOT NULL,
    DROP COLUMN old_column;

7.查看表结构

DESCRIBE 表名;
-- 或
SHOW CREATE TABLE 表名;

12)insert语句

        INSERT语句用于向表中插入新行。

INSERT INTO 表名 (列1, 列2, 列3, ...)
VALUES (值1, 值2, 值3, ...);
-- 向users表插入一行数据
INSERT INTO users (username, email, created_at)
VALUES ('john_doe', 'john@example.com', NOW());

-- 插入多行数据
INSERT INTO products (name, price, stock)
VALUES 
    ('Laptop', 999.99, 50),
    ('Phone', 699.99, 100),
    ('Tablet', 399.99, 75);

注意事项:

  • 插入的数据应与字段的数据类型相同
  • 数据的长度应在列的的规定范围内
  • 在values中列出的数据位置必须与被加入的列的排列位置相对应
  • 字符和日期类数据应包含在单引号中
  • 列可以插入空值,前提是该字段允许为空 insert into table value(null)
  • insert into () values ()()()形式添加多条记录
  • 如果是给表中所有字段添加数据,可以前面不写字段名称
  • 字段值不赋值时会使用默认值,如果不存在默认值就会报错

13)update语句

        UPDATE 语句用于修改 MySQL 数据库表中的现有记录

UPDATE table_name
SET column1 = value1, column2 = value2, ...
WHERE condition;
//table_name:表名
//set:指定要更新的列及其新值
//where:指定记录哪些需要更新(可选,但通常很重要)
//condition:确定哪些行将被更新的条件

WHERE 子句非常重要:如果不加 WHERE 条件,将更新表中的所有行

更新单列:

UPDATE customers
SET email = 'new.email@example.com'
WHERE customer_id = 1;

更新多列:

UPDATE employees
SET salary = 50000, department = 'Marketing'
WHERE employee_id = 101;

使用表达式更新:

UPDATE employees
SET salary = 50000, department = 'Marketing'
WHERE employee_id = 101;

更新所有行(慎用):

UPDATE settings
SET last_updated = NOW();

14)delete语句

        DELETE 语句用于从 MySQL 数据库表中删除记录。

DELETE FROM table_name
WHERE condition;

delete语句不能删除某一列的值(可使用update设为 null 或 '')

使用delete语句仅删除记录,不删除表本身。若要删除表,要用drop table 语句。

15)select语句

        SELECT 是 MySQL 中最重要、最常用的语句,用于从数据库中查询数据。

SELECT 
    [DISTINCT] (column1, column2, ...)/(*)
    
FROM 
    table_name
[WHERE condition]
[GROUP BY column_name(s)]
[HAVING condition]
[ORDER BY column_name(s) [ASC|DESC]]
[LIMIT offset, row_count];
  • distinct表示是否删除重复数据,要每列字段都相同才去重
  • *表示查询所有列
  • column指定列名
  • from指查询哪张表

order by子句: 

-- 查询最贵的 10 个商品(降序)
SELECT * FROM products 
ORDER BY price DESC 
LIMIT 10;

-- 按部门升序,同部门按入职时间降序
SELECT name, department, hire_date 
FROM employees 
ORDER BY department ASC, hire_date DESC;

-- 按名字长度排序,相同长度再按字母顺序
SELECT * FROM customers 
ORDER BY LENGTH(name), name;
功能 写法
升序(默认) ORDER BY column 或 ORDER BY column ASC
降序 ORDER BY column DESC
多列排序 ORDER BY col1, col2 DESC
按函数排序 ORDER BY LENGTH(name)
控制 NULL 顺序 ORDER BY IF(column IS NULL, 0, 1), column
自定义排序 ORDER BY FIELD(status, 'active', 'pending')
随机排序 ORDER BY RAND()

16)where子句中的运算符

1.比较运算符

运算符 说明 示例
= 等于 WHERE age = 25
<> 或 != 不等于 WHERE status <> 'inactive'
< 小于 WHERE price < 100
> 大于 WHERE score > 80
<= 小于等于 WHERE quantity <= 10
>= 大于等于 WHERE salary >= 5000
<=> NULL 安全的等于(可比较 NULL) WHERE name <=> NULL
IS NULL 判断是否为 NULL WHERE email IS NULL
IS NOT NULL 判断是否不为 NULL WHERE phone IS NOT NULL
BETWEEN ... AND ... 在某个范围内(包含边界) WHERE age BETWEEN 18 AND 30
NOT BETWEEN ... AND ... 不在某个范围内 WHERE price NOT BETWEEN 50 AND 100
IN (...) 在指定列表中 WHERE id IN (1, 3, 5)
NOT IN (...) 不在指定列表中 WHERE status NOT IN ('pending', 'cancelled')

2.逻辑运算符

运算符 说明 示例
AND 或 && 逻辑与(同时满足) WHERE age > 18 AND status = 'active'
OR  逻辑或(满足其一) WHERE role = 'admin' OR role = 'manager'
NOT 或 ! 逻辑非(取反) WHERE NOT (age < 18)
XOR 逻辑异或(仅一个条件为真) WHERE is_student XOR is_employed

 3.模糊匹配运算符

运算符 说明 示例
LIKE 模糊匹配(% 任意字符,_ 单个字符) WHERE name LIKE 'J%'(以 J 开头)
NOT LIKE 不匹配模式 WHERE email NOT LIKE '%@gmail.com'
REGEXP 或 RLIKE 正则表达式匹配 WHERE name REGEXP '^A.*n$'(以 A 开头,n 结尾)
NOT REGEXP 正则表达式不匹配 WHERE phone NOT REGEXP '^[0-9]{10}$'

4.其他 

运算符 说明 示例
DIV 整数除法 WHERE value DIV 2 = 5
& 位与 WHERE flags & 1 = 1
<< 左移位 WHERE num << 1 = 8
>> 右移位 WHERE num >> 1 = 4
+ 加法 WHERE age + 5 > 25
- 减法 WHERE price - discount < 50
* 乘法 WHERE salary * 12 > 60000
/ 除法 WHERE total / quantity > 10
% 或 MOD 取模(求余数) WHERE id % 2 = 0(偶数)

 17)聚合函数

1.count() 计数

        计算行数或非 NULL 值的数量。

COUNT(*)            -- 计算所有行(包括NULL)
COUNT(column)       -- 计算某列非NULL的行数
COUNT(DISTINCT column) -- 计算某列去重后的数量
-- 计算 users 表的总行数
SELECT COUNT(*) FROM users;

-- 计算 email 列非 NULL 的数量
SELECT COUNT(email) FROM users;

-- 计算不同城市的数量(去重)
SELECT COUNT(DISTINCT city) FROM customers;

2.sum() 求和

        计算某列数值的总和(忽略 NULL)。

SUM(column)
SUM(DISTINCT column)  -- 去重后求和
-- 计算订单总金额
SELECT SUM(amount) FROM orders;

-- 计算不同产品的销售总额(去重)
SELECT SUM(DISTINCT price) FROM products;

3.avg() 平均值

        计算某列的平均值(忽略 NULL)。

AVG(column)
AVG(DISTINCT column)  -- 去重后计算平均值
-- 计算员工的平均工资
SELECT AVG(salary) FROM employees;

-- 计算不同产品的平均价格(去重)
SELECT AVG(DISTINCT price) FROM products;

4.max() 最大值

        返回某列的最大值(适用于数字、日期、字符串)。

MAX(column)
-- 查找最高工资
SELECT MAX(salary) FROM employees;

-- 查找最近注册的用户
SELECT MAX(register_date) FROM users;

-- 查找字母排序最大的名字
SELECT MAX(name) FROM customers;  -- 'Z' 会排在 'A' 前面

5.min() 最小值

        返回某列的最小值(适用于数字、日期、字符串)。

MIN(column)
-- 查找最低价格
SELECT MIN(price) FROM products;

-- 查找最早的订单日期
SELECT MIN(order_date) FROM orders;

-- 查找字母排序最小的名字
SELECT MIN(name) FROM customers;  -- 'A' 会排在 'Z' 前面

18)分组统计

        按指定列分组,并对每组数据进行聚合计算(如 COUNT, SUM, AVG 等)。

SELECT 列1, 列2, 聚合函数(列3)
FROM 表名
WHERE 条件
GROUP BY 列1, 列2;
-- 按部门统计员工数量
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department;

-- 按城市和性别统计用户数量
SELECT city, gender, COUNT(*) AS user_count
FROM users
GROUP BY city, gender;

-- 计算每个产品的销售总额
SELECT product_id, SUM(amount) AS total_sales
FROM orders
GROUP BY product_id;

having------分组过滤结果

        对 GROUP BY 分组后的数据进行筛选(类似于 WHERE,但用于聚合值)。

SELECT 列1, 聚合函数(列2)
FROM 表名
GROUP BY 列1
HAVING 聚合函数(列2) 条件;
-- 筛选员工数超过 5 人的部门
SELECT department, COUNT(*) AS employee_count
FROM employees
GROUP BY department
HAVING COUNT(*) > 5;

-- 筛选平均工资超过 8000 的部门
SELECT department, AVG(salary) AS avg_salary
FROM employees
GROUP BY department
HAVING AVG(salary) > 8000;

-- 筛选总销售额超过 10000 的产品
SELECT product_id, SUM(amount) AS total_sales
FROM orders
GROUP BY product_id
HAVING SUM(amount) > 10000;

having与where对比: 

特性 WHERE HAVING
执行时机 在分组前过滤数据(原始数据) 在分组后过滤数据
能否使用聚合函数 ❌ 不能 ✅ 可以
能否使用普通列 ✅ 可以 ✅ 可以(但通常用于聚合列)
是否依赖 GROUP BY ❌ 不依赖 ✅ 依赖(除非聚合未分组)

19)字符串函数

字符串长度与比较函数:

​​LENGTH(str)​​:返回字符串的字节长度

SELECT LENGTH('MySQL'); → 5

​​CHAR_LENGTH(str) / CHARACTER_LENGTH(str)​​:返回字符串的字符数

SELECT CHAR_LENGTH('数据库'); → 3

​​STRCMP(expr1, expr2)​​:比较两个字符串,返回0(相等)、1(expr1>expr2)或-1(expr1<expr2)

SELECT STRCMP('text', 'text2'); → -1

字符串连接函数:

​​CONCAT(str1, str2, ...)​​:连接多个字符串

SELECT CONCAT('My', 'SQL'); → 'MySQL'

​​CONCAT_WS(separator, str1, str2, ...)​​:用指定分隔符连接字符串

SELECT CONCAT_WS(',', 'John', 'Doe'); → 'John,Doe'

大小写转换函数:

​​LOWER(str) / LCASE(str)​​:转换为小写

SELECT LOWER('MySQL'); → 'mysql'

​​UPPER(str) / UCASE(str)​​:转换为大写

SELECT UPPER('mysql'); → 'MYSQL'

字符串截取与提取函数:

​​SUBSTRING(str, pos, len) / SUBSTR(str, pos, len) / MID(str, pos, len)​​:从位置pos开始截取len个字符

SELECT SUBSTRING('MySQL', 3, 2); → 'SQ'

​​LEFT(str, len)​​:从左开始截取指定长度

SELECT LEFT('MySQL', 2); → 'My'

​​RIGHT(str, len)​​:从右开始截取指定长度

SELECT RIGHT('MySQL', 3); → 'SQL'

字符串查找函数:

​​LOCATE(substr, str, pos) / POSITION(substr IN str)​​:返回子串位置(从1开始),找不到返回0

SELECT LOCATE('SQL', 'MySQL'); → 3

​​INSTR(str, substr)​​:类似LOCATE但参数顺序相反

SELECT INSTR('MySQL', 'SQL'); → 3

​​FIND_IN_SET(str, strlist)​​:在逗号分隔的列表中查找字符串

SELECT FIND_IN_SET('b', 'a,b,c,d'); → 2

字符串替换与修改函数:

​​REPLACE(str, from_str, to_str)​​:替换字符串中的子串

SELECT REPLACE('www.mysql.com', 'w', 'W'); → 'WWW.mysql.com'

​​INSERT(str, pos, len, newstr)​​:在指定位置插入/替换字符串

SELECT INSERT('Quadratic', 3, 4, 'What'); → 'QuWhattic'

​​TRIM([{BOTH | LEADING | TRAILING} [remstr] FROM] str)​​:去除两端空格或指定字符

SELECT TRIM(' MySQL '); → 'MySQL'
SELECT TRIM(LEADING 'x' FROM 'xxxMySQLxxx'); → 'MySQLxxx'

​​LTRIM(str) / RTRIM(str)​​:去除左/右空格

SELECT LTRIM(' MySQL'); → 'MySQL'

字符串填充函数:

​​LPAD(str, len, padstr)​​:左侧填充到指定长度

SELECT LPAD('MySQL', 10, '*'); → '​​​​*MySQL'

​​RPAD(str, len, padstr)​​:右侧填充到指定长度

SELECT RPAD('MySQL', 10, '*'); → 'MySQL​​​​*'

格式化与转换函数:

​​FORMAT(X, D)​​:数字格式化

SELECT FORMAT(12345.6789, 2); → '12,345.68'

​​HEX(str) / UNHEX(str)​​:字符串与十六进制转换

SELECT HEX('MySQL'); → '4D7953514C'

​​BIN(n) / OCT(n) / HEX(n)​​:数字转换为二进制/八进制/十六进制字符串

SELECT BIN(12); → '1100'

20)数学函数

基本数学运算函数:

​ABS(X)​​:返回X的绝对值

SELECT ABS(-32); → 32

​SIGN(X)​​:返回X的符号:-1(负数)、0(零)或1(正数)

SELECT SIGN(-5); → -1

​MOD(N,M) 或 %​​:返回N除以M的余数

SELECT MOD(15,4); → 3

SELECT 15 % 4; → 3

​CEIL(X) / CEILING(X)​​:向上取整

SELECT CEIL(3.2); → 4

​FLOOR(X)​​:向下取整

SELECT FLOOR(3.7); → 3

​ROUND(X, D)​​:四舍五入,D指定小数位数

SELECT ROUND(3.14159, 2); → 3.14

​TRUNCATE(X, D)​​:截断数字,保留D位小数

SELECT TRUNCATE(3.14159, 2); → 3.14

指数与对数函数:

​POW(X,Y) / POWER(X,Y)​​:返回X的Y次方

SELECT POW(2,3); → 8

​SQRT(X)​​:返回X的平方根

SELECT SQRT(25); → 5

​EXP(X)​​:返回e的X次方

SELECT EXP(1); → 2.718281828459045

​LN(X) / LOG(X)​​:返回X的自然对数(以e为底)

SELECT LN(2.718281828459045); → 1.0

​LOG10(X)​​:返回X的常用对数(以10为底)

SELECT LOG10(100); → 2

​LOG2(X)​​:返回X的以2为底的对数

SELECT LOG2(8); → 3

随机数函数:

​RAND() / RAND(N)​​:返回0到1之间的随机浮点数,N为种子值

SELECT RAND(); → 0.8407172561533891

SELECT RAND(5); → 0.406135472887009 (固定种子产生固定随机数)

21)日期函数

获取当前日期和时间:

​NOW() / SYSDATE() / CURRENT_TIMESTAMP()​​:返回当前日期和时间

SELECT NOW(); → '2023-11-15 14:30:45'

​CURDATE() / CURRENT_DATE()​​:返回当前日期

SELECT CURDATE(); → '2023-11-15'

​CURTIME() / CURRENT_TIME()​​:返回当前时间

SELECT CURTIME(); → '14:30:45'

​UTC_DATE() / UTC_TIME() / UTC_TIMESTAMP()​​:返回UTC日期/时间/时间戳

SELECT UTC_TIMESTAMP(); → '2023-11-15 06:30:45' (UTC时间)

日期时间计算函数:

​DATE_ADD(date, INTERVAL expr unit) / ADDDATE(date, INTERVAL expr unit)​​:日期加法

SELECT DATE_ADD('2023-11-15', INTERVAL 1 MONTH); → '2023-12-15'

​DATE_SUB(date, INTERVAL expr unit) / SUBDATE(date, INTERVAL expr unit)​​:日期减法

SELECT DATE_SUB('2023-11-15', INTERVAL 1 WEEK); → '2023-11-08'

​ADDTIME(expr1, expr2)​​:时间加法

SELECT ADDTIME('14:30:45', '02:15:30'); → '16:46:15'

​SUBTIME(expr1, expr2)​​:时间减法

SELECT SUBTIME('14:30:45', '02:15:30'); → '12:15:15'

​DATEDIFF(expr1, expr2)​​:计算两个日期之间的天数差(expr1 - expr2)

SELECT DATEDIFF('2023-11-20', '2023-11-15'); → 5

​TIMEDIFF(expr1, expr2)​​:计算两个时间之间的差值

SELECT TIMEDIFF('14:30:45', '10:15:30'); → '04:15:15'

​TIMESTAMPDIFF(unit, datetime1, datetime2)​​:计算两个日期时间的差值,返回指定单位的结果

SELECT TIMESTAMPDIFF(MONTH, '2023-01-01', '2023-11-15'); → 10

22)加密函数

        MySQL提供了一系列加密和哈希函数,用于数据安全、密码存储和数据保护。以下是MySQL中常用的加密函数分类详解:

哈希函数:

​MD5(str)​​:计算字符串的MD5 128位哈希值(32位十六进制字符串)

安全性较低,不建议用于密码存储

SELECT MD5('password'); → '5f4dcc3b5aa765d61d8327deb882cf99'

​SHA1(str) / SHA(str)​​:计算字符串的SHA1 160位哈希值(40位十六进制字符串)

比MD5更安全但仍不够强

SELECT SHA1('password'); → '5baa61e4c9b93f3f0682250b6cf8331b7ee68fd8'

​SHA2(str, hash_length)​​:计算SHA2哈希系列(SHA-224, SHA-256, SHA-384, SHA-512)

参数hash_length可以是224、256、384或512

推荐用于安全应用

SELECT SHA2('password', 256); → '5e884898da28047151d0e56f8dc6292773603d0d6aabbdd62a11ef721d1542d8'

​PASSWORD(str)​​:MySQL特有的密码哈希函数(用于mysql.user表)

不同MySQL版本算法不同

不建议在应用中使用

SELECT PASSWORD('password'); → '*2470C0C06DEE42FD1618BB99005ADCA2EC9D1E19'

加密/解密函数:

​AES_ENCRYPT(str, key_str)​​:使用AES算法加密字符串(高级加密标准)

返回二进制数据

SELECT AES_ENCRYPT('secret', 'encryption_key'); → [二进制数据]

​AES_DECRYPT(crypt_str, key_str)​​:解密AES_ENCRYPT加密的数据

SELECT AES_DECRYPT(AES_ENCRYPT('secret', 'encryption_key'), 'encryption_key'); → 'secret'

​ENCODE(str, pass_str)​​:使用pass_str作为密码加密str

安全性较低,已弃用

SELECT ENCODE('secret', 'password'); → [二进制数据]

​DECODE(crypt_str, pass_str)​​:解密ENCODE加密的数据

SELECT DECODE(ENCODE('secret', 'password'), 'password'); → 'secret'

​DES_ENCRYPT(str[, {key_num | key_str}])​:使用DES算法加密(需要SSL支持)

SELECT DES_ENCRYPT('secret', 'password'); → [二进制数据]

​DES_DECRYPT(crypt_str[, key_str])​​:解密DES_ENCRYPT加密的数据

SELECT DES_DECRYPT(DES_ENCRYPT('secret', 'password'), 'password'); → 'secret'

随机值生成:

​RAND()​​:生成0到1之间的随机浮点数

SELECT RAND(); → 0.8407172561533891

​RAND(N)​​:使用种子N生成可重复的随机数序列

SELECT RAND(5); → 0.406135472887009

​UUID()​​:生成通用唯一标识符(UUID)

格式:xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx

SELECT UUID(); → 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'SELECT UUID(); → 'a0eebc99-9c0b-4ef8-bb6d-6bb9bd380a11'

​UUID_SHORT()​​:生成64位无符号整数的UUID

SELECT UUID_SHORT(); → 92395783848258765

23)流程控制函数

        MySQL提供了一系列流程控制函数,用于在SQL查询中实现条件逻辑和流程控制。这些函数可以极大地增强SQL的表达能力,使查询更加灵活和强大。

条件判断函数:

1. IF函数

​语法​​:IF(expr1, expr2, expr3)

  • 如果expr1为TRUE(expr1 ≠ 0且expr1 ≠ NULL),返回expr2,否则返回expr3
  • 类似于其他编程语言中的三元运算符
SELECT IF(1 > 2, 'true', 'false'); -- 返回 'false' SELECT IF(2 > 1, 'true', 'false'); -- 返回 'true' SELECT IF(NULL, 'not null', 'null'); -- 返回 'null'

2. IFNULL函数

​语法​​:IFNULL(expr1, expr2)

如果expr1不为NULL,返回expr1,否则返回expr2

SELECT IFNULL(NULL, 'default value'); -- 返回 'default value' SELECT IFNULL('not null', 'default'); -- 返回 'not null'

3. NULLIF函数

​语法​​:NULLIF(expr1, expr2)

  • 如果expr1 = expr2,返回NULL,否则返回expr1
  • 用于避免除零错误等场景
SELECT NULLIF(1, 1); -- 返回 NULL SELECT NULLIF(1, 2); -- 返回 1

24)分页查询

        MySQL 分页查询是数据库操作中非常常见的需求,主要用于处理大量数据时的分批显示。

SELECT * FROM table_name LIMIT offset, row_count;
-- 或者
SELECT * FROM table_name LIMIT row_count OFFSET offset;
-- 获取前10条记录
SELECT * FROM users LIMIT 10;

-- 获取第11-20条记录(第二页,每页10条)
SELECT * FROM users LIMIT 10, 10;
-- 或者
SELECT * FROM users LIMIT 10 OFFSET 10;

25)all、any的使用

        ALL 操作符表示"所有"或"每一个",只有当比较操作对所有子查询返回的值都为真时,整个表达式才为真。

        查找比所有部门平均工资都高的员工:

SELECT name, salary
FROM employees
WHERE salary > ALL (
    SELECT AVG(salary)
    FROM employees
    GROUP BY department_id
);

  ANY 操作符表示"任意一个"或"至少一个",只要比较操作对子查询返回的任何一个值为真,整个表达式就为真。 

        查找工资高于任何部门平均工资的员工:

SELECT name, salary
FROM employees
WHERE salary > ANY (
    SELECT AVG(salary)
    FROM employees
    GROUP BY department_id
);

26)表复制操作

只复制表结构:

CREATE TABLE employees_copy LIKE employees;

复制表结构及数据:

CREATE TABLE employees_copy AS SELECT * FROM employees;

27)左外连、右外连

-- 查询所有员工及其部门信息(包括没有部门的员工)
SELECT e.employee_id, e.name, d.department_name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id;

-- 使用WHERE子句筛选右表为NULL的记录(查找没有部门的员工)
SELECT e.employee_id, e.name
FROM employees e
LEFT JOIN departments d ON e.dept_id = d.dept_id
WHERE d.dept_id IS NULL;

28)primary key

CREATE TABLE users (
    user_id INT PRIMARY KEY,
    username VARCHAR(50) NOT NULL
);

特点:

  • 数据不能重复且不能为NULL
  • 一张表只能有一个主键,但可以是复合主键,例如:
    primary key(id,`name`)
  • 两种定义方式:
    1.字段名 primary key
    2.primary key 列名
  • 通过desc表名可以看到主键情况

29)unique 

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    email VARCHAR(100) UNIQUE,
    phone VARCHAR(20)
);

特点:

  • 数据不可重复但可为NULL
  • 可以定义多个unique

30)foreign key

-- 创建表时定义
CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    customer_id INT,
    order_date DATE,
    FOREIGN KEY (customer_id) REFERENCES customers(customer_id)
);

-- 添加外键到已有表
ALTER TABLE order_items
ADD FOREIGN KEY (order_id) REFERENCES orders(order_id);

-- 指定操作行为
CREATE TABLE order_items (
    item_id INT PRIMARY KEY,
    order_id INT,
    product_id INT,
    FOREIGN KEY (order_id) REFERENCES orders(order_id)
    ON DELETE CASCADE
    ON UPDATE CASCADE
);

 特点:

  • 外键指向的表的字段,要求是primary key或者是unique
  • 表的类型是innodb才支持外键
  • 外键字段的类型要和主键字段的类型一致
  • 外键字段的值必须在主键字段中出现过或者为NULL,前提是主键允许为NULL
  • 不能随意删除主外键

31)check 

        用于限制字段,不符合则会报错

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    salary DECIMAL(10,2) CHECK (salary > 0),
    age INT CHECK (age >= 18 AND age <= 65)
);

32)default

CREATE TABLE orders (
    order_id INT PRIMARY KEY,
    order_date DATE DEFAULT CURRENT_DATE(),
    status VARCHAR(20) DEFAULT 'Pending'
);

 特点:

  1. 为列提供默认值

  2. 当插入数据未指定值时使用

33)auto_increment

CREATE TABLE employees (
    emp_id INT PRIMARY KEY,
    name VARCHAR(50) NOT NULL,
    salary DECIMAL(10,2) CHECK (salary > 0),
    age INT CHECK (age >= 18 AND age <= 65)
);

特点:

  1. 唯一性:保证每行有唯一标识为主键或unique

  2. 自动递增:每次插入新行时自动增加

  3. 可配置性:可以设置起始值和增量

  4. 可重置:可以重新设置当前值

34)索引

        索引是数据库中一种特殊的数据结构,它类似于书籍的目录,能够帮助数据库引擎快速定位数据。

索引底层为B+。

索引的优点:

  • 大大加快数据检索速度

  • 加速表连接操作

  • 优化排序和分组操作

  • 实现唯一性约束

索引的缺点:

  • 占用额外的存储空间

  • 降低数据写入速度(增删改操作需要维护索引)

  • 增加数据库维护开销

1.普通索引:

-- 创建表时添加
CREATE TABLE users (
    id INT,
    username VARCHAR(50),
    INDEX idx_username (username)
);

-- 后期添加
CREATE INDEX idx_username ON users(username);

 2.唯一索引:

CREATE TABLE users (
    email VARCHAR(100),
    UNIQUE INDEX idx_email (email)
);

-- 后期添加
CREATE UNIQUE INDEX idx_email ON users(email);

 3.主键索引

CREATE TABLE users (
    id INT PRIMARY KEY,
    username VARCHAR(50)
);

35)删除索引

1.使用drop index

DROP INDEX idx_username ON users;

2.使用alter table

ALTER TABLE customers DROP INDEX idx_email;

删除主键索引:

ALTER TABLE orders DROP PRIMARY KEY;

36)事务

        事务是数据库管理系统中的一个重要概念,它保证了数据库操作的完整性和一致性。下面详细介绍MySQL中的事务机制。

        事务(Transaction)是数据库操作的最小工作单位,是一组不可再分割的操作集合。事务具有以下特性(ACID): 

  1. 原子性(Atomicity):事务中的所有操作要么全部完成,要么全部不完成

  2. 一致性(Consistency):事务执行前后,数据库从一个一致状态变为另一个一致状态

  3. 隔离性(Isolation):多个事务并发执行时,一个事务的执行不应影响其他事务

  4. 持久性(Durability):事务一旦提交,其结果就是永久性的

开启事务:

START TRANSACTION;
-- 或者
BEGIN;

提交事务:

COMMIT;

回滚事务:

ROLLBACK;

设置保存点:

SAVEPOINT savepoint_name;
ROLLBACK TO savepoint_name;
RELEASE SAVEPOINT savepoint_name;

37)事务隔离级别

        MySQL支持四种事务隔离级别:

  1. READ UNCOMMITTED (读未提交):最低隔离级别,允许读取未提交的数据变更

  2. READ COMMITTED (读已提交):只能读取已提交的数据

  3. REPEATABLE READ (可重复读):MySQL默认级别,确保同一事务中多次读取同样数据结果一致

  4. SERIALIZABLE (串行化):最高隔离级别,完全串行执行事务

设置隔离级别:

SET TRANSACTION ISOLATION LEVEL level;
-- 例如
SET TRANSACTION ISOLATION LEVEL READ COMMITTED;

查看当前会话隔离级别:

SELECT @@transaction_isolation;
-- 或者
SELECT @@tx_isolation;  -- MySQL 8.0之前版本

查看全局隔离级别:

SELECT @@global.transaction_isolation;
-- 或者
SELECT @@global.tx_isolation;  -- MySQL 8.0之前版本

38)事务并发问题

1. 脏读(Dirty Read):

  • 定义:一个事务读取了另一个未提交事务修改过的数据

  • 场景

    • 事务A修改了某行数据但未提交

    • 事务B读取了事务A修改后的数据

    • 事务A回滚,事务B读取到的数据实际上是无效的

2. 不可重复读(Non-repeatable Read):

  • 定义:同一事务内,多次读取同一数据返回不同结果

  • 场景

    • 事务A第一次读取某行数据

    • 事务B修改了该行数据并提交

    • 事务A再次读取同一行数据,发现数据已改变

3. 幻读(Phantom Read)

  • 定义:同一事务内,相同的查询条件返回不同的行集

  • 场景

    • 事务A查询符合某个条件的多行数据

    • 事务B插入或删除了符合该条件的行并提交

    • 事务A再次查询,发现行数变化了

4. 丢失更新(Lost Update):

  • 定义:两个事务同时更新同一数据,后提交的事务覆盖了先提交的事务的更新

  • 场景

    • 事务A和事务B同时读取某行数据

    • 事务A先修改数据并提交

    • 事务B随后修改数据并提交,覆盖了事务A的修改

隔离级别 脏读 不可重复读 幻读 丢失更新
READ UNCOMMITTED (读未提交)
READ COMMITTED (读已提交) ×
REPEATABLE READ (可重复读) × × ×
SERIALIZABLE (串行化) × × × ×
  • 可重复读在MySQL中通过多版本并发控制(MVCC)和间隙锁(Gap Lock)避免了幻读问题

  • 丢失更新问题通常需要通过应用层逻辑或乐观锁/悲观锁来解决

各隔离级别特点及应用场景: 

  1. READ UNCOMMITTED

    • 性能最好,但数据一致性最差

    • 适用于对数据准确性要求不高但要求高并发的场景

  2. READ COMMITTED

    • 避免了脏读

    • Oracle等数据库的默认级别

    • 适用于大多数OLTP系统

  3. REPEATABLE READ

    • MySQL的默认级别

    • 避免了脏读和不可重复读

    • 通过MVCC和间隙锁也避免了幻读

  4. SERIALIZABLE

    • 完全串行执行,性能最差

    • 数据一致性最好

    • 适用于对数据一致性要求极高的场景

39)存储引擎

        MySQL支持多种存储引擎,每种引擎都有其特点和适用场景。存储引擎是MySQL的核心组件,负责数据的存储、检索和管理。

常见存储引擎对比:

特性 InnoDB MyISAM MEMORY ARCHIVE CSV
事务支持 支持(ACID) 不支持 不支持 不支持 不支持
锁机制 行级锁 表级锁 表级锁 行级锁 表级锁
外键支持 支持 不支持 不支持 不支持 不支持
MVCC 支持 不支持 不支持 不支持 不支持
缓存 数据+索引 仅索引 内存中
存储限制 64TB 256TB 内存大小 系统限制
崩溃恢复 支持 有限支持 数据丢失 支持 有限支持
全文索引 5.6+支持 支持 不支持 不支持 不支持
适用场景 事务型应用 只读/读密集型 临时表/缓存 日志/归档 数据交换

1. InnoDB (默认引擎):

特点

  • 支持事务处理(ACID兼容)

  • 行级锁定和外键约束

  • 支持MVCC(多版本并发控制)

  • 自动崩溃恢复

  • 聚集索引(主键索引直接包含数据)

适用场景

  • 需要事务支持的应用

  • 高并发读写操作

  • 需要外键约束的应用

  • 需要崩溃后自动恢复的场景

2. MyISAM:

特点

  • 表级锁定

  • 全文索引支持

  • 较高的读取性能

  • 不支持事务

  • 数据文件(.MYD)和索引文件(.MYI)分离

适用场景

  • 只读或读多写少的应用

  • 需要全文索引的应用(MySQL 5.6前)

  • 数据仓库类应用

3. MEMORY (HEAP):

特点

  • 数据存储在内存中

  • 表级锁定

  • 不支持BLOB/TEXT类型

  • 服务器重启后数据丢失

  • 哈希索引默认

适用场景

  • 临时表

  • 缓存小型数据集

  • 快速查找的只读数据

4. ARCHIVE:

特点

  • 只支持INSERT和SELECT

  • 高压缩比(10:1)

  • 行级锁定

  • 不支持索引(除自增主键)

适用场景

  • 日志和审计数据存储

  • 历史归档数据

  • 很少查询的大量数据

如何选择存储引擎? 

  1. 常规OLTP应用:优先选择InnoDB

    • 支持事务

    • 行级锁定

    • 崩溃恢复

  2. 只读/分析型应用:可考虑MyISAM

    • 读取速度快

    • 全表扫描性能好

  3. 临时数据处理:可使用MEMORY引擎

    • 内存速度快

    • 临时计算结果存储

  4. 归档存储:ARCHIVE引擎

    • 高压缩比

    • 节省存储空间

查看支持的存储引擎:

SHOW ENGINES;

 查看表的存储引擎:

SHOW TABLE STATUS LIKE '表名';
-- 或
SHOW CREATE TABLE 表名;

修改表的存储引擎:

ALTER TABLE 表名 ENGINE = InnoDB;

40)视图

        视图(VIEW)是MySQL中非常重要的数据库对象,它提供了一种虚拟表的方式来组织和简化数据访问。

1. 什么是视图:

  • 视图是基于SQL语句的结果集的虚拟表

  • 视图不实际存储数据,数据来自基表

  • 视图可以像普通表一样被查询、过滤和连接

2. 视图的特点:

  • 简化复杂查询:封装复杂SQL,使查询更简单

  • 数据安全:隐藏敏感列,只暴露必要数据

  • 逻辑独立性:基表结构变化不影响应用程序

  • 多表统一访问:将多个表的数据整合为一个虚拟表

创建视图:

CREATE [OR REPLACE] VIEW 视图名 [(列名1, 列名2, ...)]
AS 
SELECT语句
[WITH [CASCADED | LOCAL] CHECK OPTION];

 示例:

CREATE VIEW myview AS
SELECT `name`
FROM student

修改视图:

ALTER VIEW 视图名 [(列名1, 列名2, ...)]
AS 
SELECT语句
[WITH CHECK OPTION];

删除视图:

DROP VIEW [IF EXISTS] 视图名;

查看视图定义:

SHOW CREATE VIEW 视图名;

41)用户管理

        MySQL用户管理是数据库安全的重要组成部分,涉及用户账号的创建、权限分配、密码策略等多个方面。

创建用户:

CREATE USER 'username'@'host' IDENTIFIED BY 'password';
CREATE USER 'dev_user'@'localhost' IDENTIFIED BY 'Password123!';
CREATE USER 'remote_user'@'192.168.1.%' IDENTIFIED BY 'SecurePass456';

修改用户:

-- 修改用户名
RENAME USER 'old_user'@'host' TO 'new_user'@'host';

-- 修改密码(MySQL 5.7+)
ALTER USER 'username'@'host' IDENTIFIED BY 'new_password';

-- 修改密码(MySQL 5.6及以下)
SET PASSWORD FOR 'username'@'host' = PASSWORD('new_password');

删除用户:

DROP USER 'username'@'host';

查看用户列表: 

SELECT User, Host FROM mysql.user;

42)权限管理

权限授予:

GRANT 权限类型 ON 数据库.表 TO 'username'@'host';
-- 授予特定数据库的所有权限
GRANT ALL PRIVILEGES ON mydb.* TO 'dev_user'@'localhost';

-- 授予特定表的SELECT权限
GRANT SELECT ON mydb.employees TO 'report_user'@'%';

-- 授予多个权限
GRANT SELECT, INSERT, UPDATE ON mydb.* TO 'app_user'@'192.168.1.%';

权限回收:

REVOKE 权限类型 ON 数据库.表 FROM 'username'@'host';
REVOKE INSERT ON mydb.* FROM 'app_user'@'192.168.1.%';

查看用户权限:

SHOW GRANTS FOR 'username'@'host';
Logo

一站式 AI 云服务平台

更多推荐