MySQL高级语法

视图

作用:将查询语句封装成一张可视化的表,封装的是动态SQL语句,会根据数据表的数据而更新

创建视图

  • 语法:create view 视图名 as 查询语句;

(1)准备数据

复制代码
MariaDB [db1]> create table ping (
    -> id int primary key,
    -> name varchar(20)
    -> );
Query OK, 0 rows affected (0.008 sec)

MariaDB [db1]> insert into ping values(1,'sunyingsha'),(2,'ch;enmeng'),(3,'wangmanyu');
Query OK, 3 rows affected (0.003 sec)
Records: 3  Duplicates: 0  Warnings: 0

MariaDB [db1]> select * from ping;
+----+------------+
| id | name       |
+----+------------+
|  1 | sunyingsha |
|  2 | ch;enmeng  |
|  3 | wangmanyu  |
+----+------------+
3 rows in set (0.001 sec)

(2)创建视图

复制代码
MariaDB [db1]> create view get_ping as select * from ping order by id desc;
Query OK, 0 rows affected (0.003 sec)

查看视图

复制代码
MariaDB [db1]> show tables;
+---------------+
| Tables_in_db1 |
+---------------+
| get_ping      |
| ping          |
| xinxi         |
+---------------+
3 rows in set (0.000 sec)

查看视图结果

复制代码
MariaDB [db1]> select * from get_ping;
+----+------------+
| id | name       |
+----+------------+
|  3 | wangmanyu  |
|  2 | ch;enmeng  |
|  1 | sunyingsha |
+----+------------+
3 rows in set (0.001 sec)

查看视图创建语句

复制代码
MariaDB [db1]> show create view get_ping;
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| View     | Create View                                                                                                                                                                            | character_set_client | collation_connection |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
| get_ping | CREATE ALGORITHM=UNDEFINED DEFINER=`root`@`localhost` SQL SECURITY DEFINER VIEW `get_ping` AS select `ping`.`id` AS `id`,`ping`.`name` AS `name` from `ping` order by `ping`.`id` desc | utf8                 | utf8_general_ci      |
+----------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+
1 row in set (0.001 sec)

修改视图

复制代码
MariaDB [db1]> alter view get_ping as select id from ping;
Query OK, 0 rows affected (0.003 sec)

MariaDB [db1]> select * from get_ping;
+----+
| id |
+----+
|  1 |
|  2 |
|  3 |
+----+
3 rows in set (0.001 sec)

删除视图

复制代码
MariaDB [db1]> drop view get_ping;
Query OK, 0 rows affected (0.000 sec)

多表关联

  • 语法:select * from 主表名 inner|left|right join 副表名 on 主表.字段=副表.字段;
  • inner join:两边都有记录
  • left join:以主表记录为主
  • right join:以副表记录为主
  • 查询过程中的执行顺序:from>where>group(包含聚合函数,如min、max、avg等)>having>order>select外键

调用函数

  • count:统计
  • distinct:去重
  • avg:获取平均值
  • min/max:最小值/最大值
  • sum:求和
  • year/month/day:获取年/月/日的部分

准备两张数据表

复制代码
mysql> create database db2;
mysql> use db2
mysql> create table xinxi(
id int auto_increment,
name varchar(20) not null,
sex int(1) not null default 0,
birth datetime,
primary key(id)
);
mysql> alter table xinxi add unique key(name);
mysql> insert into xinxi(name,sex,birth) values('xiaozhan',0,'1990-1-1'),
('luhan',0,'1990-4-20'),('liying',1,'1988-1-1'),('baby',1,'1989-1-1');
mysql> create table paihangbang(
id int not null,
score int,
rank int,
name varchar(20)
);
mysql> insert into paihangbang values(1,100,1,'xiaozhan'),(2,98,2,'luhan'),
(3,97,3,'tangyan'),(4,96,4,'liying');

连接两张数据表

复制代码
MariaDB [db2]> select * from xinxi inner join paihangbang on
    -> xinxi.name=paihangbang.name;
+----+----------+-----+---------------------+----+-------+------+----------+
| id | name     | sex | birth               | id | score | rank | name     |
+----+----------+-----+---------------------+----+-------+------+----------+
|  1 | xiaozhan |   0 | 1990-01-01 00:00:00 |  1 |   100 |    1 | xiaozhan |
|  2 | luhan    |   0 | 1990-04-20 00:00:00 |  2 |    98 |    2 | luhan    |
|  3 | liying   |   1 | 1988-01-01 00:00:00 |  4 |    96 |    4 | liying   |
+----+----------+-----+---------------------+----+-------+------+----------+
3 rows in set (0.001 sec)

MariaDB [db2]> select * from xinxi left join paihangbang on xinxi.name=paihangbang.name;
+----+----------+-----+---------------------+------+-------+------+----------+
| id | name     | sex | birth               | id   | score | rank | name     |
+----+----------+-----+---------------------+------+-------+------+----------+
|  1 | xiaozhan |   0 | 1990-01-01 00:00:00 |    1 |   100 |    1 | xiaozhan |
|  2 | luhan    |   0 | 1990-04-20 00:00:00 |    2 |    98 |    2 | luhan    |
|  3 | liying   |   1 | 1988-01-01 00:00:00 |    4 |    96 |    4 | liying   |
|  4 | baby     |   1 | 1989-01-01 00:00:00 | NULL |  NULL | NULL | NULL     |
+----+----------+-----+---------------------+------+-------+------+----------+
4 rows in set (0.001 sec)

MariaDB [db2]> select * from xinxi right join paihangbang on
    -> xinxi.name=paihangbang.name;
+------+----------+------+---------------------+----+-------+------+----------+
| id   | name     | sex  | birth               | id | score | rank | name     |
+------+----------+------+---------------------+----+-------+------+----------+
|    1 | xiaozhan |    0 | 1990-01-01 00:00:00 |  1 |   100 |    1 | xiaozhan |
|    2 | luhan    |    0 | 1990-04-20 00:00:00 |  2 |    98 |    2 | luhan    |
| NULL | NULL     | NULL | NULL                |  3 |    97 |    3 | tangyan  |
|    3 | liying   |    1 | 1988-01-01 00:00:00 |  4 |    96 |    4 | liying   |
+------+----------+------+---------------------+----+-------+------+----------+
4 rows in set (0.000 sec)

多表联查

准备数据

复制代码
#创建数据库:mysql_test
mysql> drop database if exists mysql_test;
mysql> create database mysql_test;
mysql> use mysql_test;
#创建学生表:student
mysql> create table student (
s_id int,
s_name varchar(8),
s_birth date,
s_sex varchar(4)
) default charset utf8;
#插入数据
mysql> insert into student values
(1,'赵雷','1990-01-01','男'),(2,'钱电','1990-12-21','男'),(3,'孙风','1990-05-20','男'),
(4,'李云','1990-08-06','男'),(5,'周梅','1991-12-01','女'),(6,'吴兰','1992-03-01','女'),
(7,'郑竹','1989-07-01','女'),(8,'王菊','1990-01-20','女');
#创建课程表:course
mysql> create table course (
c_id int,
c_name varchar(8),
t_id int
)default charset utf8;
#插入数据
mysql> insert into course values(1,'语文',2),(2,'数学',1),(3,'英语',3);
#创建成绩表score
mysql> create table score (
s_id int,
c_id int,
s_score int
)default charset utf8;
#插入数据
mysql> insert into score values(1,1,80),(1,2,90),(1,3,99),(2,1,70),(2,2,60),
(2,3,65),(3,1,80),(3,2,80),(3,3,80),(4,1,50),(4,2,30),(4,3,40),(5,1,76),
(5,2,87),(6,1,31),(6,3,34),(7,2,89),(7,3,98);

查询需求

(1)查询"李"姓学生的数量

复制代码
MariaDB [mysql_test]> select count(*) as cnt_name_li from student where s_name like '李%';
+-------------+
| cnt_name_li |
+-------------+
|           1 |
+-------------+
1 row in set (0.001 sec)

(2)查询"01"课程的学生的信息及课程分数

复制代码
MariaDB [mysql_test]> select s.*,score.s_score from student s inner join score on s.s_id = score.s_id;
+------+--------+------------+-------+---------+
| s_id | s_name | s_birth    | s_sex | s_score |
+------+--------+------------+-------+---------+
|    1 | 赵雷   | 1990-01-01 | 男    |      80 |
|    1 | 赵雷   | 1990-01-01 | 男    |      90 |
|    1 | 赵雷   | 1990-01-01 | 男    |      99 |
|    2 | 钱电   | 1990-12-21 | 男    |      70 |
|    2 | 钱电   | 1990-12-21 | 男    |      60 |
|    2 | 钱电   | 1990-12-21 | 男    |      65 |
|    3 | 孙风   | 1990-05-20 | 男    |      80 |
|    3 | 孙风   | 1990-05-20 | 男    |      80 |
|    3 | 孙风   | 1990-05-20 | 男    |      80 |
|    4 | 李云   | 1990-08-06 | 男    |      50 |
|    4 | 李云   | 1990-08-06 | 男    |      30 |
|    4 | 李云   | 1990-08-06 | 男    |      40 |
|    5 | 周梅   | 1991-12-01 | 女    |      76 |
|    5 | 周梅   | 1991-12-01 | 女    |      87 |
|    6 | 吴兰   | 1992-03-01 | 女    |      31 |
|    6 | 吴兰   | 1992-03-01 | 女    |      34 |
|    7 | 郑竹   | 1989-07-01 | 女    |      89 |
|    7 | 郑竹   | 1989-07-01 | 女    |      98 |
+------+--------+------------+-------+---------+
18 rows in set (0.001 sec)

(3)查询"01"课程比"02"课程成绩高的学生的信息及课程分数

复制代码
MariaDB [mysql_test]> select s.*,sc1.s_score as score_01,sc2.s_score as score_02
    -> from student s
    -> inner join (
    -> select * from score where c_id = 1
    -> ) sc1
    -> on s.s_id = sc1.s_id
    -> inner join (
    -> select * from score where c_id = 2
    -> ) sc2
    -> on s.s_id = sc2.s_id
    -> where sc1.s_score > sc2.s_score;
+------+--------+------------+-------+----------+----------+
| s_id | s_name | s_birth    | s_sex | score_01 | score_02 |
+------+--------+------------+-------+----------+----------+
|    2 | 钱电   | 1990-12-21 | 男    |       70 |       60 |
|    4 | 李云   | 1990-08-06 | 男    |       50 |       30 |
+------+--------+------------+-------+----------+----------+
2 rows in set (0.002 sec)

支持中文

方法一:建表时支持中文

复制代码
MariaDB [db2]> create table tzhong(
    -> id int,
    -> name varchar(20),
    -> sex int)DEFAULT CHARSET=utf8 collate=utf8_general_ci;
Query OK, 0 rows affected (0.008 sec)

测试:

复制代码
MariaDB [db2]> insert into tzhong values(1,'哈哈哈',0);
Query OK, 1 row affected (0.001 sec)

MariaDB [db2]> select * from tzhong;
+------+-----------+------+
| id   | name      | sex  |
+------+-----------+------+
|    1 | 哈哈哈    |    0 |
+------+-----------+------+
1 row in set (0.001 sec)

方法二:建库时支持中文

复制代码
MariaDB [db2]> create database db10 DEFAULT CHARSET=utf8 collate=utf8_general_ci;
Query OK, 1 row affected (0.001 sec)

测试:

复制代码
MariaDB [db10]> create table tzhong(
    -> id int,
    -> name varchar(20),
    -> sex int);
Query OK, 0 rows affected (0.006 sec)

MariaDB [db10]> show create table tzhong;
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table  | Create Table                                                                                                                                                                      |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tzhong | CREATE TABLE `tzhong` (
  `id` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  `sex` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_general_ci |
+--------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.001 sec)

方法三:修改服务配置文件

复制代码
[root@localhost ~]# vim /etc/my.cnf.d/mariadb-server.cnf 
[mysqld]

character-set-server=utf8

重启服务,测试:

复制代码
MariaDB [(none)]> create database 新库;
Query OK, 1 row affected (0.001 sec)

MariaDB [(none)]> show databases;
+--------------------+
| Database           |
+--------------------+
| db1                |
| db10               |
| db2                |
| information_schema |
| mysql              |
| performance_schema |
| 新库               |
+--------------------+
7 rows in set (0.001 sec)

表间约束:外键

特点

  • 外键约束,参照完整性,用来在两个表的数据之间建立连接;
  • 一张表可以设置多个外键,一个外键可以加载单列或多列上;
  • 外键是表中的一个字段、不一定是本表的主键,但需要对应另一个表的唯一键;
  • 关联的两张表的字段类型、字符集需要相同;

语法

  • ALTER TABLE <数据表名> ADD CONSTRAINT <索引名> FOREIGN KEY(<列名>) REFERENCES <主表名> (<列名>);

创建外键

复制代码
MariaDB [db2]> alter table paihangbang add constraint fk_name foreign key(name) references xinxi(name);
Query OK, 3 rows affected (0.018 sec)              
Records: 3  Duplicates: 0  Warnings: 0
  • constraint:级联关系
  • 想删除主表的字段,需要把该字段上关联的外键先删除
  • 想添加从表的字段,需要在主表的数据范围里面

注:如果paihangbang表中的数据不在xinxi这张表的范围内,则外键会创建失败

查看外键

