MySQL:简单的增删改查
MySQL作为一款关系型数据库产品,其最基本的功能就是实现数据的存储、查看和管理。下面将介绍MySQL数据库中不同数据类型的查询、增加、修改和删除功能。
查询数据
基本语法介绍
在MySQL中,使用
SELECT
语句可以对数据表中的数据进行查询,它是最常用的查询语句。
该语句有字段名、查询表名两个必选项和查询条件、分组、排序、查询限制等其它可选项。
(通常情况下,我们把附加在主语句后面的条件语句称为子句)
下面列出语法(聚合函数、连接查询等将在后面几篇文章中介绍):
/*
语法如下:
SELECT [DISTINCT] <*|ALL|字段名>
FROM <表名>
[WHERE <主查询条件>] [GROUP BY <字段名>] [ORDER BY <字段名>] [HAVING <副查询条件>]
[LIMIT <行数|起始行,查询的行数>];
*/
语法解释:
*|ALL|字段名
---- 必选,指定查询哪个字段的数据,选择*
或ALL
查询全部字段。多个字段名之间用,
分隔。
表名
---- 必选,指定查询哪张表中的数据。
DISTINCT
---- 可选,对重复记录进行过滤。
WHERE
子句 ---- 可选,查询符合条件的记录。
GROUP BY
子句 ---- 可选,当使用聚合函数时,对结果按指定字段名进行分组。
ORDER BY
子句 ---- 可选,对结果按指定字段的顺序进行正序或倒序排序。
HAVING
子句 ---- 可选,对结果进行二次过滤。
LIMIT
子句 ---- 可选,限制结果的显示行数。
SELECT
语句的参数还不止这些,更为复杂的查询不在本篇文章的讨论范围之内。
打印任意值
值得一提的是,SELECT
语句的本质是在屏幕上打印内容,和其它编程语言的print
方法类似,如果你要使用SELECT
语句打印任意常量值,也是被允许的。比如:
SELECT 123456; // 打印数字
SELECT '嘎嘎——机械——嘎嘎'; // 打印任意字符串
查询表中全部数据
在MySQL中,查询一张表中的全部数据,只需要将查询的字段名改为*
(通配符,意为全部)即可。如果想过滤重复的记录,只需要在字段名参数前加上DISTINCT
选项即可。
/* 查询数据表中全部记录 */
USE `cpla_in_liyue`; // 使用数据库cpla_in_liyue
SELECT * FROM `army_region`; // 查询表army_region中的全部数据
SELECT DISTINCT * FROM `army_region`; // 查询表army_region中的全部数据,并过滤重复记录
如图,已经查出了数据表army_region
中的全部数据。
查询表中部分字段
跟上面的方法类似,查询表中部分字段的数据只需要将字段名改为自己需要的字段即可;同样地,如果需要过滤重复的记录,只需要在字段名参数前加上关键字 DISTINCT
即可。
在下面的例子中,我们只需要查询出千岩军各支队的编号和派驻地址,即以下三个字段:armyid
,region_L1
,region_L2
。
/* 查询千岩军支队编号和派驻地址 */
SELECT armyid,region_L1,region_L2 FROM `army_region`;
SELECT DISTINCT armyid,region_L1,region_L2 FROM `army_region`; // 过滤重复数据
如图,我们已经成功查出armyid
,region_L1
,region_L2
三个字段的数据。
限定条件查询
在MySQL中,我们还可以使用 WHERE
子句来从大量的记录中找出指定条件的记录。使用强大的WHERE
子句可以实现很多条件复杂的查询。WHERE
子句的条件需要使用各种运算符。(本节需要用到的有:=
等于,!=
不等于,<
小于)
条件的基本写法:字段名+运算符+指定的值
,用空格分隔。
例1:查询编号值小于指定值的记录
现在,我们需要查询支队编号小于10020的记录,则条件可以这样写:armyid < 10020
。
/* 查询编号值小于10020的记录 */
SELECT * FROM `army_region` WHERE armyid < 10020;
如图,我们已经成功查出支队编号小于10020的记录。
例2:查询地址不等于某值的记录
现在,我们需要查出表中的全部值,但需要过滤地址中为Permission Denied
(拒绝访问)的记录。本题条件可以这样写:region_L1 != 'Permission Denied'
。
/* 过滤地址值为拒绝访问的记录 */
SELECT * FROM `army_region` WHERE region_L1 != 'Permission Denied';
如图,我们已经成功过滤地址值为拒绝访问的记录。(表中id
值为6、9、17、22的记录地址值为Permission Denied
)
例3:查询一级地址等于某值的记录
本题中,我们需要查出千岩军部署在海外(须弥)的特遣部队。本题条件可以这样写:region_L1 = '须弥'
。
/* 查询地址值为海外的记录 */
SELECT * FROM `army_region` WHERE region_L1 = '须弥';
如图,我们已经查出地址值为须弥的记录。
例4:查询表中指定区间数据
在MySQL中,我们还可以通过LIMIT
子句查询指定区间的数据,例如查询前10行数据或者第15至第23行数据。下面通过几个小例子来讲解查询区间数据的方法。
小例子1:查询前10行数据
查询前10行数据的方法很简单,只需要将LIMIT
子句的行数值设置为10即可。
/* 查询表中前10行数据 */
SELECT * FROM `army_region` LIMIT 10;
小例子2:查询第15-23行数据
查询指定区间的数据也很简单,只需要向LIMIT
子句指定起始行和查询的行数即可。
注意:起始行不会被查询出来,因此起始行数要减1。
/* 查询表中第15-23行数据 */
SELECT * FROM `army_region` LIMIT 14,9; # 从15行开始,查询9条记录
小例子3:查询后10行数据
查询表中后10行数据需要和ORDER BY
子句配合,先使用ORDER BY
子句将结果集按id
列倒序排序,再使用LIMIT
子句限定输出行数。
/* 查询表中后10行数据 */
SELECT * FROM `army_region` ORDER BY id DESC LIMIT 10;
插入数据
在MySQL中,可以使用
INSERT
语句向数据表中插入一条记录。
INSERT
语句有三种格式:INSERT INTO ... VALUES
,INSERT INTO ... SET
,INSERT INTO ... SELECT
。其中INSERT INTO ... SET
语句的作用和INSERT INTO ... VALUES
基本相同,故不予介绍。
INSERT INTO ... VALUES
语句主要的作用是插入数据,而INSERT INTO ... SELECT
语句的作用是从另一个查询结果集中复制数据。
基本语法
下面列出INSERT
语句的基本语法:
/*
语法如下:
插入数据 -- INSERT INTO [PRIORITY_LEVEL] <表名>[(字段名)] VALUES(数值) [ON DUPLICATE KEY UPDATE 字段名=表达式];
复制数据 -- INSERT INTO [PRIORITY_LEVEL] <表名>[(字段名)] <SELECT语句> [ON DUPLICATE KEY UPDATE 字段名=表达式];
*/
语法解释:
表名
---- 必选,指定要插入数据的数据表。
VALUES(...)
---- 插入数据必选,设置要插入到数据表中的值。
SELECT语句
---- 复制数据必选,设置要复制到数据表中的结果集。
(字段名)
---- 可选,指定向表中哪些字段插入数据,若不指定则按先后顺序插入一条完整记录,若非空字段未指定则用默认值填充,无默认值则报错。
PRIORITY_LEVEL
---- 可选,设置语句执行的优先级。稍后介绍其作用和参数。
ON DUPLICATE KEY UPDATE
---- 可选,设置当主键索引或唯一索引重复时的操作。
PRIORITY_LEVEL参数
在实际的生产环境中(比如网站),一张数据表大概率会被大量用户访问,难免会有很多操作冲突。若不对这些用户操作进行管理,数据的完整性将被破坏,这时候就需要一种机制来保证查询的顺序进而保护数据。修饰符PRIORITY_LEVEL
正是其中之一。
PRIORITY_LEVEL
可以调整 INSERT
、UPDATE
、DELETE
三种语句的优先级,它有以下三种参数可选:
LOW_PRIORITY
:低优先级,适用于INSERT
、UPDATE
和DELETE
语句。DELAYED
:延迟优先级,仅适用于INSERT
语句,当目标数据表被占用时,新数据会被保存至缓冲区中,等待目标数据表占用被释放时再进行插入。HIGH_PRIORITY
:高优先级,适用于INSERT
和SELECT
语句。
ON DUPLICATE KEY UPDATE子句
通常情况下,用户输入的数据是不可靠的,如果完全信任用户输入的参数,那势必会造成一些问题。假如用户提供的参数和主键索引或者唯一索引相冲突(重复),那MySQL就会报错。而ON DUPLICATE KEY UPDATE
子句会检查表中有没有重复的记录,如果有则更新值,反之执行插入。
该子句的常用语法如下:
/*
语法如下:
ON DUPLICATE KEY UPDATE <字段1>=<新值1>,...,<字段N>=<新值N>;
*/
INSERT INTO `army_region` VALUES(8,10009,'层岩巨渊','璃月-须弥中部边境')
ON DUPLICATE KEY UPDATE
region_L1 = VALUES(region_L1),
region_L2 = VALUES(region_L2);
# 因为表中已经有了id值为8的记录,新插入值和主键重复,所以更新该重复行的值
注:该子句判断重复行的优先级顺序:主键索引有重复>唯一索引有重复。
对比图:
插入完整的数据
在MySQL中,可以使用 INSERT INTO ... VALUES
语句向指定数据表中插入一条完整的数据。插入的数据数量一定要和字段数量相匹配,如果VALUES()
中的数据不齐全,那么MySQL会报出如下错误:
下面演示向数据表中插入一条完整的数据:
1.首先查看表结构:
2.然后根据表结构来插入数据:
/* 向数据表中插入单条完整数据 */
INSERT INTO `army_region` VALUES(29,10030,'珉林','天遒谷');
3.插入成功。
插入多条完整数据
在MySQL中,还可以在一条语句中批量插入多条完整的数据,其语法和插入单条数据相似,只需要在多个记录数据值之间加上,
进行分隔即可。下面介绍具体的操作方法:
/* 插入三条完整数据 */
# INSERT INTO `<表名>` VALUES(<数据值1>),(<数据值2>),(<数据值3>);
INSERT INTO `army_region` VALUES
(30,10031,'珉林','华光林'),
(31,10032,'珉林','琥牢山'),
(32,10033,'璃沙郊','灵矩关');
如图,成功插入三条数据。
向指定字段插入数据
在MySQL中,还可以只向指定的字段插入数据,未指定的字段值将使用默认值或者NULL
代替,但如果有未指定的字段没有默认值,INSERT
语句的执行将会失败。同样地,这里也可以通过使用,
分隔的方法插入多条记录值。下面介绍具体的操作方法:
/* 向指定字段插入数据 */
# INSERT INTO `<表名>`(字段1,字段2,字段3) VALUES(值1,值2,值3),(值1,值2,值3);
INSERT INTO `army_region`(armyid,region_L1,region_L2) VALUES
(10034,'璃沙郊','黑岩厂军管区'),
(10035,'云来海','龙脊雪山快速航道-璃月段'),
(10036,'碧水原','璃月-枫丹航道')
ON DUPLICATE KEY UPDATE
armyid = VALUES(armyid),
region_L1 = VALUES(region_L1),
region_L2 = VALUES(region_L2);
如图,成功插入三条新记录。
将查询结果集插入数据表
在MySQL中,我们可以使用 INSERT INTO ... SELECT
语句将一个SELECT
语句返回的查询结果集的全部或部分数据插入到数据表中。下面介绍具体的操作方法:
1.先查看表结构(或者创建一张新复制表):
/* 在复制结果集前先查看表结构 */
USE `cpla_in_liyue`; # 选择数据库
SHOW TABLES; # 查看数据库中的所有表
DESCRIBE `region_dirtbl`; # 查看表region_dirtbl的结构
/* 在复制结果集前创建新表 */
CREATE TABLE IF NOT EXISTS `region_bak` LIKE `region_dirtbl`; # 根据自己的需要创建表
2.再预先执行SELECT
语句,确定其是否可插入:
/* 校对结果集是否可插入 */
SELECT * FROM `region_dirtbl` LIMIT 10; # 查看结果集
DESCRIBE `region_dirtbl`; # 查看目标表结构
3.执行插入语句:
/* 将结果集插入至数据表中 */
INSERT INTO `region_bak` SELECT * FROM `region_dirtbl`;
4.插入成功。
注:和其它
INSERT
语句语法相同,INSERT INTO ... SELECT
语句也支持向指定字段复制。
更新数据
在MySQL中,如果想对现有的数据值进行更改,可以使用
UPDATE
语句来实现。
基本语法
UPDATE
语句的语法比较简单,下面进行列出:
/*
语法如下:
UPDATE [PRIORITY_LEVEL] [IGNORE] `<表名>` SET
<字段1> = <值1>,
<字段2> = <值2>
[WHERE <限定条件>] [ORDER BY <字段名>] [LIMIT <行数值>]
*/
语法解释:
表名
---- 必选,指定要进行操作的数据表。
字段 = 值
---- 必选,指定将目标字段的数据更新至某个值。
WHERE
子句 ---- 建议选择,更新符合条件要求的记录。
PRIORITY_LEVEL
---- 可选,优先级修饰符,只有LOW_PRIORITY
可选,意为多用户环境下延迟执行本操作。
IGNORE
---- 可选,如果本条语句执行出现错误,则忽略错误继续执行剩余的操作。
ORDER BY
子句 ---- 可选,指定进行更新操作的顺序,可和LIMIT
子句配合使用。
LIMIT
子句 ----可选,限制执行操作的行数,可和ORDER BY
子句配合使用。
如果使用UPDATE
语句,最好指定条件,否则UPDATE
语句会直接更新所选字段的全部数据。
指定条件更新
在MySQL中,使用UPDATE
语句配合WHERE
条件可以修改表中某一条记录的数据。下面通过举例说明:
例题:修改
region_dirtbl
表中的记录,将明蕴镇地区的区域负责单位改为辉山厅。
1.查看表结构
对一张表进行操作时,首先需要知道这张表的用途。用户可以通过如下语句查看表结构:
/* 查看region_dirtbl表的结构 */
DESCRIBE `region_dirtbl`; # 查看表的基本结构、索引、属性等
SHOW FULL COLMUNS FROM `region_dirtbl`; # 在上条语句的基础上查看更多的信息(字符集、权限、注释)
从以上运行结果中(注释信息)可以看出表中各字段的职能。
2.查看表中数据,确定修改内容
我们可以通过SELECT
语句查看表中数据,来更直观地确定各个字段的职能和要修改的信息。
/* 在更新前预先查看region_dirtbl表中的部分数据 */
SELECT * FROM `region_dirtbl` LIMIT 10;
3.使用UPDATE语句更新
根据查看到的信息,更新语句可以这样写:
/* 更新region_dirtbl表中的指定数据 */
UPDATE `region_dirtbl` SET regionDir = '辉山厅' WHERE region_L2 = '明蕴镇';
4.更新成功
指定区间更新
在MySQL中,用户还可以使用 ORDER BY
子句和LIMIT
子句配合UPDATE
进行指定区间的更新,例如将表的后10行更新为指定的值等等。此方法的详细解释可以跳转至本文关于查询指定区间数据的知识讲解进行详细学习。
例题:修改表中后10行数据
/* 修改region_bak表中后10行数据 */
UPDATE `region_bak` SET regionDir = 'undefind' ORDER BY id DESC LIMIT 10;
特别注意:在
UPDATE
语句中使用LIMIT
子句时只能有一个参数!
更新字段中全部数据
当使用UPDATE
语句不指定条件时,会将指定字段中全部数据更新成一个指定的值。这通常会造成灾难性的后果并造成公司巨额财产损失,因此执行此类操作需谨慎。吃好点,过两天就能接到叔叔的电话了,里面没啥好吃的┐(´∇`)┌
/* 更新region_bak表中指定字段的全部数据 */
UPDATE `region_bak` SET region_L1 = '我是深渊教团',region_L2 = '你部队已被消灭',regionDir = '速开城门';
删除数据
在MySQL中,可使用
DELETE
语句删除表中符合条件的记录。
基本语法
DELETE
语句的语法较为简单,下面进行列出:
/*
语法如下:
DELETE [PRIORITY_LEVEL][QUICK][IGNORE] FROM `<表名>`
[WHERE <条件表达式>] [ORDER BY <列名> [ASC|DESC]] [LIMIT <行数>];
*/
语法解释:
表名
---- 必选,不再重复陈述。
WHERE
子句 ---- 建议必选,指定条件表达式,未指定则删除表中所有数据。
ORDER BY
子句 ---- 可选,对字段进行排序,ASC
为升序,DESC
为降序,可和LIMIT
子句配合使用。
LIMIT
子句 ---- 可选,限定执行操作的行数,可和LIMIT
子句配合使用。
PRIORITY_LEVEL
---- 可选,指定本操作的优先级,删除语句只有LOW_PRIORITY
可选。
QUICK
---- 可选,加快删除进度。
IGNORE
---- 可选,执行并忽略本操作中的所有错误。
指定条件删除
使用WHERE
子句可精准删除符合条件的记录,下面演示删除region_bak
数据表中id
值为6的记录:
/* 删除region_bak表中id值为6的记录 */
DELETE FROM `region_bak` WHERE id = 6;
如图,id
值为6的记录已经消失。
指定区间删除
像其它语句一样,DELETE
语句也可以配合ORDER BY
子句和LIMIT
子句进行指定区间记录的删除。注意:和UPDATE
语句一样,删除语句的LIMIT
子句也只能有一个数值。
下面演示删除region_bak
表中后12行的记录:
/* 删除region_bak表中后12行记录 */
DELETE FROM `region_bak` ORDER BY id DESC LIMIT 12;
如图,表中后12行记录已经被删除。
删除全部记录(清空数据表)
在MySQL中,使用DELETE
语句且不加条件时会清空指定数据表的全部记录。清空数据表时除了使用DELETE
语句,还可以使用 TRUNCATE TABLE
语句。下面列出两者之间的不同之处:
- 使用
TRUNCATE TABLE
语句清空表时直接释放物理存储(DDL
操作),而DELETE
会产生大量事务日志,容易造成死锁(DML
操作)。 TRUNCATE TABLE
语句会重置AUTO_INCREMENT
计数器,而DELETE
语句不会。TRUNCATE TABLE
语句不能删除视图和被外键引用的表 。
注:在清空数据表时,建议使用
TRUNCATE TABLE
语句以避免死锁和大量系统资源占用。有关如何使用TRUNCATE TABLE
语句清空数据表,请跳转至超详细的MySQL入门教程(三)- 清空表中数据
/* 清空region_bak表中的全部记录 */
DELETE FROM `region_bak`;
如图,表region_bak
中的所有记录已经被清空。