MySQL |常用 SQL 语句与 pymysql 函数

前言:本篇为 MySQL 系列第二篇,承接上一篇 pymysql 连接 MySQL 基础,系统梳理 MySQL 常用 SQL 语法、语句分类,以及 pymysql 库核心 API。附带完整可运行 Python 示例,演示建库、建表、主外键、增删改查、事务回滚整套流程,适合 Python 操作 MySQL 入门学习。

一、完整示例代码

沿用 pymysql,一次性演示数据库连接、建库、建表、主键外键、多表关联查询、增删改查、事务回滚、删库全流程。

复制代码
import pymysql

database_name = 'testmysql'
delete_database = True  # True执行删库,False保留数据库
# delete_database = False

# 建立数据库连接
connection = pymysql.connect(
    host='localhost',
    port=3306,
    user='test',
    password='mysql',
    charset='utf8mb4',
    # database=database_name, # 先不指定库,后面手动use切换
)

# SQL语句定义
create_database_sql = f'CREATE DATABASE IF NOT EXISTS {database_name};'
show_sql = 'SHOW databases;'
goto_database = f'USE {database_name};'

# 创建班级表
create_table_Classes_sql = '''
CREATE TABLE IF NOT EXISTS 班级 (
    班号 INT AUTO_INCREMENT PRIMARY KEY,
    班名 VARCHAR(100) NOT NULL,
    班导 VARCHAR(100)
);
'''
# 创建学生表,设置外键,级联删除、级联更新
create_table_Students_sql = '''
CREATE TABLE IF NOT EXISTS 学生 (
    学号 INT AUTO_INCREMENT PRIMARY KEY,
    姓名 VARCHAR(100) NOT NULL,
    性别 ENUM('男', '女', '其他','直升机') NOT NULL,
    民族 VARCHAR(50),
    班级 INT,
    FOREIGN KEY (班级) REFERENCES 班级(班号) ON DELETE CASCADE ON UPDATE CASCADE
);
'''
delete_database_sql = f'DROP DATABASE IF EXISTS {database_name};'

try:
    with connection.cursor() as cursor:
        cursor.execute(show_sql)
        all_database_name = cursor.fetchall()
        if not (database_name,) in all_database_name:
            # 1. 创建数据库
            cursor.execute(create_database_sql)
            cursor.execute(show_sql)
            all_database_name = cursor.fetchall()
            if (database_name,) in all_database_name:
                print('数据库创建完成')
            cursor.execute(goto_database)

            # 2. 创建数据表
            cursor.execute(create_table_Classes_sql)
            cursor.execute(create_table_Students_sql)

            # 3. 插入数据
            insert_Class_sql = '''
                INSERT INTO 班级 (班名, 班导) VALUES (%s, %s),(%s, %s),(%s, %s)
            '''
            data_Class = ['日升班', '道光', '伏流班', '汪洋', '腾渊班', '菲杨']
            cursor.execute(insert_Class_sql, data_Class)

            insert_Students_sql = '''
                INSERT INTO 学生 (姓名, 性别,民族,班级) VALUES (%s, %s, %s, %s)
            '''
            name = ['赵匡胤', '钱镠', '孙悟空', '武曌', '曹雪芹', '杰瑞', '张三', '约翰·纳什', '武直-10']
            sex0 = ['男', '男', '男', '女', '男', '其他', '男', '男', '直升机']
            nati = ['汉', '汉', '汉', '汉', '满', '米奇', '汉', '维京', '中华民族']
            clas = [2, 3, 3, 2, 1, 1, 1, 2, 3]
            data = [[name[i], sex0[i], nati[i], clas[i]] for i in range(len(name))]
            cursor.executemany(insert_Students_sql, data)
            connection.commit()

            # 4. 删除数据
            delete_sql = 'DELETE FROM 学生 WHERE 姓名=%s;'
            cursor.execute(delete_sql, '杰瑞')
            connection.commit()

            # 5. 更新数据
            change_sql = 'UPDATE 学生 SET 性别 = %s,民族 = %s WHERE 姓名 = %s;'
            cursor.executemany(change_sql, (('其他', None, '孙悟空'),))
            connection.commit()

            # 6. 查询数据
            select_classes_sql = 'SELECT * FROM 班级'
            cursor.execute(select_classes_sql)
            classes = cursor.fetchall()
            print('班级有:')
            for class_info in classes:
                print(class_info)

            # 子查询跨表
            select_students_sql = '''
                SELECT * FROM 学生 
                WHERE 班级 in (SELECT 班号 FROM 班级 WHERE 班名 = %s);
            '''
            cursor.execute(select_students_sql, '腾渊班')
            students = cursor.fetchall()
            print('腾渊班的学生有:')
            for student_info in students:
                print(student_info)

            # JOIN联表查询
            select_students_sql = '''
                SELECT 学生.*
                FROM 学生 JOIN 班级 ON 学生.班级 = 班级.班号
                WHERE 班级.班名 = %s;
            '''
            cursor.execute(select_students_sql, '伏流班')
            students = cursor.fetchall()
            print('伏流班的学生有:')
            for student_info in students:
                print(student_info)

            # 7. 删除数据库
            if delete_database:
                cursor.execute(delete_database_sql)
                cursor.execute(show_sql)
                all_database_name = cursor.fetchall()
                if not (database_name,) in all_database_name:
                    print('数据库删除完成')
            else:
                print('未删除数据库')
        else:
            print(f"数据库 {database_name} 已存在,为防止误删,程序终止")
    connection.commit()
