SQL(Structured Query Language),被称为结构化查询语言,是目前主流的关系型数据库上执行数据操作、数据检索以及数据库维护所需要的标准语言。它将数据查询、数据操纵、事务控制、数据定义和数据控制集于一身。不分大小写,习惯上,关键字用大写,表名列命用小写。
MySQL数据库服务器的交互实质,都是通过结构化查询语言来实现的,所以SQL是各类数据库交互方式的基础。
SQL是机构化查询语言(Structured Query Language)的英文首字母,专门用来与数据库通信的语言。SQL由很多关键字组成。SQL具有以下优点:
MySQL数据库所支持的SQL语言包含:数据库定义语言(DDL)、数据库操纵语言(DML)、数据库控制语言(DCL)。
主要用于对数据库的对象进行创建、删除、修改等操作。数据库对象包括:表、默认约束、规则、试图、触发器、存储过程等。主要SQL语句为:
主要对数据库对象的数据进行查询、增加、删除、修改等操作。主要SQL语句为:
用于安全管理,例如显示数据库登录用户权限。主要SQL语句为:
主要包括一些常用的常量、变量、运算符、表达式、函数、流程控制和注解等。
(1)常量
在程序运行过程中值不变的量。
MySQL提供的内置函数,可以帮助用户更加方便的处理表的数据。
根据一组数据求出一个值。聚合函数的结果只对非NULL的值进行计算,NULL则被忽略,以下面数据为例,介绍几个常用的聚合函数。
mysql> select * from tb_student;
+------------+--------------+------+----------+
| student_no | student_name | age | class_no |
+------------+--------------+------+----------+
| 1 | 张三 | 17 | 001 |
| 2 | 李四 | 18 | 001 |
| 3 | 王五 | 17 | 001 |
| 4 | 小六 | 19 | 002 |
+------------+--------------+------+----------+
4 rows in set (0.02 sec)
(1)COUNT()函数:查询表中所有行数。
mysql> select count(*) from tb_student;
+----------+
| count(*) |
+----------+
| 4 |
+----------+
1 row in set (0.00 sec)
(2)SUM()函数:计算某个字段的总和。
mysql> select sum(age) from tb_student;
+----------+
| sum(age) |
+----------+
| 71 |
+----------+
1 row in set (0.00 sec)
(3)AVG()函数:计算某个字段平均值。
mysql> select avg(age) from tb_student;
+----------+
| avg(age) |
+----------+
| 17.7500 |
+----------+
1 row in set (0.00 sec)
(4)MAX()函数:找到某个字段的最大值。
mysql> select max(age) from tb_student;
+----------+
| max(age) |
+----------+
| 19 |
+----------+
1 row in set (0.00 sec)
(5)MIN()函数:找到某个字段的最小值。
mysql> select min(age) from tb_student;
+----------+
| min(age) |
+----------+
| 17 |
+----------+
1 row in set (0.00 sec)
主要用于处理数字类型。
(1)ABS()函数:计算某个字段的绝对值。
mysql> select abs(1),abs(-1);
+--------+---------+
| abs(1) | abs(-1) |
+--------+---------+
| 1 | 1 |
+--------+---------+
1 row in set (0.00 sec)
(2)FLOOR()函数:返回小于或等于参数的最大整数。
mysql> select floor(1.5),floor(-2);
+------------+-----------+
| floor(1.5) | floor(-2) |
+------------+-----------+
| 1 | -2 |
+------------+-----------+
1 row in set (0.00 sec)
(3)RAND()函数:返回0-1之间的随机数
mysql> select rand(),rand();
+--------------------+--------------------+
| rand() | rand() |
+--------------------+--------------------+
| 0.8018397919850795 | 0.6479518717601447 |
+--------------------+--------------------+
1 row in set (0.00 sec)
(4)TRUNCATE()函数:保留小数点后几位值。
mysql> select truncate(1.23242,3);
+---------------------+
| truncate(1.23242,3) |
+---------------------+
| 1.232 |
+---------------------+
1 row in set (0.00 sec)
主要处理字符串类型。
(1)UPPER()和UCASE()函数:将字母转化为大写或小写。
mysql> select upper('abc'),ucase('ABC');
+--------------+--------------+
| upper('abc') | ucase('ABC') |
+--------------+--------------+
| ABC | ABC |
+--------------+--------------+
1 row in set (0.00 sec)
(2)LEFT()函数:返回字符串前n个字符。
mysql> select left('ABC',2);
+---------------+
| left('ABC',2) |
+---------------+
| AB |
+---------------+
1 row in set (0.00 sec)
(3)SUBSTRING()函数:截取n到m长度的字符。
mysql> select substring('ABC',1,2);
+----------------------+
| substring('ABC',1,2) |
+----------------------+
| AB |
+----------------------+
1 row in set (0.00 sec)
(1)CURDATE()函数:返回当前日期。
mysql> select curdate();
+------------+
| curdate() |
+------------+
| 2021-09-10 |
+------------+
1 row in set (0.00 sec)
(2)CURTIME()函数:返回当前时间。
mysql> select curtime();
+-----------+
| curtime() |
+-----------+
| 23:40:52 |
+-----------+
1 row in set (0.00 sec)
(3)NOW()函数:返回当前时间和日期。
mysql> select now();
+---------------------+
| now() |
+---------------------+
| 2021-09-10 23:40:59 |
+---------------------+
1 row in set (0.00 sec)
除了上述介绍的,还有很多函数,例如条件判断函数等。
(1)IF()函数:判断表达式是否成立,返回对应结果。
mysql> select if(1>2,'大于','小于');
+-----------------------+
| if(1>2,'大于','小于') |
+-----------------------+
| 小于 |
+-----------------------+
1 row in set (0.00 sec)
(2)IFNULL()函数:判断数据是否为空(NULL)。
mysql> select ifnull(null,'空');
+-------------------+
| ifnull(null,'空') |
+-------------------+
| 空 |
+-------------------+
1 row in set (0.00 sec)
数据库可以看作是一个专门存储数据对象的容器,下面主要讲解使用SQL语句创建和操作数据库和表。
安装好MySQL(自行百度安装MySQL)后,就可以开始创建和使用数据库了,涉及数据库的创建、选择、查看、修改和删除操纵。
创建数据库是在系统磁盘上划分一块区域用于数据存储和管理,MySQL创建数据库的基本语法格式是:
CREATE {
DATABASE | SCHEMA} [IF NOT EXISTS] 数据库名
[[DEFAULT] CHARACTER SET [=] 字符集名]
[[DEFAULT] COLLATE [=] 校对规则];
语法说明:
例子:在MySQL中创建一个db_class的数据库:
CREATE DATABASE IF NOT EXISTS db_class
DEFAULT CHARACTER SET GB2312
DEFAULT COLLATE GB2312_chinese_ci;
执行结果如下所示:
mysql> CREATE DATABASE IF NOT EXISTS school
-> DEFAULT CHARACTER SET GB2312
-> DEFAULT COLLATE GB2312_chinese_ci;
Query OK, 1 row affected (0.01 sec)
或者最简单的创建方式
CREATE DATABASE IF NOT EXISTS db_class;
用户创建数据库需要获得相对应的权限,上述命令执行成功后会在MySQL的data目录下创建一个与数据库名称相同的文件夹。
在实际开发过程用会有多个数据库的情况,下面介绍如何快速的查看和选择数据库。
语法格式:
SHOW {
DATABASES | SCHEMAS};
执行结果如下所示:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| school |
+--------------------+
7 rows in set (0.00 sec)
可以看到,数据库不仅仅有我们创建的数据库,还包含系统自动创建的数据库,各个数据库的作用如下表所示。
数据库名称 | 数据库作用 |
---|---|
mysql | 配置用户访问权限 |
information_schema | 保存MySQL服务器所维护的其他数据库信息,如数据库名、数据库的表、表的数据类型与访问权限等 |
performance_schema | 收集数据库服务器性能参数 |
school | 自定义数据库,用于学校系统管理 |
通过命令查看有哪些数据库了,可以通过命令跳转到指定数据库,才可以对数据库及表、数据进行各种操作。语法格式:
USE 数据库名;
执行结果如下所示:
mysql> use school;
Database changed
MySQL数据库的默认字符集为 latin1,默认校对规则为 latin1_swedish_ci,可以使用对应的语法对其修改。
ALTER {
DATABASE | SCHEMA} 数据库名
[DEFAULT] CHARACTER SET [=] 字符集
[DEFAULT] COLLATE [=] 校对规则;
比如现在修改school数据库的字符集,执行结果如下所示:
mysql> alter database school
-> default character set =gb2312
-> default collate gb2312_chinese_ci;
Query OK, 1 row affected (0.00 sec)
删除数据库就是将创建好的数据库文件从磁盘上清除同时数据也会删除。语法格式:
DROP {
DATABASE | SCHEMA} [IF EXISTS] 数据库名;
比如现在将school数据库删除,执行结果如下所示:
mysql> drop database school;
Query OK, 1 row affected (0.03 sec)
使用show databases;查看数据库,已经没有school的数据库了,如下所示:
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mysql |
| performance_schema |
| sys |
+--------------------+
4 rows in set (0.00 sec)
切忌误删系统自带的数据库,否则将不能正常运行。
数据库创建成功后,就可以在数据库中创建表了。表是数据库中最重要、最基本的数据对象,若没有表,数据库其他的数据对象就没有意义。表是按照行和列的格式来存储的,每一行代表一个记录,每一列代表记录的一个字段取值。创建表的过程就是定义每个字段的过程,也是实施数据完整性约束的过程。
数据类型是指系统中所允许数据存储的类型。例如存放金额的字段应该用数值型,存放文本、人名等信息应该用字符型等。创建表时必须为表的每个字段指定正确的数据类型及可能的数据长度。数据类型不仅可以对数据进行排序,对优化方面也有重要作用。
MySQL常用的数据类型有数值类型、日期和时间、字符串类型,下面介绍常用的几种类型。
数值类型 | 范围(有符号) | 范围(无符号) | 备注 |
---|---|---|---|
BIT | 1~64 | 1~64 | 位字段类型,默认长度为1 |
TINYINT | -128~127 | 0~255 | 很小的整数 |
BOOL、BOOLEAN | - | - | 等同于TINYINT(1)。true为真,false为假 |
INT、INTEGER | -2147483648~2147483647 | 0~4294967295 | 普通大小的整数 |
DOUBLE | -1.7976931348623157E+308-2.2250738585072014E-308),0,(2.2250738585072014E-3081.7976931348623157E+308 | 0~(2.2250738585072014E-308,1.7976931348623157E+308) | 双精度浮点数值 |
DECIMAL | - | - | 小数值,DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 |
数值类型 | 范围 | 备注 |
---|---|---|
DATE | 1000-01-01~9999-12-31 | 日期型,格式为“YYYY-MM-DD” |
TIME | -838:59:59~838:59:59 | 时间型,格式为“HH:mm:ss” |
DATETIME | 1000-01-01 00:00:00~9999-12-31 23:59:59 | 日期时间型,格式为“YYYY-MM-DD HH:mm:ss” |
YEAR | 两位格式 :70~69表示1970 ~2069,四位格式:1901 ~ 2155 | 年,2位或3位,格式为“YYYY-MM-DD” |
TIMESTAMP | 1970-01-01 00:00:00~2037 | 时间戳,时间的秒数 |
数值类型 | 范围 | 备注 |
---|---|---|
CHAR | 0~255 | 固定长度的字符类型,不满足长度字符用空格代替 |
VARCHAR | 0~65535 | 可变长度字符,存放多少字符就是多少字符 |
TINYTEXT | 255(2^8-1) | 短文本数据 |
TEXT | 65535(2^16-1) | 长文本数据 |
创建表使用 CREATE TABLE
语句,其基本语法格式为:
CREATE TABLE 表名(
字段名 数据类型 [列级完整性约束条件] [默认值],
... ...
)ENGINE = 引擎类型;
在已有school数据库中创建tb_student,并使用InnoDB引擎存储数据。如下所示:
mysql> create table tb_student(
-> student_no int not null primary key auto_increment,
-> student_name varchar(20) not null,
-> age int not null,
-> class_no varchar(10) default null
-> )engine=Innodb;
Query OK, 0 rows affected (0.02 sec)
下面对上述语句进行说明:
CREATE
权限,多个字段通过逗号(,)分隔,字段名在表里唯一。PRIMARY KEY
、UNIQUE
)、参数完整性约束(FOREIGN KEY
)、用户自定义约束(NOT NULL
、DEFAULT
、CHECK
约束等)。NULL
和NOT NULL
可以给字段自定义约束,NULL
表示非必填项可以为NULL
。NOT NULL
表示必填项,不允许为NULL
。需注意NULL
和空格之间的区别,空格(’ ‘)是一个有效字符串,NULL
是一个关键字和空值(’’)。AUTO_INCREMENT
可以将字段设置为自增唯一值,只有整型才能设置,初始值为1,累计递增+1。DEFAULT
表示字段的默认值,当没有值时默认使用设定好的参数。SHOW ENGINES
查看数据库支持的引擎:mysql> show engines;
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| Engine | Support | Comment | Transactions | XA | Savepoints |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
| MEMORY | YES | Hash based, stored in memory, useful for temporary tables | NO | NO | NO |
| MRG_MYISAM | YES | Collection of identical MyISAM tables | NO | NO | NO |
| CSV | YES | CSV storage engine | NO | NO | NO |
| FEDERATED | NO | Federated MySQL storage engine | NULL | NULL | NULL |
| PERFORMANCE_SCHEMA | YES | Performance Schema | NO | NO | NO |
| MyISAM | YES | MyISAM storage engine | NO | NO | NO |
| InnoDB | DEFAULT | Supports transactions, row-level locking, and foreign keys | YES | YES | YES |
| BLACKHOLE | YES | /dev/null storage engine (anything you write to it disappears) | NO | NO | NO |
| ARCHIVE | YES | Archive storage engine | NO | NO | NO |
+--------------------+---------+----------------------------------------------------------------+--------------+------+------------+
创建表后,可以通过命令查看某数据库创建的有哪些表及表的结构,确定表定义是否正确。
语法格式如下:
SHOW TABLES;
执行如下所示:
mysql> use school;
Database changed
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| tb_student |
+------------------+
1 row in set (0.00 sec)
DESCRIBE/DESC
语句或SHOW CLUMNS
查看表的结构,包括字段名、数据类型、默认值等。语法格式如下:
SHOW COLUMNS FROM 表名;
DESC 表名;
执行如下所示:
mysql> show columns from tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| age | int | NO | | NULL | |
| class_no | varchar(10) | YES | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| age | int | NO | | NULL | |
| class_no | varchar(10) | YES | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
当然,还可以查看表的详细结构,格式如下:
SHOW CREATE TABLE 表名;
执行如下所示:
mysql> show create table tb_student;
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| tb_student | CREATE TABLE `tb_student` (
`student_no` int NOT NULL AUTO_INCREMENT,
`student_name` varchar(20) NOT NULL,
`age` int NOT NULL,
`class_no` varchar(10) DEFAULT NULL,
PRIMARY KEY (`student_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+------------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
这样不仅可以查看创建表的详细语句,还可以查看存储引擎和字符编码。
有时候可能把表创建好了,应需求变动,需要对表做一些调整与修改。
格式如下:
ALTER TABLE 表名 ADD COLUMN 字段名 数据类型 约束条件 [FIRST | AFTER];
[FIRST
| AFTER
]:表示新增字段的位置,是第一个字段还是在已有字段后面,默认最后一列。
比如:在tb_student表中新增id_no字段,执行如下所示:
mysql> alter table tb_student add column id_no varchar(32) not null unique ;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| age | int | NO | | NULL | |
| class_no | varchar(10) | YES | | NULL | |
| id_no | varchar(32) | NO | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
ALTER TABLE
提供了三个修改字段的子句,分别如下:
(1)CHANGE
子句。可以修改列名、数据类型,同时添加多个CHANGE
子句只需逗号分开。
ALTER TABLE 表名 CHANGE [COLUMN]原字段名 新字段名 数据类型[约束条件];
比如:修改tb_student表的age字段改为student_age类型为bigint,默认值为0,执行如下所示:
mysql> alter table tb_student change column age student_age bigint(20) default 0;
Query OK, 0 rows affected, 1 warning (0.06 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | 0 | |
| class_no | varchar(10) | YES | | NULL | |
| id_no | varchar(32) | NO | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
(2)ALTER
子句。修改和删除列的默认值。
ALTER TABLE 表名 ALTER [COLUMN]字段名 {
SET|DROP} DEFAULT;
比如:将student_no字段改为18,再删除默认值,执行如下所示:
mysql> alter table tb_student alter column student_age set default '18';
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | 18 | |
| class_no | varchar(10) | YES | | NULL | |
| id_no | varchar(32) | NO | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
mysql> alter table tb_student alter column student_age drop default;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | NULL | |
| class_no | varchar(10) | YES | | NULL | |
| id_no | varchar(32) | NO | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
(3)MODIFY
子句。与CHANGE
子句不同,只能修改数据类型和列的顺序。
ALTER TABLE 表名 MODIFY [COLUMN]字段名 数据类型[约束条件][FIRST | AFTER];
比如:修改id_no的数据类型长度为int类型,排在class_no前面。
mysql> alter table tb_student modify column id_no int(18) after student_age;
Query OK, 0 rows affected, 1 warning (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 1
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | NULL | |
| id_no | int | YES | UNI | NULL | |
| class_no | varchar(10) | YES | | NULL | |
+--------------+-------------+------+-----+---------+----------------+
5 rows in set (0.00 sec)
语法格式为:
ALTER TABLE 表名 DROP [COLUMN]字段名;
比如:现在的班级号我想提取出来,单独新建一个表,此时需要删除此字段,执行如下所示:
mysql> alter table tb_student drop column class_no;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> desc tb_student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | NULL | |
| id_no | int | YES | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
有时候可能再新建表的时候把表名命名错了,需要重新命名,语法格式为:
ALTER TABLE 表名 RENAME [TO] 新表名;
或者
RENAME TABLE 表名 TO 新表名;
现在我们将tb_student改为student,方便输入,执行如下所示:
mysql> alter table tb_student rename to student;
Query OK, 0 rows affected (0.01 sec)
mysql> rename table tb_student to student;
Query OK, 0 rows affected (0.03 sec)
mysql> desc tb_student;
ERROR 1146 (42S02): Table 'school.tb_student' doesn't exist
mysql> desc student;
+--------------+-------------+------+-----+---------+----------------+
| Field | Type | Null | Key | Default | Extra |
+--------------+-------------+------+-----+---------+----------------+
| student_no | int | NO | PRI | NULL | auto_increment |
| student_name | varchar(20) | NO | | NULL | |
| student_age | bigint | YES | | NULL | |
| id_no | int | YES | UNI | NULL | |
+--------------+-------------+------+-----+---------+----------------+
4 rows in set (0.00 sec)
再使用原来的表名就会报表不存在,所有操作都有用新的表名
当数据库重构以后,会有很多废弃的表,防止占用空间,浪费资源,需要将它删除,语法格式为:
DROP TABLE [IF EXISTS] 表名,....[表n];
加上IF EXISTS
语句防止删除表时报错,删除多个表用逗号(,)隔开,比如:现在我要删除class_student表,执行如下所示:
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| class_student |
| student |
+------------------+
2 rows in set (0.00 sec)
mysql> drop table class_student;
Query OK, 0 rows affected (0.01 sec)
mysql> show tables;
+------------------+
| Tables_in_school |
+------------------+
| student |
+------------------+
1 row in set (0.00 sec)
所有的表的删除操作都会影响对应的数据,所以删除需谨慎。
关系模型的完整性规则是对关系的某种约束。保证数据的正确性和一致性,关系模型中有三类完整性约束,分别是实体完整性、参照完整性、用户定义的完整性。完整性约束能有效地防止对MySQL的意外破坏和非法存取,提高完整性检测的效率,减轻开发人员负担。
实体完整性是指关系的主属性不能为空值。
NULL
。主键约束使用PRIMARY KEY
来实现,可以通过创建表或修改表示添加,其方式有两种,下面以新建一个class表来说明两种的区别:
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int not null
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int,
-> class_count int null,
-> class_tech_no int not null,
-> primary key(class_no)
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
CONSTRAINT<约束名>
{
PRIMARY KEY(主键字段)
|UNIQUE(候选键字段)
|FOREIGN KEY(外键字段) REFERENCES 参照表(主键字段)
|CHECK(约束条件表达式)
};
比如:给班级表的class_teacher_no创建一个约束名为PK_tech的约束
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int not null,
-> constraint PK_tech foreign key(class_tech_no) references tb_tech(tech_no)
-> )engine=InnoDB;
Query OK, 0 rows affected (0.04 sec)
NULL
值,可以有多个候选键,同样有列级和表级两种完整性约束,下面再class表中给class_tech_no添加候选键约束,执行如下所示:mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int not null unique
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int,
-> class_count int null,
-> class_tech_no int not null,
-> constraint uq_class UNIQUE(class_tech_no)
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
参照完整性规则定义的是外键与主键之间的引用规则,即外键的取值或者为空,或者等于被参照关系中某个主键的值,同样有列级和表级两种完整性约束。定义外键时,需要遵循以下规则:
(1)被参照表必须已存在。
(2)必须是被参照表定义的主键或候选键。
(3)外键列和被参照表的主键或候选键数据类型相同。
比如:给class表的class_tech_no定义外键,执行如下所示:
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int not null references tb_tech(tech_no)
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
mysql> drop table class;
Query OK, 0 rows affected (0.01 sec)
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int not null,
-> constraint PK_tech foreign key(class_tech_no) references tb_tech(tech_no)
-> )engine=InnoDB;
Query OK, 0 rows affected (0.04 sec)
再class表上定义外键约束后,只有当tech表没有数据是时才可删除class数据,MySQL可以通过定义违约处理策略,来修改这个规则。
违约处理策略包括两部分:一是指定参照动作的语句(UPDATE
、DELETE
);二是指定采取动作(RESTRICT
、CASCADE
、SET NULL
、NO ACTION
和SET DEFAULT
),其中RESTRICT
为默认值。具体策略如下:
mysql> create table class(
-> class_no int primary key,
-> class_count int null,
-> class_tech_no int
-> constraint PK_tech foreign key(class_tech_no) references tb_tech(tech_no)
-> ON DELETE SET NULL
-> ON UPDATE CASCADE
-> )engine=InnoDB;
Query OK, 0 rows affected (0.02 sec)
mysql> select * from class;
+----------+-------------+---------------+
| class_no | class_count | class_tech_no |
+----------+-------------+---------------+
| 1 | 22 | 1 |
+----------+-------------+---------------+
1 row in set (0.00 sec)
mysql> select * from tb_tech;
+---------+
| tech_no |
+---------+
| 1 |
| 2 |
+---------+
2 rows in set (0.00 sec)
mysql> update tb_tech set tech_no=11 where tech_no=1;
Query OK, 1 row affected (0.00 sec)
Rows matched: 1 Changed: 1 Warnings: 0
mysql> select * from class;
+----------+-------------+---------------+
| class_no | class_count | class_tech_no |
+----------+-------------+---------------+
| 1 | 22 | 11 |
+----------+-------------+---------------+
1 row in set (0.00 sec)
mysql> delete from tb_tech where tech_no =11;
Query OK, 1 row affected (0.01 sec)
mysql> select * from class;
+----------+-------------+---------------+
| class_no | class_count | class_tech_no |
+----------+-------------+---------------+
| 1 | 22 | NULL |
+----------+-------------+---------------+
1 row in set (0.00 sec)
用户定义完整性,满足了应用的语义需求,MySQL支持的几种用户定义完整性,分别是非空约束、CHECK
约束和触发器。
NOT NULL
关键字,来约束列取值不能为空。执行如下所示:mysql> create table tb_student(
-> student_no int not null primary key auto_increment,
-> student_name varchar(20) not null,
-> age int not null,
-> class_no varchar(10) default null
-> )engine=Innodb;
Query OK, 0 rows affected (0.02 sec)
mysql> alter table tb_student add column id_no varchar(32) not null unique ;
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
CHECK
关键字。执行如下所示:mysql> create table tb_student(
-> student_no int not null primary key auto_increment,
-> student_name varchar(20) not null,
-> age int not null CHECK(age >0 and age <25),
-> class_no varchar(10) default null
-> )engine=Innodb;
Query OK, 0 rows affected (0.02 sec)
当约束建立不符合要求时,可以使用 ALTER TABLE
语句来更新有关约束。
(1)删除主键约束
语法格式为:
ALTER TABLE 表名 DROP PRIMARY KEY;
比如:删除class表的class_no的主键约束,执行如下所示:
mysql> show create table class;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
KEY `PK_tech` (`class_tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class drop primary key;
Query OK, 1 row affected (0.06 sec)
Records: 1 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
KEY `PK_tech` (`class_tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(2)删除外键约束
语法格式为:
ALTER TABLE 表名 DROP FOREIGN KEY 外键约束名;
比如:删除class表中class_tech_no的外键约束,执行如下所示:
mysql> show create table class;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
KEY `PK_tech` (`class_tech_no`),
CONSTRAINT `PK_tech` FOREIGN KEY (`class_tech_no`) REFERENCES `tb_tech` (`tech_no`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class drop foreign key PK_tech;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
KEY `PK_tech` (`class_tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(2)删除候选键约束
语法格式为:
ALTER TABLE 表名 DROP 候选键字段;
比如:删除class表class_count字段的候选键,执行如下所示:
mysql> show create table class;
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
UNIQUE KEY `PK_class_count` (`class_count`),
KEY `PK_tech` (`class_tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class drop class_count;
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+-------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_tech_no` int DEFAULT NULL,
KEY `PK_tech` (`class_tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(1)添加主键约束
语法格式为:
ALTER TABLES 表名 ADD CONSTRAINT 约束名 PRIMARY KEY (主键字段);
比如:给class表的class_no字段加上主键约束,执行如下所示:
mysql> show create table class;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class add constraint PK_class_no primary key(class_no);
Query OK, 0 rows affected (0.04 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(2)添加外键约束
语法格式为:
ALTER TABLES 表名 ADD CONSTRAINT 约束名 FOREIGN KEY (外键字段) REFERENCES 被参照表(主键字段);
比如:给class表的class_tech_no字段加上外键约束,执行如下所示:
mysql> show create table class;
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class add constraint FK_class_tech_no foreign key(class_tech_no) references tb_tech(tech_no);
Query OK, 0 rows affected (0.07 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
KEY `FK_class_tech_no` (`class_tech_no`),
CONSTRAINT `FK_class_tech_no` FOREIGN KEY (`class_tech_no`) REFERENCES `tb_tech` (`tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
(3)添加候选键约束
语法格式为:
ALTER TABLES 表名 ADD CONSTRAINT 约束名 UNIQUE KEY (字段);
比如:给class表的class_count字段加上主键约束,执行如下所示:
mysql> show create table class;
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
KEY `FK_class_tech_no` (`class_tech_no`),
CONSTRAINT `FK_class_tech_no` FOREIGN KEY (`class_tech_no`) REFERENCES `tb_tech` (`tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
mysql> alter table class add constraint UN_class_count unique key(class_no);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show create table class;
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
| class | CREATE TABLE `class` (
`class_no` int NOT NULL,
`class_count` int DEFAULT NULL,
`class_tech_no` int DEFAULT NULL,
PRIMARY KEY (`class_no`),
UNIQUE KEY `UN_class_count` (`class_no`),
KEY `FK_class_tech_no` (`class_tech_no`),
CONSTRAINT `FK_class_tech_no` FOREIGN KEY (`class_tech_no`) REFERENCES `tb_tech` (`tech_no`)
) ENGINE=InnoDB DEFAULT CHARSET=gb2312 |
+-------+-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)
索引(Index)是数据库技术的一个重要概念与技术,也是MySQL的一个数据库对象。索引是查询优化的最主要的方式。
对数据库中表进行查询时,系统对表中数据主要有两种搜索方式一种是全表扫描、检索,这种是将表的数据从头到尾逐行读取,这种查询效率就会降低;另一种是利用数据表上建立的索引进行扫描,根据索引值与记录关系直接访问数据表中的记录行。
如下图所示,比如查询学生编号为“2021002”的学生姓名,首先找到“2021002”在索引项的记录,在按照索引值与数据表之间的关系,之间找到“2021002”对应的数据记录。
在MySQL中索引分为普通索引、唯一索引、主键索引、聚族索引及全文索引等。
(1)普通索引
最基本的索引类型,索引列值可以取空值或重复值。创建普通索引时,通常使用的关键字是INDEX
或KEY
。
(2)唯一索引
索引列值不能重复,唯一的,可以是空值。关键字是UNIQUE
.
(3)主键索引
主键索引是一种唯一索引。与唯一索引不同的是引用列值不能为空。关键字为PRIMARY KEY
。
(4)聚族索引
索引的顺序就是数据存储的物理存储顺序,这样能保证索引值相近的元组所存储的物理位置也相近。并非所有存储引擎支持聚族索引,目前只有solidDB和InnoDB。
(5)全文索引
只能创建在数据类型为VARCHAR
或TEXT
的列上。建立全文索引后,能够在建立的列上进行全文查找。
在实际使用中,索引可以建立在单一列上,称为单列索引。也可以建立在多个列上,称为组合索引。
(1)单列索引
一个索引只包含原表中的一个列。一个表上可以建立多个单列索引。比如,在学生表中建立学号索引,还可以建立班级索引。
(2)组合索引
在表的多个列上创建一个索引。比如,班级表的“班号”和“班主任编号”建立一个索引,称为组合索引。
语法格式为:
SHOW {
INDEX|INDEXES|KEYS} {
FROM | IN} 表名 [{
FROM | IN} 表名];
比如:查看学生表的索引,\G按列打印,方便查询。执行结果如下所示:
mysql> show index from student\G;
*************************** 1. row ***************************
Table: student #表名称
Non_unique: 0 #是否唯一索引。是:1,否:0
Key_name: PRIMARY # 索引名称
Seq_in_index: 1
Column_name: student_no #建立索引的列名
Collation: A #顺序索引 升序:A
Cardinality: 6 # 数据行数
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE # 索引类型 B+树
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
MySQL提供了三种创建索引的方法。一种是创建表的时候创建索引,另外两种分别是在已存在的表上建立索引,使用CREATE INDEX
或ALTER TABLE
添加索引。
CAEATE TABLE
创建索引CREATE TABLE 表名(
字段名 数据类型 [列级完整性约束条件] [默认值],
... ...
[CONSTRAINT 索引名][UNIQUE] [INDEX |KEY]
[索引名](列名)[ASC|DESC]
)ENGINE = 引擎类型;
比如:创建tb_student_1的表建立主键、唯一索引。执行结果如下所示:
mysql> create table tb_student_1(
-> student_no int not null primary key unique auto_increment,
-> student_name varchar(20) not null,
-> age int not null,
-> class_no varchar(10) default null
-> )engine=Innodb;
Query OK, 0 rows affected (0.02 sec)
mysql> show index from tb_student_1 \G;
*************************** 1. row ***************************
Table: tb_student_1
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: student_no
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: tb_student_1
Non_unique: 0
Key_name: student_no
Seq_in_index: 1
Column_name: student_no
Collation: A
Cardinality: 0
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
2 rows in set (0.01 sec)
CERATE INDEX
创建索引CREATE [UNIQUE] INDEX 索引名 ON 表名(列名[ASC|DESC]);
比如:创建老师表的编号的唯一降序索引。执行结果如下所示:
mysql> create unique index un_tech on tech(tech_no desc);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from tech \G;
*************************** 1. row ***************************
Table: tech
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: tech_no
Collation: A
Cardinality: 6
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
*************************** 2. row ***************************
Table: tech
Non_unique: 0
Key_name: un_tech
Seq_in_index: 1
Column_name: tech_no
Collation: D
Cardinality: 6
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
2 rows in set (0.00 sec)
ALTER TABLE
创建索引ALTER TABLE 表名 ADD [UNIQUE | FULLTEXT] [INDEX | KEY] [索引名](列名[ASC|DESC]);
比如:给老师表的老师名称加上唯一索引。执行结果如下所示:
mysql> alter table tech add unique un_tech_name(tech_name);
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
#省略多余结果,可参考上面
*************************** 3. row ***************************
Table: tech
Non_unique: 0
Key_name: un_tech_name
Seq_in_index: 1
Column_name: tech_name
Collation: A
Cardinality: 6
Sub_part: NULL
Packed: NULL
Null: YES
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
3 rows in set (0.00 sec)
DEOP INDEX
语句删除索引DROP INDEX 索引名 ON 表名;
比如:删除老师表的老师名称索引。执行结果如下所示:
mysql> drop index un_tech_name on tech;
Query OK, 0 rows affected (0.02 sec)
Records: 0 Duplicates: 0 Warnings: 0
ALTER TABLE
语句删除索引ALTER TABLE 表名 DROP INDEX 索引名;
比如:删除老师表的老师编号索引。执行结果如下所示:
mysql> alter table tech drop index un_tech;
Query OK, 0 rows affected (0.01 sec)
Records: 0 Duplicates: 0 Warnings: 0
mysql> show index from tech \G;
*************************** 1. row ***************************
Table: tech
Non_unique: 0
Key_name: PRIMARY
Seq_in_index: 1
Column_name: tech_no
Collation: A
Cardinality: 6
Sub_part: NULL
Packed: NULL
Null:
Index_type: BTREE
Comment:
Index_comment:
Visible: YES
Expression: NULL
1 row in set (0.00 sec)
可以看到之前创建的两个索引都删除了。
使用索引可以大大加快查询速度,提高MySQL的检索性能,但过多的使用反而会影响系统性能。
INSERT
、UPDATE
、DELETE
的效率。上一篇:MySQL数据库程序设计(一)
下一篇:MySQL数据库程序设计(三)