复制代码
MariaDB [db2]> show create table paihangbang;
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table       | Create Table                                                                                                                                                                                                                                                                                                               |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| paihangbang | CREATE TABLE `paihangbang` (
  `id` int(11) NOT NULL,
  `score` int(11) DEFAULT NULL,
  `rank` int(11) DEFAULT NULL,
  `name` varchar(20) DEFAULT NULL,
  KEY `fk_name` (`name`),
  CONSTRAINT `fk_name` FOREIGN KEY (`name`) REFERENCES `xinxi` (`name`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1 COLLATE=latin1_swedish_ci |
+-------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.000 sec)

删除外键

  • 语法:ALTER TABLE <表名> DROP FOREIGN KEY <外键约束名>; #删约束

  • 语法:drop index 约束名 on 表名; #删外键索引

    #删除级联
    MariaDB [db2]> alter table paihangbang drop foreign key fk_name;
    Query OK, 0 rows affected (0.003 sec)
    Records: 0 Duplicates: 0 Warnings: 0
    #再删索引
    MariaDB [db2]> drop index fk_name on paihangbang;
    Query OK, 0 rows affected (0.004 sec)
    Records: 0 Duplicates: 0 Warnings: 0

存储过程

  • 存储过程(stored procedure):是将一组SQL语句作为一个整体来执行的数据库对象,通过被调用来运行;
  • 和函数一样,是一条或多条SQL语句的集合,区别函数是已经定义好的、存储过程是用户自己定义的;

调用函数

复制代码
MariaDB [db2]> select * from paihangbang;
+----+-------+------+----------+
| id | score | rank | name     |
+----+-------+------+----------+
|  1 |   100 |    1 | xiaozhan |
|  2 |    98 |    2 | luhan    |
|  4 |    96 |    4 | liying   |
+----+-------+------+----------+
3 rows in set (0.000 sec)
#调用sum函数求和
MariaDB [db2]> select sum(score) as 总分 from paihangbang;
+--------+
| 总分   |
+--------+
|    294 |
+--------+
1 row in set (0.001 sec)
#调用avg函数求平均值
MariaDB [db2]> select avg(score) as 总分 from paihangbang;
+---------+
| 总分    |
+---------+
| 98.0000 |
+---------+
1 row in set (0.001 sec)

MariaDB [mysql_test]> select s_id from score;
+------+
| s_id |
+------+
|    1 |
|    1 |
|    1 |
|    2 |
|    2 |
|    2 |
|    3 |
|    3 |
|    3 |
|    4 |
|    4 |
|    4 |
|    5 |
|    5 |
|    6 |
|    6 |
|    7 |
|    7 |
+------+
18 rows in set (0.000 sec)
#查询结果去重------distinct
MariaDB [mysql_test]> select distinct s_id from score;
+------+
| s_id |
+------+
|    1 |
|    2 |
|    3 |
|    4 |
|    5 |
|    6 |
|    7 |
+------+
7 rows in set (0.000 sec)

定义存储过程

复制代码
mysql> create procedure delete_data()
#存储过程开始
begin
    #要执行的语句1
    delete from paihangbang where id=2; -对,执行
    #要执行的语句2
    delete from xinxi2 where id=2; -若错,终止
    #存储过程结束
end

注:语句之间单独执行,除非加事务

调用存储过程

  • mysql> call delete_data;

支持事务ACDI

过程:开启事务------操作------成功:commit提交事务|失败:rollback回滚

  • A:原子性,事务里的语句要么全部执行、要么全部不执行
  • C:一致性,事务运行时不改变数据库中的数据
  • I:隔离性,指两个以上事务间独立运行、互不干扰
  • D:持久性,事务运行完对文件影响是持久的、不会随意回滚

定义带事务的存储过程

复制代码
mysql> CREATE PROCEDURE delete_data_with_rollback()
#存储过程开始
begin
    #定义错误变量t_error,默认值为0
    declare t_error int;
    #定义检查到语句错误,将t_error的值改为1
    declare continue handler for sqlexception set t_error=1;
    #开启事务
    start transaction;
        #先删paihangbang数据
        delete from paihangbang;
        #再删xinxi数据,故意写错了表名(xinxi - xinxix)
        delete from xinxi;
        #使用if结构,若t_error的值是1则rollback,否则commit
        #rollback或commit都会结束事务
        if t_error =1 then
            rollback;
        else
            commit;
        end if;
    #存储过程结束
    end

注:运行上述步骤之后,表中的数据并不会消失,因为事务还没有真正执行并提交

复制代码
#执行事务
MariaDB [db2]> call delete_data_with_rollback;
Query OK, 6 rows affected (0.002 sec)

MariaDB [db2]> select * from xinxi;
Empty set (0.001 sec)
#表中数据被清除

查看存储过程

  • mysql> show create procedure delete_data;

    #查看所有存储过程
    MariaDB [db2]> show procedure status;
    +-------+---------------------------+-----------+-----------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
    | Db | Name | Type | Definer | Modified | Created | Security_type | Comment | character_set_client | collation_connection | Database Collation |
    +-------+---------------------------+-----------+-----------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
    | db2 | delete_data_with_rollback | PROCEDURE | lisi@% | 2025-09-19 18:13:06 | 2025-09-19 18:13:06 | DEFINER | | utf8 | utf8_general_ci | latin1_swedish_ci |
    | mysql | AddGeometryColumn | PROCEDURE | mariadb.sys@localhost | 2025-09-16 21:09:14 | 2025-09-16 21:09:14 | INVOKER | | utf8 | utf8_general_ci | latin1_swedish_ci |
    | mysql | DropGeometryColumn | PROCEDURE | mariadb.sys@localhost | 2025-09-16 21:09:14 | 2025-09-16 21:09:14 | INVOKER | | utf8 | utf8_general_ci | latin1_swedish_ci |
    +-------+---------------------------+-----------+-----------------------+---------------------+---------------------+---------------+---------+----------------------+----------------------+--------------------+
    3 rows in set (0.002 sec)

    #查看存储过程内容
    MariaDB [db2]> show create procedure delete_data_with_rollback;
    +---------------------------+-------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
    | Procedure | sql_mode | Create Procedure | character_set_client | collation_connection | Database Collation |
    +---------------------------+-------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
    | delete_data_with_rollback | STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION | CREATE DEFINER=lisi@% PROCEDURE delete_data_with_rollback()
    begin
    declare t_error int;
    declare continue handler for sqlexception set t_error=1;
    start transaction;
    delete from paihangbang;
    delete from xinxix;
    if t_error =1 then
    rollback;
    else
    commit;
    end if;
    end | utf8 | utf8_general_ci | latin1_swedish_ci |
    +---------------------------+-------------------------------------------------------------------------------------------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+----------------------+----------------------+--------------------+
    1 row in set (0.001 sec)

删除存储过程

  • mysql> drop procedure delete_data;

    MariaDB [db2]> drop procedure delete_data_with_rollback;
    Query OK, 0 rows affected (0.003 sec)

    MariaDB [db2]> drop procedure delete_data_with_rollback;
    ERROR 1305 (42000): PROCEDURE db2.delete_data_with_rollback does not exist

事务的隔离级别

  1. READ_UNCOMMITTED(读未提交)------读脏数据
  2. READ_COMMITTED(读已提交)------不可重复读
  3. REPEATABLE_READ(可重复读,MySQL默认)
  4. SERIALIZABLE(串行读)

查看mysql的隔离级别

  • mysql> show variables like 'tx_isolation';

  • 或:

  • mysql> select @@tx_isolation;

    MariaDB [db2]> show variables like 'tx_isolation';
    +---------------+-----------------+
    | Variable_name | Value |
    +---------------+-----------------+
    | tx_isolation | REPEATABLE-READ |
    +---------------+-----------------+
    1 row in set (0.001 sec)

修改默认存储引擎

复制代码
vim /etc/my.cnf.d/mariadb-server.cnf

[mysqld]
default-storage-engine=INNODB

systemctl restart mariadb
相关推荐
IvorySQL3 小时前
直播预告| PostgreSQL 与 IvorySQL 在云原生时代的演进与实践
数据库·postgresql·ivorysql
LeicyII3 小时前
6.MySQL索引的数据结构【面试题】
数据结构·数据库·mysql
大筒木老辈子4 小时前
MySQL笔记---数据库基础
数据库·笔记·mysql
Yan-英杰4 小时前
Amazon SES + NestJS 实战:零成本打造高送达率邮箱验证方案
java·服务器·前端·网络·数据库·ai
深蓝电商API4 小时前
爬虫数据存储:MongoDB 在电商采集中的应用
数据库·爬虫·mongodb
弹简特4 小时前
【MySQL初阶】04-数据表的操作
数据库·mysql
一个天蝎座 白勺 程序猿4 小时前
Apache IoTDB(6):深入解析数据库管理操作——增删改查与异构数据库实战指南
数据库·apache·时序数据库·数据库管理·iotdb
十八旬4 小时前
苍穹外卖项目实战(day11-1)-记录实战教程、问题的解决方法以及完整代码
服务器·数据库·windows·redis
浅拾光º4 小时前
mysql重启,服务器计划重启,如何优雅地停止MySQL?
服务器·mysql·adb