except pymysql.MySQLError as e:
    print(f"Error: {e}")
    connection.rollback() # 异常回滚事务
finally:
    connection.close()
    print('数据库链接已关闭')

二、常用 SQL 语句与基础概念

SQL 大小写不敏感;数据库、表、字段名是否区分大小写,由 MySQL 服务配置决定。 MySQL 语句末尾必须使用分号;,语句中空格、换行会被忽略。

2.1 SQL 语句四大分类

表格

分类 全称 作用
DDL 数据定义语言 创建、修改、删除数据库对象(库、表)
DML 数据操作语言 对表里的数据做增删改查
DCL 数据控制语言 用户权限管理
TCL 事务控制语言 事务提交、回滚管理

2.2 SQL 注释写法

复制代码
-- 单行注释(--后面必须加空格)
# 单行注释,不需要空格
/*
多行注释
可以跨行写内容
*/

2.3 DDL 数据定义语言

DDL 语句执行时会隐式提交事务 ,一旦执行无法回滚,操作务必谨慎。 表名、字段名如果和 mysql 关键字冲突,使用反引号 ````` 包裹。

数据库相关操作
复制代码
-- 创建数据库
CREATE DATABASE [IF NOT EXISTS] `数据库名` [CHARACTER SET 'utf8mb4'];

-- 删除数据库
DROP DATABASE [IF EXISTS] `数据库名`;

-- 查看所有数据库
SHOW DATABASES;

-- 切换使用的数据库
USE `数据库名`;

-- 查看当前所在数据库
SELECT DATABASE();
数据表相关操作
复制代码
-- 查询当前库所有表
SHOW TABLES;

-- 查看表结构
DESC `表名`;

-- 查看建表SQL
SHOW CREATE TABLE `表名`;

建表基础语法

复制代码
CREATE TABLE `表名` (
   字段名 类型 [约束] [COMMENT '注释'],
   字段名 类型 [约束] [COMMENT '注释']
);
MySQL 常用数据类型
  • 整型:BIGINT、INT、MEDIUMINT、SMALLINT、TINYINT,占用字节依次 8/4/3/2/1
  • 浮点数:FLOAT单精度、DOUBLE双精度
  • 定点数:DECIMAL(M,D),例如DECIMAL(3,2)总 3 位,保留 2 位小数,适合金额
  • 时间日期:DATE(YYYY-MM-DD)、TIME(HH:MM)、DATETIME、TIMESTAMP
  • 字符串
    • CHAR(n)固定长度,查询速度快,最大 255 字符,不足补空格
    • VARCHAR(n)可变长度,仅占用实际字符空间
    • TEXT长文本,不用指定最大长度
  • 枚举集合
    • ENUM单选,只能取预先定义好的其中一个值
    • SET多选,可以选取预定义多个值
表约束

表格

约束 说明
PRIMARY KEY 主键,唯一标识一行数据
UNIQUE 唯一约束,字段值不能重复
NOT NULL 非空约束,字段不允许为 NULL
DEFAULT 默认值,插入不填时自动填充默认值
FOREIGN KEY 外键约束,关联另一张表主键
CHECK 检查约束,限制字段取值规则
修改表结构
复制代码
-- 添加列
ALTER TABLE 表名 ADD 字段名 字段类型 [约束];

-- 删除列
ALTER TABLE 表名 DROP COLUMN 字段名;

-- 修改字段类型
ALTER TABLE 表名 MODIFY COLUMN 字段名 新类型 ;

-- 修改表名
ALTER TABLE 表名 RENAME TO 新表名;

2.4 DML 数据操作语言(增删改查)

复制代码
-- 新增数据
INSERT INTO 表名 [(字段1, 字段2)] VALUES (值1,值2),(值1,值2);

-- 删除数据,务必加WHERE条件!
DELETE FROM 表名 WHERE 条件;

-- 更新数据,不加WHERE会修改全表!
UPDATE 表名 SET 字段1=值,字段2=值 WHERE 条件;

-- 查询数据
SELECT 字段1,字段2 FROM 表名 WHERE 条件;
-- * 代表查询全部字段

2.5 DCL 权限控制语句

日常开发使用较少,用于管理数据库账号权限

复制代码
-- 授予权限
GRANT 权限1, 权限2 ON 表名 TO 用户名 [WITH GRANT OPTION];

-- 撤销权限
REVOKE 权限1, 权限2 ON 表名 FROM 用户名;

2.6 TCL 事务控制语言

事务:一组 SQL 操作作为一个原子单元,全部执行成功,或者全部回滚,保证数据一致性。 MySQL 默认每条 DML 语句自动作为独立事务提交。

复制代码
-- 开启事务
START TRANSACTION;
BEGIN TRANSACTION;

-- 提交事务,持久化修改
COMMIT;

-- 回滚,撤销本次事务内所有操作
ROLLBACK;

-- 设置保存点
SAVEPOINT 保存点名称;

三、pymysql 核心常用函数

1. 数据库连接

复制代码
connection = pymysql.connect(
    host='localhost',
    port=3306,
    user='root',
    password='xxx',
    database='testdb',
    charset='utf8mb4'
)
# 关闭连接
connection.close()

2. 事务操作

复制代码
connection.commit()   # 提交事务
connection.rollback() # 事务回滚

3. 游标 cursor(执行 SQL、读取结果)

复制代码
# 创建游标
cursor = connection.cursor()
# with语法自动关闭游标,推荐写法
with connection.cursor() as cursor:
    pass
cursor.close()

4. SQL 执行 & 获取结果集

表格

方法 功能
cursor.execute(sql, args) 执行单条 SQL,返回受影响行数
cursor.executemany(sql, args_list) 批量执行多条 SQL,适合批量插入
cursor.fetchone() 获取查询结果第一条数据
cursor.fetchmany(size) 获取指定 size 条结果
cursor.fetchall() 获取全部查询结果
cursor.rowcount 本次 execute 影响的数据行数

游标可以理解为结果集的指针,fetch 读取数据后,指针向后移动,重复 fetch 不会重复读到前面的数据。

四、小结

  1. DDL 操作库表结构,隐式提交,不能回滚;DML 操作表内数据,需要手动 commit/rollback 管理事务。
  2. 外键可以做表关联,支持级联更新 / 删除,开发中根据业务取舍。
  3. pymysql 中推荐with管理游标,异常捕获配合rollback防止脏数据。
  4. 查询不需要 commit;新增、修改、删除操作,必须 commit 才会真正写入数据库。
相关推荐
NineData2 小时前
MySQL 到 Doris 实时数据同步:订单、用户和日志数据入仓方案
数据库·mysql
Dovis(誓平步青云)3 小时前
现场问题先关闭还是先验收,建筑任务怎样处理依赖
前端·javascript·数据库·mysql·音视频
xuefuhe4 小时前
MySQL:group_replication_start_on_boot vs group_replication_bootstrap_group
mysql
for_ever_love__4 小时前
MySQL Online DDL 完全指南:INSTANT/INPLACE/COPY 三种算法、MDL 锁事故与 gh-ost 实战
数据库·mysql·ddl·online·gh-ost·锁表·加字段
for_ever_love__4 小时前
MySQL 子查询、派生表与 CTE 优化:半连接、物化和递归实战
数据库·mysql·优化·as·子查询·with·cte
鱼很腾apoc6 小时前
【MySQL】 第1期 从核心概念到表约束全解析
linux·c语言·数据库·学习·mysql
斯内普吖7 小时前
(开源)校园充电宝租借管理系统实战指南 基于 Java + SSM + Vue + MySQL
java·vue.js·mysql·开源
啵啵啵鱼8 小时前
对数据的增删改查
数据库·mysql·ai·idea·ai编程·navicat·obsidian
靠沿8 小时前
MySQL数据库基础——索引的使用&alter、explain关键字
java·数据库·mysql