MySQL:简单库表管理
一些基本概念
想要学习MySQL的库表管理,了解一些基本概念是必不可少的。下面将介绍一些MySQL中一些重要的术语。
表
MySQL中最常见的数据库对象,是一张表格(相当于Excel的表),里面存放着各种数据。
字段
MySQL中最基本的数据存储单位,许多字段构成一张表,字段本身的类型决定了字段中应该存储哪些数据。字段实现了对数据的分类。MySQL中有五种主要数据类型:数字类型、字符串类型、地理空间类型、JSON类型和日期时间类型。
约束
约束是一种对数据内容进行限制,以保证数据的正确性、完整性和有效性的一套业务检查机制,不同的数据库实现这种机制的方法也不同。
在MySQL中有以下九种约束:主键约束、唯一性约束、检查约束、非空约束、自增长约束、零填充约束、无符号约束、外键约束、默认约束。下面介绍它们的具体作用:
- 主键约束
PRIMARY KEY
:将一个字段设置为主键。(MySQL允许一张表有多个主键) - 唯一性约束
UNIQUE
:限制该列不能有重复数据。 - 检查约束
CHECK
:限制该列数据必须符合某个表达式定义的条件。(如人数小于等于5000,numOfPol <= 5000
) - 非空约束
NOT NULL
:限制该列数据不能为NULL值(即空值) - 自增长约束
AUTO_INCREMENT
:设置某列数据随着行数增长自动增加1。自增长列是不为NULL且唯一的列。(仅用于整数类型列) - 零填充约束
ZEROFILL
:设置当某列数据实际长度小于定义长度时自动在前面补0。(仅用于数字类型列) - 无符号约束
UNSIGNED
:限制某列数据为非负数。(仅用于数字类型列) - 外键约束
FOREIGN KEY
:将本表(子表)中的某列数据与外表(父表)中的某列数据建立关联。 - 默认约束
DEFAULT
:为某列数据指定默认值。
建立外键约束的条件:
1.父表和子表必须为InnoDB存储引擎。
2.父表列和子表列必须创建索引。(父表一般为主键索引,子表一般为唯一索引)
3.子表的外键必须和父表的主键数据类型相对应。(最好相同)
索引
索引是一种数据结构,用于对数据的存储进行优化,以便于在海量数据中快速查找到指定的数据。索引一般存储在磁盘上单独的文件中,包含对数据表中所有记录的引用。
马萨卡?你问我引用是啥?请你自行去学习一下C++吧!因为MySQL是用C++写的。( • ̀ω•́ )✧
在MySQL中,索引类型一般有四种:普通索引、唯一索引、空间索引、全文索引,索引方法有两种:BTREE(B+树)和HASH(哈希)。
- 普通索引
INDEX
:MySQL最基本的索引类型,没有限制条件。 - 唯一索引
UNIQUE
:设置该索引后列中的每个值必须是唯一的。 - 空间索引
SPATIAL
:地理空间类型专用的索引。 - 全文索引
FULLTEXT
:只能在数据类型为CHAR
、VARCHAR
和TEXT
的列上建立。当要查询的内容较大时,使用全文索引可以提高查询速度。
视图
视图是MySQL中的虚拟表(逻辑表),其本质是存放在数据库中的
SELECT
语句(视图的定义),视图本身并不存放数据,当基表被删除时,视图也会被删除。合理地使用视图并管理权限可以只让指定用户看到自己指定的数据。用户也可以从视图创建视图或表。
视图具有如下特性:
- 简单性:视图是已经经过条件过滤的结果集,看到的就是需要的。
- 安全性:视图可以阻止用户查看自己没有权限查看的信息。(只需要在表中增加一列查询权限等级或其它可以区分用户的信息,再创建视图并授权给其它用户)
- 数据独立性:利用视图的屏蔽特性可以使数据库和应用程序独立,即修改数据表结构可以不影响视图(有时要对视图做一些小小的修改),从而不影响应用程序。
基表和视图在以下情况下会相互影响:
1.当整个基表或基表的某一列被删除,视图会失效。
2.在基表(或视图)中修改记录的具体内容,视图(或基表)中对应的内容也会被修改。
3.对基表的列进行更名时,视图中的列名也会变化,但DBA可以通过修改视图定义来使列名保持不变。
向基表中增加列并不会影响视图。
存储过程
存储过程是一组MySQL语句的集合,用户可以直接调用存储过程来执行已经定义好的存储过程。存储过程相当于其它编程语言中的函数。
触发器
触发器的定义:触发器是一种特殊的存储过程,它在试图更改触发器所保护的数据时自动执行。
简单地说,触发器就相当于一种机关一样,当其它用户向触发器(机关)所保护的表中写入内容时(条件是使用INSERT
、UPDATE
、DELETE
语句),触发器会执行一系列由管理员预定义好的语句来起到保护作用。
事务
事务的定义:事务是指一组相互依赖的操作单元(DML语句)的集合,用于保证对数据库的正确修改和数据完整性。如果事务中的某个操作单元失败,那么这次事务的全部操作会被撤销。事务操作在被提交前存放于缓冲池中。目前只有InnoDB存储引擎支持事务。
事务必须符合ACID特性:
- A,原子性(Atomicity):每次事务都是一个不可分割的整体。(即只有所有操作单元都成功,事务才会被提交)
- C,一致性(Consistency):事务执行完毕后,关系数据的完整性与业务逻辑的一致性不能被改变。
- I,隔离性(Isolation):在并发环境中,多个事务操作不能相互冲突。(即一个事务不能使用另一个事务正在使用的数据)
- D,持久性(Durability):事务结束后,所做的修改永久保存。
简单的数据库管理
下面介绍如何对MySQL数据库进行创建、查看、修改、删除等操作。
查看并选择数据库
登录数据库后,你可以使用以下语句来查看(或筛选)MySQL实例中到底有哪些数据库:
/*
语法如下:
SHOW DATABASES [LIKE '正则条件'];
*/
SHOW DATABASES; // 查看所有数据库
SHOW DATABASES LIKE '%s%'; // 筛选名称中有字母s的数据库
语法解释:
LIKE
---- 可选,用于指定正则查询条件,%
表示不占位,_
表示占位。
在发现需要用的数据库时,需要使用以下语句使用数据库,才能将查询操作定向到这个数据库中:
/*
语法如下:
USE <数据库名>;
*/
USE cpla_in_liyue;
这样所有的操作都将在名为cpla_in_liyue
的数据库中执行。
查看数据库创建语句
在MySQL中用户可以通过如下语句查看数据库详细信息:
SHOW CREATE DATABASE `test_db`;
创建数据库
用户可以通过如下语句创建一个数据库:
/*
语法如下:
CREATE DATABASE [IF NOT EXISTS] <数据库名> [CHARACTER SET=<字符集名>] [COLLATE = <字符校验规则名>];
*/
CREATE DATABASE `test_db`; // 第一种方法
CREATE DATABASE IF NOT EXISTS `test_db` CHARACTER SET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci; // 第二种方法
语法解释:
IF NOT EXISTS
---- 条件判断语句,意为“如果不存在”。
CHARACTER SET
---- 指定字符集名称,默认为utf8
。
COLLATE
---- 指定字符校验规则,默认utf8_general_ci
。
需要注意的是,数据库名称一旦指定就无法修改,想要修改只能删掉数据库重新创建。
如果按照第一种方法创建数据库,但是数据库重名,MySQL就会报出如下错误:
mysql> create database `test_db`;
ERROR 1007 (HY000): Can't create database 'test_db'; database exists
修改数据库
数据库一经创建,就无法修改名称,所以用户只能使用 ALTER DATABASE
语句修改字符集和字符校对规则。
/*
语法如下:
ALTER DATABASE [数据库名] [DEFAULT CHARACTER SET=<字符集名>] [DEFAULT COLLATE=<字符校对规则名>]
*/
ALTER DATABASE `test_db` DEFAULT CHARACTER SET=utf8mb4 DEFAULT COLLATE=utf8mb4_0900_ai_ci; // 方法一
ALTER DATABASE DEFAULT CHARACTER SET=utf8mb4 DEFAULT COLLATE=utf8mb4_0900_ai_ci; // 方法二(不推荐)
语法解释:
数据库名
---- 可选,未指定的情况下选择当前数据库,建议选择。
DEFAULT CHARACTER SET
---- 可选,设置该数据库默认字符集。
DEFAULT COLLATE
---- 可选,设置该数据库默认字符校对规则。
如果用户未指定数据库(没写),则MySQL会选择当前数据库,但假如用户没有使用USE
语句指定数据库,则MySQL会报出如下错误:
mysql> alter database default character set=utf8mb4 default collate=utf8mb4_0900_ai_ci;
ERROR 1046 (3D000): No database selected
删除数据库
在MySQL中,用户可以通过DROP DATABASE
语句来删除一个或多个、甚至全部数据库。因此在执行这条语句时一定要小心再小心。如果你操作的是公司数据库,那么叔叔会请你去局里喝茶(σ-`д・´)
/*
语法如下:
DROP DATABASE [IF EXISTS] <数据库名|*>;
*/
DROP DATABASE `test_db`; // 删除数据库“test_db”
DROP DATABASE IF EXISTS `test_db`; // 如果数据库“test_db”存在,则删除该数据库
DROP DATABASE *; // 刑啊,很刑啊,张三逝吧(删除全部数据库)
语法解释:
IF EXISTS
---- 可选,条件判断语句,意为“如果存在”。
数据库名
---- 必选(二选一),指定要删除的数据库名称。
*
---- 必选(二选一),通配符,意为“全部”。一种能吃五年以上铁饭碗的操作
简单的数据表管理
下面介绍对数据库中的数据表进行简单的查看、创建、修改、删除等操作。
查看数据表
在MySQL中,用户可以通过如下语句查看当前数据库中包含的数据表信息(需要先使用USE
语句选择数据库):
USE `cpla_in_liyue`;
SHOW TABLES;
在MySQL中,使用如下的两种方法查看数据库表结构:
/*
语法如下:
- DESCRIBE <数据表名>;
- SHOW COLUMNS FROM <数据表名>;
*/
DESCRIBE `army_region`; // 第一种方法
SHOW COLUMNS FROM `army_region`; // 第二种方法
不管使用哪种方法,返回的结果都一样:
下面对返回信息的类别作一些解释说明:
- Field:字段的名称。
- Type:字段的数据类型。
- Null:字段中的值是否允许为NULL。
- Key:字段设置的索引类型,空白为未设置。
- Default:字段的默认值,
(NULL)
为未设置。 - Extra:显示其它附加属性,比如
AUTO_INCREMENT
。
查看数据表结构信息
在MySQL中,我们可以通过如下语句查看数据表的结构和索引信息:
DESCRIBE `student_score`; // 查看数据表结构
SHOW INDEX FROM `student_score`; // 查看数据表中的索引
创建数据表
在MySQL中,可以使用 CREATE TABLE
语句创建一张数据表,基本语法如下:
/*
语法如下:
CREATE TABLE [IF NOT EXISTS] <数据表名>(
<字段1> <数据类型>(定义长度) [附加属性],
<字段2> <数据类型>(定义长度) [附加属性],
<字段3> <数据类型>(定义长度) [附加属性],
[其它约束]
)[ENGINE=<存储引擎>][DEFAULT CHARSET=<字符集名>];
*/
语法解释:
IF NOT EXISTS
---- 条件选择语句,意为“如果不存在”。
数据类型
---- 按需求从MySQL的数据类型中选择一种。
定义长度
---- 指定数据的长度,如255个字符的字符串、5位长的整数等。地理空间类型、自动递增列和JSON类型不需要指定长度。
附加属性
---- 为字段添加一些约束。稍后将列出一些常用的附加属性。
其它约束
---- 设置一些约束,如:主键约束、外键约束、检查约束等。
ENGINE
---- 设置表使用的存储引擎,默认InnoDB。
DEFAULT CHARSET
---- 设置表使用的字符集。
或者你也可以通过如下语句创建一张表的备份:
CREATE TABLE IF NOT EXISTS `new_table_name` LIKE `old_table_name`; // 仅复制一张表的结构
CREATE TABLE IF NOT EXISTS `new_table_name` AS SELECT * FROM `old_table_name` // 复制一张表的全部数据
在创建数据表时,我们通常会为字段设置一些约束,以让字段中的数据符合某种格式的要求,使数据更具有完整性、规范性和合理性。关于常见的约束列表,请跳转至本文基础概念章节中关于约束的介绍。
下面通过具体的例子来讲解创建数据表的基本语法:
假设我们要创建一张学生成绩数据表,表中有如下字段:
1.id,序号;
2.name,学生的名字;
3.score,成绩;
4.isPass,错题过关了吗;
5.crdate,创建日期;
分析一下:
id
列为序号,应该是表的主键,且应该为正整数、自增长列,数值上应该是唯一、非空的。一个班的学生不会太多,故应该采用INT
数据类型和唯一、非空、无符号、自增长约束、设置检查约束:人数小于等于50。name
列为学生名字,在班里学生没有同名的情况下,该列应该被设置为唯一非空的。(不指定默认值,因为该项是必须的)所以使用:VARCHAR
数据类型(最大50个字符)、唯一约束、非空约束。score
列为学生成绩,正常情况下学生成绩应该是非负数,且小数位数只有一位,最大不超过100。因此该列使用DECIMAL
数据类型(有效数字4位,小数位数1位)、无符号约束、非空约束(必须,不指定默认值)、检查约束:分数小于等于100。isPass
存放布尔值。在MySQL中,布尔值用0(True)
和1(False)
表示,所以布尔值类型的字段写为TINYINT(1)
。故采用:TINYINT
数据类型(1位数字)、无符号约束、非空约束、默认约束(默认肯定是订正没过关,指定1
)、检查约束:数值仅为0
或1
,CHECK(isPass IN (0,1))
。crdate
为记录创建时间,不可缺少,默认为当前时间。故采用:TIMESTAMP
时间戳数据类型,非空约束,默认约束:当前时间NOW()
。
代码如下:
CREATE TABLE IF NOT EXISTS `student_score`(
`id` INT UNSIGNED UNIQUE AUTO_INCREMENT NOT NULL, // 无符号、唯一、自增、非空
`name` VARCHAR(50) UNIQUE NOT NULL, // 唯一、非空
`score` DECIMAL(4,1) UNSIGNED NOT NULL, // 无符号、非空
`isPass` TINYINT(1) UNSIGNED NOT NULL DEFAULT 1, // 布尔值,无符号、非空、默认False
`crdate` TIMESTAMP NOT NULL DEFAULT NOW(), // 时间戳,非空、默认值当前时间
PRIMARY KEY(`id`), // 设置主键为"id"
CHECK(score <= 100.0), // 检查约束,分数小于等于100.0
CHECK(isPass IN (0,1)) // 检查约束,布尔值为0或1
)ENGINE=INNODB DEFAULT CHARSET=utf8mb4; // 设置存储引擎为InnoDB,默认字符集utf8mb4
下面对约束是否生效进行验证:
1.查看表结构:
一切正常。
2.尝试插入分数值大于100.0:
不符合约束,报错。
3.尝试插入数字7到isPass中
不符合约束,报错。由此可见,约束全部生效。
修改数据表
在MySQL中,创建数据表后,如果需要对数据表的结构进行修改,可使用 ALTER TABLE
语句新建字段和约束、修改字段定义、删除字段、重命名字段等诸多操作。下面介绍ALTER TABLE
语句的基本操作:
1.新建字段、索引和约束
新建字段
向一张表中增加一个字段的语法如下(假设要为表student_score
增加一个stuNumber
学号字段):
/*
语法如下:
ALTER TABLE `<数据表名>` ADD <字段名> <字段定义>;
*/
ALTER TABLE `student_score` ADD stuNumber INT(8); // 8位INT,无附加索引和约束
新建索引
虽然为学生成绩表student_score
增加了学号字段stuNumber
,但它还是无法满足我们的要求:没有增加索引,会被写入各种垃圾信息。现在要为其增加唯一索引,以确保每位学生的学号都是不同的。
/*
语法如下:
ALTER TABLE `<数据表名>` ADD <索引类型> <索引名称>(<作用字段>);
*/
ALTER TABLE `student_score` ADD UNIQUE stuNumber_UN_INDEX(stuNumber); // 添加名为“stuNumber_UNINDEX”,作用列为“stuNumber”的唯一索引
语法解释:
索引类型
---- 必选,有INDEX
、UNIQUE
、FULLTEXT
、SPATIAL
四种类型可选。具体请跳转至本文基础概念章节中关于索引的介绍。
索引名称
---- 必选,需要为新建的索引指定一个名称,通常为字段名+下划线+索引类型
。
作用字段
---- 必选,需要指定索引作用于表中的哪个字段。
现在我们尝试添加两条学号相同的记录:
添加失败。
新建约束
在MySQL中,可以使用ALTER TABLE
语句新建一个约束,但只能创建主键约束、唯一约束、外键约束、和检查约束四种约束;其它诸如无符号、0填充之类的约束只能通过MODIFY
参数更改表定义来添加了。
现在我们要为学号字段stuNumber
添加检查约束,规定学号必须大于数值9999999
,下面列出语法:
/*
语法如下:
ALTER TABLE `<数据表名>` ADD CONSTRAINT <约束名称> <约束类型> <具体的约束定义>;
*/
ALTER TABLE `stuNumber` ADD CONSTRAINT stuNumber_CK_COTRN CHECK(stuNumber > 9999999); // 添加检查约束,限制学号数值必须大于9999999
语法解释:
约束名称
---- 必选,为约束指定一个名称。
约束类型
---- 必选,从PRIMARY KEY
、UNIQUE
、FOREIGN KEY
、和CHECK
中选择一个。
具体的约束定义
---- 必选,每种约束都有自己的语法定义。
下面我们尝试添加一条学号小于9999999
的记录:
失败了。
创建其它类型约束的语法和示例如下:
/*
语法如下:
1.主键约束 ALTER TABLE `<数据表名>` ADD CONSTRAINT <约束名称> PRIMARY KEY (作用字段);
2.唯一约束 ALTER TABLE `<数据表名>` ADD CONSTRAINT <约束名称> UNIQUE (作用字段);
3.外键约束 ALTER TABLE `<数据表名>` ADD CONSTRAINT <约束名称> FOREIGN KEY(<子表字段名>) REFERENCES <父表名>(<父表字段名>);
*/
ALTER TABLE `student_score` ADD CONSTRAINT stuNumber_PR_COTRN PRIMARY KEY(stuNumber); // 设置stuNumber为主键
ALTER TABLE `student_score` ADD CONSTRAINT stuNumber_UN_COTRN UNIQUE(stuNumber); // 设置stuNumber的每个值都唯一
ALTER TABLE `student_score` ADD CONSTRAINT stuNumber_FR_COTRN FOREIGN KEY(stuNumber) REFERENCES student_info(studentID); // 设置student_score.stuNumber与student_info.studentID关联
2.修改和重命名
修改字段定义
在MySQL中,可以使用ALTER TABLE
语句配合 MODIFY
选项,就可以修改字段的定义,包括字段数据类型、定义长度和约束等等。下面列出语法:
/*
语法如下:
ALTER TABLE `<数据表名>` MODIFY <字段名> <新字段定义>;
*/
ALTER TABLE `student_score` MODIFY stuNumber INT(8) ZEROFILL UNSIGNED UNIQUE NOT NULL; // 修改已命名的字段的定义
修改后的表定义如下:
注意:
MODIFY
选项只能修改字段定义,并不能重命名字段。
重命名字段
在MySQL中,我们可以通过ALTER TABLE
语句配合 CHANGE
选项来进行对字段的重命名和重新定义操作。下面列出语法:
/*
语法如下:
ALTER TABLE `<数据表名>` CHANGE <原字段名> <新字段名> <新字段定义>;
*/
ALTER TABLE `student_score` CHANGE stuNumber stuSerNum INT(8) ZEROFILL UNSIGNED UNIQUE NOT NULL; // 重命名字段并修改定义
重命名字段后的表定义:
修改字段默认值
在MySQL中,使用ALTER TABLE
语句配合 ALTER
选项可以专门修改字段的默认值。语法如下:
/*
语法如下:
ALTER TABLE `<数据表名>` ALTER <字段名> SET DEFAULT <默认值>; -- 添加默认值
ALTER TABLE `<数据表名>` ALTER <字段名> DROP DEFAULT; -- 删除默认值
*/
ALTER TABLE `student_score` ALTER stuSerNum SET DEFAULT 00000000; // 为字段stuSerNum添加默认值00000000
ALTER TABLE `student_score` ALTER stuSerNum DROP DEFAULT; // 删除字段stuSerNum的默认值
添加默认值后的表定义如下:
注意:
ALTER TABLE ... ALTER
只能修改字段的默认值。
重命名表
在MySQL中,用户可以有两种方法对数据表进行重命名,分别是 ALTER TABLE
语句配合RENAME AS
选项 和 RENAME TABLE
语句。下面列出它们的语法:
/*
语法如下:
1. ALTER TABLE <原数据表名> RENAME AS <新数据表名>;
2. RENAME TABLE <原数据表名> TO <新数据表名>;
*/
ALTER TABLE `student_score` RENAME AS `student_newScore`;
RENAME TABLE `student_score` TO `student_newScore`;
删除操作
1.删除索引
在MySQL中,可以通过 DROP INDEX
语句对索引进行删除。对索引进行删除的语法如下(假设要删除字段name
的唯一索引):
/*
语法如下:
DROP INDEX <索引名> ON `<数据表名>`;
*/
SHOW CREATE TABLE `student_score`; // 先找出索引名
DROP INDEX name ON `student_score`; // 删除唯一索引
删除索引后的表结构:
2.删除约束
在MySQL中,可以使用ALTER TABLE
语句配合 DROP
语句来删除约束,语法如下:
(以要删除检查约束为例,约束名可以通过SHOW CREATE TABLE
语句查看表结构获得)
/*
语法如下:
1. ALTER TABLE `<数据表名>` DROP PRIMARY KEY; -- 删除主键
2. ALTER TABLE `<数据表名>` DROP CONSTRAINT <约束名> -- 删除检查约束、唯一约束
3. ALTER TABLE `<数据表名>` DROP FOREIGN KEY <外键名> -- 删除外键约束
*/
ALTER TABLE `student_score` DROP CONSTRAINT student_score_chk_1; // 删除名为“student_score_chk_1”的检查约束
删除前表中的检查约束:
执行删除约束语句:
删除成功:
用户可以根据自己的情况选择PRIMARY KEY
、CONSTRAINT
和FOREIGN KEY
三种参数中的一种。
注意:使用
PRIMARY KEY
参数会对表中所有主键进行删除,但无法删除一个自动增长列的主键约束。因此,如果要删除一个自动增长列的主键约束,需要先使用ALTER TABLE ... MODIFY
语句将自动增长属性撤销。
3.删除字段
在MySQL中,用户可以使用 ALTER TABLE ... DROP COLUMN
语句删除表中的某一字段,语法如下(假设要删除新建的字段classNumber
):
/*
语法如下:
ALTER TABLE `<数据表名>` DROP COLUMN <字段名>;
*/
ALTER TABLE `student_score` DROP COLUMN className;
删除前:
执行删除语句:
删除后:
4.清空表中数据
在MySQL中,可以通过 TRUNCATE
语句清空整张表的数据,但表结构本身会保留。
/*
语法如下:
TRUNCATE TABLE `<要清空的表>`
*/
TRUNCATE TABLE `student_score`;
原表数据:
执行清空语句:
mysql> TRUNCATE TABLE `student_score`;
Query OK, 0 rows affected (0.02 sec)
清空后:
5.删除整张表
在MySQL中,可以使用 DROP TABLE
指定要删除的数据表,同样地,乱用这条语句可能也会被叔叔请去喝茶 。
/*
语法如下:
DROP TABLE [IF EXISTS] `<要删除的表名>`; // IF EXISTS是什么意思应该不用解释了
*/
DROP TABLE `student_score`; // 删除表“student_score”
DROP TABLE *; // 听说叔叔对你很感兴趣?(删除库中全部数据表)
删除前数据库中的表:
执行删除语句:
mysql> DROP TABLE IF EXISTS `student_score`;
Query OK, 0 rows affected (0.00 sec)
删除后: