【MySQL运维DBA】【SQL基础系列002篇】

文章目录

在MySQL中,DDL(数据定义语言)、DCL(数据控制语言)和DML(数据操作语言)是三种主要的SQL语言类别。然而,由于每种类别的语句数量有限,且部分语句在实际使用中可能较为罕见,因此我将为每个类别提供尽可能多且实用的语句实例,并附上相应的说明。但请注意,可能无法严格达到每个类别20个实例的要求。

DDL(数据定义语言)

DDL语句主要用于定义和管理数据库结构,包括创建、修改和删除数据库对象(如表、索引等)。

  1. 创建数据库

    sql 复制代码
    CREATE DATABASE mydb;

    说明:创建一个名为mydb的数据库。

  2. 删除数据库

    sql 复制代码
    DROP DATABASE mydb;

    说明:删除名为mydb的数据库。

  3. 创建表

    sql 复制代码
    CREATE TABLE users (
        id INT AUTO_INCREMENT PRIMARY KEY,
        username VARCHAR(50) NOT NULL,
        email VARCHAR(100) UNIQUE
    );

    说明:在mydb数据库中创建一个名为users的表,包含id、username和email字段。

  4. 删除表

    sql 复制代码
    DROP TABLE users;

    说明:删除名为users的表。

  5. 修改表结构 - 添加字段

    sql 复制代码
    ALTER TABLE users ADD COLUMN age INT;

    说明:在users表中添加一个名为age的字段。

  6. 修改表结构 - 删除字段

    sql 复制代码
    ALTER TABLE users DROP COLUMN age;

    说明:从users表中删除名为age的字段。

  7. 修改表结构 - 修改字段类型

    sql 复制代码
    ALTER TABLE users MODIFY COLUMN username VARCHAR(100);

    说明:将users表中的username字段类型修改为VARCHAR(100)。

  8. 修改表结构 - 重命名字段

    sql 复制代码
    ALTER TABLE users CHANGE COLUMN email mail VARCHAR(150);

    说明:将users表中的email字段重命名为mail,并修改其类型为VARCHAR(150)。

  9. 创建索引

    sql 复制代码
    CREATE INDEX idx_username ON users(username);

    说明:在users表的username字段上创建索引,以提高查询性能。

  10. 删除索引

    sql 复制代码
    DROP INDEX idx_username ON users;

    说明:删除users表上的idx_username索引。

(由于DDL语句数量有限,且部分高级用法不常用,以下仅列出部分额外实例)

  1. 创建视图

    sql 复制代码
    CREATE VIEW user_view AS SELECT id, username FROM users;

    说明:创建一个名为user_view的视图,包含users表中的id和username字段。

  2. 删除视图

    sql 复制代码
    DROP VIEW user_view;

    说明:删除名为user_view的视图。

  3. 创建存储过程

    sql 复制代码
    DELIMITER //
    CREATE PROCEDURE AddUser(IN uname VARCHAR(50), IN uemail VARCHAR(100))
    BEGIN
        INSERT INTO users(username, email) VALUES(uname, uemail);
    END //
    DELIMITER ;

    说明:创建一个名为AddUser的存储过程,用于向users表中插入新用户。

  4. 删除存储过程

    sql 复制代码
    DROP PROCEDURE AddUser;

    说明:删除名为AddUser的存储过程。

(以下DDL语句较为罕见或特定于某些场景,因此简要列出)

15-20. (包含分区表创建、触发器创建与删除、事件调度器创建与删除等高级用法,由于篇幅限制,此处不详细展开,但可根据MySQL官方文档或相关教程获取具体实例)

DCL(数据控制语言)

