主要内容:
数据库管理(创建数据库、修改数据库、删除数据库)、表管理(关系数据库的规范化1NF\2NF\3NF、创建表、修改表、删除表、复制表)、约束(分类、应用)、事务控制语言TCL
一、数据库管理
库名的命名规则
- ① 仅可以使用数字、字母、下划线、不能纯数字
- ② 区分字母大小写,具有唯一性
- ③ 不可使用指令关键字、特殊字符
1、创建数据库
- 格式:
CREATE DATABASE [IF NOT EXISTS]
[[DEFAULT] CHARACTER SET ]
[[DEFAULT] COLLATE ];
解释说明:
- <数据库名>:创建数据库的名称。MySQL 的数据存储区将以目录方式表示 MySQL 数据库,因此数据库名称必须符合操作系统的文件夹命名规则,不能以数字开头,尽量要有实际意义。注意在 MySQL 中数据库名区分大小写。
- IF NOT EXISTS:在创建数据库之前进行判断,只有该数据库目前尚不存在时才能执行操作。此选项可以用来避免数据库已经存在而重复创建的错误。
- [DEFAULT] CHARACTER SET:指定数据库的字符集。指定字符集的目的是为了避免在数据库中存储的数据出现乱码的情况。如果在创建数据库时不指定字符集,那么就使用系统的默认字符集。(汉语字符集:utf8mb4)
- [DEFAULT] COLLATE:指定字符集的默认校对规则。
- MySQL 的字符集(CHARACTER)和校对规则(COLLATION)是两个不同的概念。字符集是用来定义 MySQL 存储字符串的方式,校对规则定义了比较字符串的方式。
例如:
mysql> create database mydb default charset utf8mb4;
Query OK, 1 row affected (0.00 sec)
mysql> show databases;
+--------------------+
| Database |
+--------------------+
| information_schema |
| mydb |
| mysql |
| nsd2021 |
| performance_schema |
| sys |
+--------------------+
6 rows in set (0.00 sec)
常见报错:再次创建同名数据库,则报错数据库已创建,不会覆盖原有数据库
mysql> create database mydb default charset utf8mb4;
ERROR 1007 (HY000): Can't create database 'mydb'; database exists
2、修改数据库
- 格式:
ALTER DATABASE [数据库名] {
[ DEFAULT ] CHARACTER SET |
[ DEFAULT ] COLLATE };
解释说明:
- ALTER DATABASE 用于更改数据库的全局特性。
- 使用 ALTER DATABASE 需要获得数据库 ALTER 权限。
- 数据库名称可以忽略,此时语句对应于默认数据库。
- CHARACTER SET 子句用于更改默认的数据库字符集。
3、删除数据库
- 格式:DROP DATABASE [ IF EXISTS ] ;
解释说明:
- :指定要删除的数据库名。
- IF EXISTS:用于防止当数据库不存在时发生错误。
- DROP DATABASE:删除数据库中的所有表格并同时删除数据库。
- 如果要使用 DROP DATABASE,需要获得数据库 DROP 权限。
二、表管理
良好的数据库设计表现在以下几方面:
- 访问效率高;
- 减少数据冗余,节省存储空间,便于进一步扩展;
- 可以使应用程序的开发变得更容易;
1、范式(NF,Normal Form)
数据库的设计范式,是符合某一种级别的关系模式的集合,构造数据库必须遵循一定的规则,在关系数据库中,这种规则就是范式(关系数据库中的每一个关系都要满足一定的规范);根据满足规范的条件不同,可以分为5个等级:第一范式(1NF)、第二范式(2NF)……第五范式(5NF)。一般情况下,只要把数据规范到第三范式标准就可满足需求。
① 第一范式(1NF)--> 无重复的列
- 在一个关系中,消除重复字段,且各字段都是最小的逻辑存储单位。即要满足原子性。
- 第一范式是第二和第三范式的基础,是最基本的范式。第一范式包括下列指导原则。
(1)数据组的每个属性只可以包含一个值。
(2)关系中的每个数组必须包含相同数量的值。
(3)关系中的每个数组一定不能相同。
- 在任何一个关系数据库中,第一范式是对关系模式的基本要求,不满足第一范式的数据库就不是关系型数据库。
② 第二范式(2NF)--> 属性完全依赖于主键(非主属性非部分依赖于主关键字)
- 第二范式是在第一范式的基础上建立起来的,即满足第二范式必先满足第一范式(1NF)。
- 第二范式要求数据库表中的每个实体(即各个记录行)必须可以被唯一地区分。为实现区分各行记录通常需要为表设置一个“区分列”,用以存储各个实体的唯一标识。这个唯一属性列被称为主关键字或主键。
- 第二范式要求实体的属性完全依赖于主关键字,即不能存在仅依赖主关键字一部分的属性,如果存在,那么这个属性和主关键字的这一部分应该分离出来形成一个新的实体(新表),新实体与原实体之间是一对多的关系。
③ 第三范式(3NF)--> 属性不依赖于其它非主属性
- 第三范式是在第二范式的基础上建立起来的,即满足第三范式必先满足第二范式。
- 第三范式要求关系表不存在非关键字列对任意候选关键字列的传递函数依赖,也就是说,第三范式要求一个关系表中不包含已在其他表中包含的非主关键字信息。
- 除主键外,其他字段必须依赖主键。
补充:完全依赖、部分依赖、传递依赖
① 部分函数依赖:设X,Y是关系R的两个属性集合,存在X→Y,若X’是X的真子集,存在X’→Y,则称Y部分函数依赖于X。
例子:学生基本信息表R中(学号,身份证号,姓名)当然学号属性取值是唯一的,在R关系中,(学号,身份证号)->(姓名),(学号)->(姓名),(身份证号)->(姓名);所以姓名部分函数依赖与(学号,身份证号);
② 完全函数依赖:设X,Y是关系R的两个属性集合,X’是X的真子集,存在X→Y,但对每一个X’都有X’!→Y,则称Y完全函数依赖于X。
例子:学生基本信息表R(学号,班级,姓名)假设不同的班级学号有相同的,班级内学号不能相同,在R关系中,(学号,班级)->(姓名),但是(学号)->(姓名)不成立,(班级)->(姓名)不成立,所以姓名完全函数依赖与(学号,班级);
③ 传递函数依赖:设X,Y,Z是关系R中互不相同的属性集合,存在X→Y(Y !→X),Y→Z,则称Z传递函数依赖于X。
例子:在关系R(学号 ,宿舍, 费用)中,(学号)->(宿舍),宿舍!=学号,(宿舍)->(费用),费用!=宿舍,所以符合传递函数的要求;
2、表管理语句
1)创建表
- 格式:
CREATE TABLE
(
字段名称1 数据类型 [(长度) 约束],
字段名称2 数据类型 [(长度) 约束],
字段名称3 数据类型 [(长度) 约束],
....
);
- 信息种类:
常用数据类型:
数据类型 |
描述 |
tinyint(m) |
1个字节 范围(-128~127) |
smallint(m) |
2个字节 范围(-32768~32767) |
mediumint(m) |
3个字节 范围(-8388608~8388607) |
int(m) |
4个字节 范围(-2147483648~2147483647) |
bigint(m) |
8个字节 范围(+-9.22*10的18次方) |
float(m,d) |
单精度浮点型 8位精度(4字节) m总个数,d小数位 |
double(m,d) |
双精度浮点型 16位精度(8字节) m总个数,d小数位 |
decimal(m,d) |
m表示十进制数字总的个数,d表示小数点后面数字的位数。常用于货币 |
char(n) |
固定长度,最多255个字符,不够指定字符格式时在右边用空格补全 |
varchar(n) |
不固定长度,最多65535个字符,按数据实际大小分配存储空间 |
tinytext |
可变长度,最多255个字符 |
text |
可变长度,最多65535个字符 |
mediumtext |
可变长度,最多2的24次方-1个字符 |
longtext |
可变长度,最多2的32次方-1个字符 |
date |
日期 '2008-12-2' |
time |
时间 '12:25:36' |
datetime |
日期时间 '2008-12-2 22:06:44' |
timestamp |
自动存储记录修改时间 |
enum(选项1, 选项2, ...) |
单选字符串数据类型,适合存储表单界面中的“单选值” |
set(选项1,选项2, ...) |
多选字符串数据类型,适合存储表单界面的“多选值” |
例如:在数据库mydb中,创建departments部门表(id,dept_name)
mysql> use mydb;
Database changed
mysql> select database();
+------------+
| database() |
+------------+
| mydb |
+------------+
1 row in set (0.00 sec)
mysql> create table departments (id int, dept_name varchar(20));
Query OK, 0 rows affect