DCL语句主要用于控制数据库的访问权限和安全级别。

  1. 授予用户权限

    sql 复制代码
    GRANT SELECT, INSERT ON mydb.* TO 'username'@'host' IDENTIFIED BY 'password';

    说明:授予用户username在host主机上使用密码password登录,并对mydb数据库具有SELECT和INSERT权限。

  2. 撤销用户权限

    sql 复制代码
    REVOKE SELECT, INSERT ON mydb.* FROM 'username'@'host';

    说明:撤销用户username在host主机上对mydb数据库的SELECT和INSERT权限。

  3. 创建用户

    sql 复制代码
    CREATE USER 'newuser'@'localhost' IDENTIFIED BY 'password';

    说明:在本地主机上创建一个名为newuser的用户,并设置密码为password。

  4. 删除用户

    sql 复制代码
    DROP USER 'newuser'@'localhost';

    说明:删除本地主机上的newuser用户。

  5. 查看用户权限

    sql 复制代码
    SHOW GRANTS FOR 'username'@'host';

    说明:查看用户username在host主机上的权限。

  6. 修改用户密码

    sql 复制代码
    SET PASSWORD FOR 'username'@'host' = PASSWORD('newpassword');

    说明:修改用户username在host主机上的密码为newpassword。

(由于DCL语句相对有限,以下仅列出部分额外实例,部分可能涉及高级权限管理)

7-10. (包含授予/撤销特定表的权限、授予/撤销执行存储过程的权限等)

复制代码
例如:
```sql
GRANT SELECT ON mydb.users TO 'readonlyuser'@'localhost';
REVOKE EXECUTE ON PROCEDURE mydb.AddUser FROM 'someuser'@'host';
```

11-20. (涉及角色管理、全局权限授予与撤销等高级用法,由于篇幅和复杂性限制,此处不详细展开)

DML(数据操作语言)

DML语句主要用于对数据库中的数据进行查询、插入、更新和删除操作。

  1. 插入数据

    sql 复制代码
    INSERT INTO users(username, email) VALUES('john', 'john@example.com');

    说明:向users表中插入一条新记录。

  2. 查询数据

    sql 复制代码
    SELECT * FROM users;

    说明:查询users表中的所有记录。

  3. 更新数据

    sql 复制代码
    UPDATE users SET email = 'john_new@example.com' WHERE username = 'john';

    说明:更新users表中username为john的记录的email字段。

  4. 删除数据

    sql 复制代码
    DELETE FROM users WHERE username = 'john';

    说明:删除users表中username为john的记录。

  5. 条件查询

    sql 复制代码
    SELECT * FROM users WHERE age > 25;

    说明:查询users表中年龄大于25岁的所有记录。

  6. 排序查询

    sql 复制代码
    SELECT * FROM users ORDER BY username ASC;

    说明:按username字段升序查询users表中的所有记录。

  7. 聚合查询

    sql 复制代码
    SELECT COUNT(*) FROM users;

    说明:查询users表中的记录总数。

  8. 分组查询

    sql 复制代码
    SELECT gender, COUNT(*) FROM users GROUP BY gender;

    说明:按gender字段分组查询users表中的记录数。

  9. 连接查询 (假设有orders表与users表关联)

    sql 复制代码
    SELECT users.username, orders.order_date FROM users INNER JOIN orders ON users.id = orders.user_id;

    说明:通过内连接查询users表和orders表,获取用户及其订单信息。

  10. 子查询

    sql 复制代码
    SELECT * FROM users WHERE id IN (SELECT user_id FROM orders WHERE order_date > '2023-01-01');

    说明:查询在2023-01-01之后有订单的所有用户。

当然,DML(Data Manipulation Language,数据操作语言)语句在涉及更复杂的查询和操作时会用到多种高级SQL特性,如联合查询(UNION)、窗口函数(Window Functions)等。下面是一些示例,展示如何在DML语句中结合这些高级特性。

联合查询(UNION)

联合查询用于合并两个或多个SELECT语句的结果集。每个SELECT语句必须有相同数量的列,并且相应的列必须具有兼容的数据类型。

sql 复制代码
-- 查询部门ID为10和20的所有员工信息
SELECT emp_id, emp_name, dept_id, salary
FROM employees
WHERE dept_id = 10
UNION
SELECT emp_id, emp_name, dept_id, salary
FROM employees
WHERE dept_id = 20;

使用窗口函数

窗口函数用于在结果集的行上执行计算,而不将结果集聚合为单个输出行。常见的窗口函数包括ROW_NUMBER(), RANK(), DENSE_RANK(), NTILE(), LEAD(), 和 LAG()等。

sql 复制代码
-- 查询每个部门的员工,并按薪水排序,同时显示员工的薪水排名
SELECT 
    emp_id, 
    emp_name, 
    dept_id, 
    salary,
    RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_rank
FROM employees;

联合查询结合窗口函数

将联合查询与窗口函数结合使用,可以实现更复杂的查询需求。例如,查询两个部门中每个员工的薪水排名,并合并结果。

sql 复制代码
WITH ranked_dept_10 AS (
    SELECT 
        emp_id, 
        emp_name, 
        dept_id, 
        salary,
        RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_rank
    FROM employees
    WHERE dept_id = 10
),
ranked_dept_20 AS (
    SELECT 
        emp_id, 
        emp_name, 
        dept_id, 
        salary,
        RANK() OVER (PARTITION BY dept_id ORDER BY salary DESC) AS salary_rank
    FROM employees
    WHERE dept_id = 20
)
SELECT 
    emp_id, 
    emp_name, 
    dept_id, 
    salary, 
    salary_rank
FROM ranked_dept_10
UNION ALL
SELECT 
    emp_id, 
    emp_name, 
    dept_id, 
    salary, 
    salary_rank
FROM ranked_dept_20
ORDER BY dept_id, salary_rank;

复杂的DML操作:更新操作结合子查询和窗口函数

有时DML操作本身可能涉及复杂的子查询或窗口函数,虽然直接在UPDATE或DELETE语句中使用窗口函数不是所有数据库都支持,但可以通过CTE(Common Table Expressions)或临时表来实现。

sql 复制代码
-- 假设我们要更新薪水最低的5%的员工的薪水,增加10%
WITH low_salary_employees AS (
    SELECT 
        emp_id, 
        salary,
        NTILE(20) OVER (ORDER BY salary ASC) AS salary_tile
    FROM employees
)
UPDATE employees
SET salary = salary * 1.10
WHERE emp_id IN (
    SELECT emp_id
    FROM low_salary_employees
    WHERE salary_tile = 1
);

在这个例子中,我们使用了一个CTE来计算薪水最低的20个分组(NTILE(20)),然后选择了最低的分组(salary_tile = 1)进行更新。

总结

联合查询和窗口函数是SQL中的强大工具,可以显著增强查询的复杂性和功能。在实际应用中,合理使用这些特性可以极大地提高数据处理和分析的效率。

相关推荐
IT19955 小时前
Fail2Ban 防护 MySQL 实战|登录失败 3 次,IP 封禁 24 小时
数据库·mysql
桌面运维家7 小时前
旧电脑跑不动课程软件,VDI云桌面怎样接着用?
运维·服务器·虚拟化·pve·vdi·云桌面
zhang133830890757 小时前
传统机械三杯式风速传感器易磨损冻堵?CG-88金属超声波风速风向传感器给出免运维方案
运维·服务器·网络·人工智能·自动化
知已难寻7 小时前
第 2 篇 · 云的地基:服务器、存储、网络三大基础设施
运维·服务器·网络·云原生·云计算·负载均衡·1024程序员节
paopaokaka_luck8 小时前
流浪动物救助与收养系统(DeepSeek AI对话、 ECharts多维分析、救助流程衔接、领养与回访衔接、 捐赠确认与公示、志愿者协作)
java·前端·javascript·人工智能·mysql·echarts·推荐算法
2601_949847759 小时前
bcrypt.js 跨端三方库仓颉适配全流程
linux·运维·ubuntu
m0_639906949 小时前
Linux 操作系统入门:目录结构、服务排查常用命令、Shell 脚本基础
linux·运维·后端
lzhdim10 小时前
100条常用SQL语句
数据库·sql·mysql·mybatis
今天重构了吗10 小时前
Linux 上 rm -rf 删错了能找回吗
运维·服务器
KaiwuDB10 小时前
KaiwuDB 分布式集群扩缩容,从原理到完整操作踩坑总结
运维·数据库·分布式