认识MySQL
- 作用:前端主要负责展示页面数据给用户。这意味着前端开发者需要设计用户界面(UI)和用户体验(UX),确保用户可以直观地与软件交互。
- 技术:前端开发者可能会使用HTML、CSS和JavaScript等技术来构建和美化网页,以及与后端进行通信(例如,通过API请求数据)。
- 作用:后端是连接数据库、控制视图跳转和给前端传递数据的部分。这意味着后端开发者需要处理业务逻辑、数据验证、安全性以及与数据库的交互。
- 技术:后端开发者可能会使用Java、Python、Ruby等编程语言,以及框架(如Spring、Django)和数据库连接技术(如JDBC)来构建后端服务。
- JDBC:Java Database Connectivity(JDBC)是一个Java API,用于执行SQL语句和访问数据库。它允许Java程序与各种关系数据库进行交互。
- 作用:数据库用于存储和管理数据。在这个上下文中,MySQL是一个流行的关系型数据库管理系统(RDBMS),用于存储和检索应用程序需要的数据。
- 技术:数据库管理员(DBA)或数据库开发者可能会使用SQL(结构化查询语言)来查询、插入、更新和删除数据。
- 只会CRUD(Create, Read, Update, Delete,即创建、读取、更新、删除),可以混饭吃 = 初级
- 操作系统,数据结构和算法 = 中级
- 离散数学,数字电路,编译原理+实战经验 = 高级
为什么学习数据库
什么是数据库( DataBase , 简称 DB )
定义:数据库是一个关键组件,用于存储、管理、查询和维护应用程序所需的数据。简而言之,数据库是一个按照数据结构来组织、存储和管理数据的仓库。它是长期存储在计算机内的、有组织的、可共享的、统一管理的大量数据的集合。它确保了数据的完整性、安全性和一致性,并支持对数据进行增加、删除、修改和查询等操作。
作用:数据存储、管理(增删改查)、保护、共享、备份与恢复;支持业务逻辑;性能优化
两种数据库类型
关系型数据库(SQL)
数据结构特点
- 表格化组织:关系型数据库的主要数据组织形式是表格(或称为关系)。每个表格包含行(记录)和列(字段),其中行代表具体的数据记录,而列则代表记录中的各个属性或数据项。
- 明确的关系:关系型数据库中的数据表之间通过主键和外键等约束来建立明确的关系。主键是表格中唯一标识数据记录的属性,而外键则用于连接不同表格中的数据,确保数据的完整性和一致性。
- 数据完整性:关系型数据库支持事务处理,确保数据的完整性。ACID是数据库事务的四个关键属性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这些属性保证了在多个操作同时发生时,数据库能够保持数据的完整性和一致性。
- 标准查询语言:关系型数据库使用结构化查询语言(SQL)来管理和查询数据。这使得用户可以通过SQL语句方便地进行数据的检索、更新、删除等操作,提高数据处理的效率和灵活性。
常见关系型数据库系统:
- MySQL、Oracle、SQL Server、SQLite、DB2等。
非关系型数据库(NoSQL)
数据结构特点
- 灵活性:非关系型数据库的数据结构并不局限于固定的表结构,每个记录(或元组)都可以具有不同的字段,并且这些字段可以按需动态修改。这种灵活性使得开发者能够在不改变整个数据库结构的前提下,轻松地为记录添加新的字段或属性,从而轻松应对快速变化的数据需求,存储多样化的数据,例如用户评论、日志文件、社交媒体内容等。
- 非表格形式:非关系型数据库可以使用键值对(key-value)、文档(document)或图形(graph)等形式来存储数据。这些数据结构更适合处理非结构化或半结构化的数据,能够处理更为复杂、多样化的数据类型。
- 水平可扩展性:由于非关系型数据库通常具有水平可扩展性,因此可以轻松地通过添加更多的服务器来增加数据库的容量和性能。这种特性使得非关系型数据库非常适合处理大规模、高并发的数据读写请求,适用于高性能场景。
常见非关系型数据库系统:
- Redis、MongoDB、Cassandra、CouchDB、HBase、Neo4j等。
什么是DBMS
数据库管理系统 ( DataBase Management System ):
它是一种操纵和管理数据库的大型软件,用于建立、使用和维护数据库。DBMS提供数据定义功能、数据存取功能、数据库运行管理功能、数据库的建立和维护功能以及数据库的传输等功能。按功能划分,数据库管理系统大致可分为6个部分,包括 模式翻译、应用程序的编译、交互式查询、数据的组织与存取、事务运行管理、数据库的维护。
MySQL简介
概念:是现在流行的开源的,免费的关系型数据库
特点 :
- 免费,开源数据库
- 小巧,功能齐全
- 使用便捷
- 可运行于Windows或Linux操作系统
- 可适用于中小型甚至大型网站应用
命令行操作
DBMS中SQL语句分类
名称 | 解释 | 命令 |
---|---|---|
DDL(数据定义语言) | 定义和管理数据对象,如数据库,数据表等 | CREATE、DROP、ALTER |
DML(数据操作语言) | 用于操作数据库对象中所包含的数据 | INSERT、UPDATE、DELETE |
DQL(数据查询语言) | 用于查询数据库数据 | SELECT |
DCL(数据控制语言) | 用于管理数据库的语言,包括管理权限及数据更改 | GRANT、commit、rollback |
在SQL中,命令关键字不区分大小写
反引号``:在MySQL中,如果表名或字段名包含特殊字符(如空格、连字符、点、美元符号等)或它们是SQL的关键字(如 SELECT
, FROM
, WHERE
等),那么通常需要用反引号(``)来引用它们。
作用:告诉数据库管理系统(DBMS)该标识符(表名或字段名)应该被当作一个标识符而不是一个关键字或其他特殊字符来处理。
数据库管理中逐步细化的过程
操作数据库 > 操作数据库中的表 > 操作数据库表中的数据
操作数据库
- 使用命令行工具
mysql
连接到MySQL服务器。格式如下:mysql -h [主机地址] -u [用户名] -p [主机地址]:可以输入服务器的IP地址、域名或者主机名 [用户名]:指定连接到MySQL服务器时使用的用户名 -p:提示用户输入与指定用户名关联的密码
- 如果是连接到本地MySQL服务器,可以使用:
mysql -u [用户名] -p
- 输入密码后,如果成功,将看到MySQL的提示符
mysql>
创建数据库(以下在数据库管理系统中执行)
CREATE DATABASE IF NOT EXISTS [数据库名];
所有的创建和删除操作尽量加上判断,以免报错
查看创建数据库的完整语句
SHOW CREATE DATABASE [数据库名];
执行这个命令后,MySQL将返回一个结果集,其中包含两行数据。第一行是数据库名,第二行是创建该数据库的SQL语句。这个SQL语句可以用来在其他MySQL服务器上重新创建具有相同配置的相同数据库。需要具有足够权限。
删除数据库
-
在删除数据库之前,要确保已经备份了所有重要的数据,因为删除操作是不可逆的。
DROP DATABASE [数据库名];
-
在MySQL中,
FLUSH
命令可以用来刷新或重置某些服务器资源。例如,要刷新权限,可以使用:FLUSH PRIVILEGES;
这将重新加载授权表,使得任何最近的权限更改生效。
- 在MySQL提示符下,输入以下命令查看所有数据库:
SHOW DATABASES;
- 使用
USE
命令选择一个数据库进行操作:USE [数据库名];
操作数据库中的表
- 要查看表的信息,首先需要选择数据库,然后使用
DESCRIBE
或DESC
命令查看表的结构:USE [数据库名]; DESCRIBE [表名]; //或者 DESC [表名];
- 或者,也可以使用
SHOW COLUMNS
命令来查看表的列信息:SHOW COLUMNS FROM [表名];
查看数据表的定义语句
SHOW CREATE TABLE [表名]
执行这个命令后,MySQL将返回一个结果集,其中包含两个列:Table 和 Create Table 。Table 列显示表名,而 Create Table 列则包含用于创建该表的完整SQL语句。需要具有足够权限。
查看数据库中的表
- 使用
SHOW TABLES;
命令查看当前数据库中的所有表。
- 创建表:
CREATE TABLE 表名 (列定义);
- 修改表:
ALTER TABLE 表名 ADD/DROP/MODIFY 列定义;
- 删除表:
DROP TABLE 表名;
操作数据库表中的数据
修改密码
要修改MySQL用户的密码,可以使用SET PASSWORD
命令或者ALTER USER
命令。以下是两种方法的示例:
-
使用
SET PASSWORD
命令(适用MySQL 5.7.6前的老旧版本):SET PASSWORD FOR [用户名]@[主机名] = PASSWORD([新密码]);
-
使用
ALTER USER
命令(推荐,因为更灵活且安全):ALTER USER [用户名]@[主机名] IDENTIFIED BY [新密码];
注意,在修改密码时,需要具有足够的权限来执行这些命令。通常,这意味着开发者需要以 root 用户或其他具有管理员权限的用户身份登录到MySQL服务器。
- 在MySQL提示符下,可以直接输入SQL语句并执行,例如:
SELECT * FROM [表名];
- 插入数据:
INSERT INTO 表名 (列名) VALUES (值);
- 查询数据:
SELECT 列名 FROM 表名 WHERE 条件;
- 更新数据:
UPDATE 表名 SET 列名 = 新值 WHERE 条件;
- 删除数据:
DELETE FROM 表名 WHERE 条件;
其他操作
- 使用
SOURCE
命令执行SQL脚本文件:SOURCE [文件路径];
- 使用
EXIT
命令退出MySQL命令行工具。
-- 当行注释
/*
多行注释
*/
数据库
数据库的列(数据)类型
数值
类型 | 说明 | 取值范围 | 字节 |
---|---|---|---|
tinyint | 十分小的数据 | -27 到 27 - 1 (有符号)0 到 28 - 1 (无符号) | 1个字节 |
smallint | 较小的数据 | -215 到 215 - 1 (有符号)0 到 216 - 1 (无符号) | 2个字节 |
mediumint | 中等大小数据 | -223 到 223 - 1 (有符号)0 到 224 - 1 (无符号) | 3个字节 |
int | 标准的整数 | -231 到 231 - 1 (有符号)0 到 232 - 1 (无符号) | 4个字节 |
bigint | 较大的数据 | -263 到 263 - 1 (有符号)0 到 264 - 1 (无符号) | 8个字节 |
float | 单精度浮点数 | 约 (3.4e-38,1.17e+38)0 , (-3.4e-38,-1.17e+38) (IEEE 754 标准) | 4个字节 |
double | 双精度浮点数 | 约 (2.23e-308,1.80e+308)0 , (-2.23e-308,-1.80e+308) (IEEE 754 标准) | 8个字节 |
decimal | 字符串形式的浮点数 | 依赖于定义的精度和刻度 | 可变 |
说明:
这里的 E
或 e
是科学计数法中的一个标准符号,用于表示乘以 10
的某个幂次。而并不是指自然常数 e
(约等于 2.71828)。在科学计数法中,E-38
或 e-38
表示 10
的 -38
次方,即 10^-38
。
decimal:
[列名] DECIMAL(P,D)
意味着它可以存储最多 P 位数,其中 D 位是小数部分。存储数值区间是[-最大数字,+最大数字]。
字符串形式的浮点数不具有舍入误差,在数据库中通常用于存储精确的数值,尤其是当涉及到货币或其他需要精确计算的场合时。
字符串
类型 | 说明 | 字节 |
---|---|---|
char | 字符串固定大小的 | 0-255 |
varchar | 可变字符串 | 0-65535 |
tinytext | 微型文本 | 2^8 -1 |
text | 文本串 | 2^16-1 保存大文本 |
日期时间
类型 | 说明 | 字节 |
---|---|---|
date | [年]-[月]-[日] [ ]表示数字 | 日期格式 |
time | [时]:[分]:[秒] | 时间格式 |
datetime | [年]-[月]-[日] [时]:[分]:[秒] | 最常用 |
timestamp | 时间戳 | 1970.1.1 到现在的毫秒数 用于记录精确时间 |
year | [年] |
NULL
没有值,未知
注意:使用null进行运算,结果为null
数据库的字段属性
UNSIGNED
- 声明该列只能存储非负整数
ZEROFILL
- 如果字段的值不足以填满指定的宽度,那么会在值的左侧填充 0,以确保整数字段总是具有指定的显示宽度
- 要求列的值必须是非负的
- 例如
INT(5) ZEROFILL
。这里的5
是显示宽度,意味着当值显示时,它应该总是有5位数
AUTO_INCREMENT
-
自增,自动在上一条记录的基础上+1(默认)
-
自增属性通常用于为主键生成唯一的ID值,新记录插入时该值自动递增,确保每条记录有唯一标识符
-
被设置为 Auto_Increment 的列中的记录必须是整数类型
-
如果列同时设置了
ZEROFILL
和AUTO_INCREMENT
属性,MySQL 会确保新生成的自动增长值在显示时满足ZEROFILL
的要求 -
可以设置自增的起始值和步长(在MySQL中,可以在创建表时设置起始值,而步长通常是在会话级别或全局级别设置的,而非针对单个表)
语法格式
CREATE TABLE table_name ( column_name INT NOT NULL AUTO_INCREMENT, -- 其他列定义 PRIMARY KEY (column_name) ) AUTO_INCREMENT = START_VALUE; --table_name 是要创建的表的名称 --column_name 是要设置为自增的列的名称 --START_VALUE 是起始值
NOT NULL 非空
- 如果设置为NOT NULL,则该列必须有值,否则就会报错;
DEFAULT 默认
- 当创建表时,可以在列定义中使用
DEFAULT
关键字来指定默认值 - 如果列的数据类型允许
NULL
值(即列的定义中包含了NULL
),并且没有为该列指定默认值,那么该列的默认值就是NULL
- 如果列的数据类型不允许
NULL
值(即列的定义中没有包含NULL
),并且没有为该列指定默认值,那么在尝试插入没有该列值的新记录时,MySQL将抛出一个错误
拓展
每一个表,都必须存在以下5个字段!未来做项目用的,表示一个记录存在的意义
- id 主键
- version 乐观锁
- is_delect 伪删除
- gmt_create 创建时间
- gmt_update 修改时间
主键(Primary Key)是数据库表中用于唯一标识每条记录的一列或一组列。主键的作用是确保表中的每条记录都具有唯一的标识符,以便能够轻松地进行检索、更新和删除操作。
主键具备以下特点:
- 唯一性:主键列的值必须是唯一的,任何两条记录不能拥有相同的主键值。
- 非空性:主键列的值不能为空,即不允许出现 NULL 值。
- 一般选择数字类型或者字符串类型来作为主键,通常使用整数类型或者GUID(全局唯一标识符)。
- 一个表只能有一个主键,但主键可以由多个字段组合而成,这种主键称为复合主键。
通过定义主键,可以确保表中的数据记录在逻辑上都有一个独一无二的标识符,从而使得数据库系统能够高效地管理和操作数据。
数据库表
创建数据库表
创建数据库表的语法格式
CREATE TABLE [IF NOT EXISTS] `表名` (
`字段1` [列类型1] [属性1] [索引1] [注释1],
`字段2` [列类型2] [属性2] [索引2] [注释2],
`字段3` [列类型3] [属性3] [索引3] [注释3],
...
`字段N` 列类型N [属性N] [索引N] [注释N],
PRIMARY KEY (`主键字段`)
) [表类型] [表字符集设置] [注释];
说明:
- [IF NOT EXISTS] 是一个可选的关键词,表示 如果表已经存在,
CREATE TABLE
语句将不会执行任何操作,也不会显示错误 表名
是表的名称,需要用反引号(`)括起来,当表名包含特殊字符或与MySQL保留字冲突时必须使用字段N
等是表中的列名,也需要用反引号括起来- [列类型N] 等是对应列的数据类型,如
INT
、VARCHAR(255)
、TEXT
等 - [属性] 是可选的列属性,如
NOT NULL
、DEFAULT 默认值
、AUTO_INCREMENT
等 - [索引] 是可选的索引定义,如
UNIQUE
、FULLTEXT
、FOREIGN KEY
等 - [注释] 是可选的注释,注释内容用--引出
- PRIMARY KEY (
主键字段
) 定义了表的主键,主键字段名也需要用反引号括起来 - [表类型] 是可选的,用于指定表的存储类型,如
ENGINE=InnoDB
- [表字符集设置] 是可选的,用于指定表的字符集和校对规则,如
CHARACTER SET utf8mb4 COLLATE utf8mb4_unicode_ci
- [注释] 是可选的,用于给整个表添加注释
- ()内除了最后一个语句,其他
- 所有语句后面加
,
(英文的)
以下是一个具体的例子:
CREATE TABLE IF NOT EXISTS `users` ( -- 创建一个名为 users的表,如果该表不存在
`id` INT NOT NULL AUTO_INCREMENT, -- 定义一个名为 id的整数字段,不允许为空,并设置为自动增长
`username` VARCHAR(50) NOT NULL, -- 定义一个名为 username的变长字符串字段,最大长度为50,不允许为空
`email` VARCHAR(100) NOT NULL UNIQUE, -- 定义一个名为 email的变长字符串字段,最大长度为100,不允许为空,并且必须是唯一的
`password` VARCHAR(255) NOT NULL, -- 定义一个名为 password的变长字符串字段,最大长度为255,不允许为空
`created_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 定义一个名为 created_at的时间戳字段,默认值为当前时间戳
`updated_at` TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, -- 定义一个名为 updated_at的时间戳字段,默认值为当前时间戳,当记录更新时自动更新为当前时间戳
PRIMARY KEY (`id`) -- 将 id字段设置为主键
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='用户表'; -- 设置表的存储引擎为InnoDB,字符集为utf8mb4,并添加注释'用户表'
数据库表的类型
数据库引擎:
MYISAM | INNODB | |
---|---|---|
事物支持 | 不支持 | 支持 |
数据行锁定 | 不支持 (它只表锁) | 支持 |
外键约束 | 不支持 | 支持 |
全文索引 | 支持 | 支持(MySQL 5.6版本之后) |
表空间大小 | 较小 | 较大,约为MYISAM2倍 |
适用场景:
- MyISAM : 节约空间及相应速度;主要是读操作,并且不需要事务支持、行级锁定和外键约束
- 适用 InnoDB : 安全性高,事务处理及多用户操作数据表,多表多用户操作;需要事务支持、行级锁定和外键约束
然而,随着MySQL的发展,InnoDB已经变得越来越流行,因为它提供了更好的数据完整性和并发性能。
在物理空间存在的位置
包括表文件 , 数据文件 , 以及数据库的选项文件
位置 : Mysql安装目录data下存放数据表 . 目录名对应数据库名 , 该目录下文件名对应数据表
物理存储层面:MySQL 数据库管理系统以文件的形式保存数据库和表的数据。这些文件通常位于 MySQL 服务器的 data
目录下,而每个数据库通常对应一个文件夹,文件夹的名字就是数据库的名字。在这个文件夹内,每个表都会有与之对应的文件。
MySQL 支持多种存储引擎,每种存储引擎在物理存储层面上的实现方式会有所不同。 InnoDB 和 MyISAM 是 MySQL 中最常见的两种存储引擎。
MyISAM 存储引擎
对于 MyISAM 存储引擎来说,每个表在物理上会有三个文件:
*.frm
:这是表的结构定义文件,它存储了表的元数据,如列名、数据类型等。*.MYD
:这是数据文件,存储了表的实际数据。*.MYI
:这是索引文件,存储了表的索引信息,用于加快查询速度。InnoDB 存储引擎
对于 InnoDB 存储引擎来说,通常只有一个 *.frm 文件用于存储表的结构定义。
InnoDB 的数据和索引信息则存储在表空间中。表空间可以是单个文件,也可以是多个文件组成的文件组。
在 MySQL 的默认配置中,InnoDB 的表空间存储在名为 ibdata1 的文件中。这个文件还包含了其他的信息,如 undo 日志、系统更改日志等。
从 MySQL 5.6 开始,InnoDB 还支持将表空间和索引信息存储在单独的文件中,这被称为“文件表空间”(file-per-table)。在这种模式下,每个 InnoDB 表都会有一个与之对应的 .ibd 文件位于与 *.frm 文件相同的目录下,用于存储该表的数据和索引信息。
总结一下,对于InnoDB表:
无论是否启用“文件表空间”特性(file-per-table),ibdata1
文件都是InnoDB存储引擎的共享表空间文件,都会包含InnoDB的内部数据和元数据,如undo日志、系统更改日志等。而*.frm
文件始终用于存储表结构定义,并位于对应数据库的文件夹内
- 如果启用了文件表空间特性,
ibdata1
文件将只包含InnoDB的内部数据和元数据。而每个InnoDB表都将有一个独立的.ibd
文件来存储该表的数据和索引信息,.ibd
文件与*.frm
文件位于同一级目录下 - 如果未启用文件表空间特性,
ibdata1
文件除了包含内部数据和元数据外,还会包含所有InnoDB表的数据和索引信息。而每个InnoDB表仍然会有一个*.frm
文件用于存储表结构定义,但这个文件位于对应数据库的文件夹内,而不是与ibdata1
文件在同一级目录下
设置数据表字符集
MySQL 数据库管理系统支持多种字符集,这些字符集决定了如何存储和比较字符串数据。字符集的选择对于能够正确存储和检索各种语言(特别是非英语语言,如中文)的数据至关重要。
MySQL 的默认字符集是 Latin1,这是一个单字节字符集,主要支持西欧语言,并不完全支持中文字符。因此,在创建数据库、数据表或数据列时,通常需要显式地指定字符集以支持中文。
以下是如何设置 MySQL 数据库、数据表和数据列的字符集:
在创建数据库时,可以使用
CHARACTER SET
关键字来指定字符集。例如,要创建一个使用 UTF-8 字符集的数据库,可以使用以下 SQL 语句:CREATE DATABASE 数据库名 CHARACTER SET utf8;
--CHARACTER SET utf8 与 CHARSET=utf8 二者等效
--如果需要支持需要存储所有 Unicode 字符,应该使用 utf8mb4 而不是 utf8
在创建数据表时,也可以指定字符集。例如:
CREATE TABLE 表名 (
列名 数据类型,
...
) CHARACTER SET utf8;
此外,还可以为单个数据列指定字符集。这通常用于当表中的不同列需要使用不同的字符集时。例如:
CREATE TABLE 表名 (
列名1 数据类型 CHARACTER SET utf8,
列名2 数据类型 CHARACTER SET latin1,
...
);
除了通过 SQL 语句设置字符集外,还可以在 MySQL 的配置文件
my.ini
(或 my.cnf
,取决于操作系统和安装方式)中设置默认字符集。例如,可以设置 character-set-server
参数来指定服务器的默认字符集:[mysqld]
character-set-server=utf8
具体操作(Windows系统):
net stop mysql
[client]
default-character-set=utf8
[mysqld]
character-set-server=utf8
保存并关闭 my.ini 文件后,通过服务管理器或命令行来启动 MySQL 服务。例如,使用命令行执行以下命令:
net start mysql
这样,如果没有在创建数据库、数据表或数据列时显式地指定字符集,MySQL 将使用配置文件中指定的默认字符集。
总之,为了确保能够正确地存储和检索各种语言的数据,建议在创建数据库、数据表或数据列时显式地指定适当的字符集。如果未指定,MySQL 将使用配置文件或系统默认值,这可能会导致数据丢失或错误。
修改和删除数据表字段
SQL中 ALTER TABLE 命令可以用于在已经存在的表上进行各种修改,如添加、修改、重命名或删除字段,以及重命名表本身
--在表中添加一个新的字段
ALTER TABLE 表名 ADD 新字段 列属性
ALTER TABLE test ADD age INT(10) --在test表中添加了一个名为age的新字段,其数据类型为INT,并且最大长度为10
ALTER TABLE 表名 MODIFY 字段 列属性
ALTER TABLE test MODIFY age INT(1) --将test表中的age字段的数据类型修改为INT(1)
ALTER TABLE 表名 CHANGE 老字段名 新字段名 列属性
ALTER TABLE test CHANGE age age1 INT(10) --将test表中的age字段重命名为age1,并将其数据类型设置为INT(10)
ALTER TABLE 表名 DROP 字段名
ALTER TABLE test DROP age1 --从test表中删除了age1字段
ALTER TABLE 旧表名 RENAME AS 新表名
ALTER TABLE teacher RENAME AS teacher1 --将teacher表重命名为teacher1
DROP TABLE IF EXISTS 表名
DROP TABLE IF EXISTS student --检查数据库中是否存在名为student的表。如果存在,则删除student表
MySQL数据管理
外键(了解)
外键(Foreign Key)是关系型数据库中用于建立两个表之间联系的一种数据库约束。它用于确保引用完整性,即两个表之间的数据关联性和一致性。
概念
- 定义:在一个表中,如果有某个列(或列的组合)的值必须引用另一个表的主键值(或者是NULL,如果外键列允许NULL值),那么这个列(或列的组合)就被称为外键。
- 主表和从表:拥有主键的表通常被称为主表(Parent Table),而拥有外键的表被称为从表(子表)(Child Table 或 Foreign Table),从表中的外键列引用主表的主键列。
作用
理解
可以想象有两个表:一个是“学生”表,另一个是“课程”表。众多学生选修多门课程是一种多对多的关系,为了表示这种关系,可以创建一个“选课”表,其中包含学生ID和课程ID两个外键列。这两个外键列分别引用“学生”表的主键和“课程”表的主键。
通过这种方式,外键不仅保证了数据的完整性(例如,不会有一个不存在的学生ID或课程ID出现在“选课”表中),而且还建立了表之间的关联,使得我们可以轻松地查询某个学生选修了哪些课程,或者哪些学生选修了某一门课程。
使用外键示例
在创建表的时候,使用外键
-- 如果不存在名为`grade`的表,则创建该表
CREATE TABLE IF NOT EXISTS `grade` (
`gradeid` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '年级id', -- `gradeid`列,类型为INT(10) UNSIGNED,不允许为空,自动增长,并带有注释'年级id'
`gradename` VARCHAR(100) NOT NULL COMMENT '年级名称', -- `gradename`列,类型为VARCHAR(100),不允许为空,并带有注释'年级名称'
PRIMARY KEY(`gradeid`) -- 设置`gradeid`列为主键
) ENGINE=INNODB DEFAULT CHARSET=utf8; -- 设置表的存储引擎为InnoDB,字符集为utf8
-- 如果不存在名为`student`的表,则创建该表
CREATE TABLE IF NOT EXISTS `student` (
`id` INT(10) UNSIGNED NOT NULL AUTO_INCREMENT COMMENT '学号', -- `id`列,类型为INT(10) UNSIGNED,不允许为空,自动增长,并带有注释'学号'
`name` VARCHAR(200) NOT NULL COMMENT '姓名', -- `name`列,类型为VARCHAR(200),不允许为空,并带有注释'姓名'
`sex` ENUM('男', '女') NOT NULL COMMENT '性别', -- `sex`列,使用ENUM类型限制值为'男'或'女',不允许为空,并带有注释'性别'
`gradeid` INT(10) UNSIGNED NOT NULL COMMENT '学生的年级', -- `gradeid`列,类型为INT(10) UNSIGNED,不允许为空,并带有注释'学生的年级'
`pwd_hash` VARCHAR(255) NOT NULL COMMENT '密码哈希', -- `pwd_hash`列,类型为VARCHAR(255),不允许为空,用于存储密码哈希值,并带有注释'密码哈希'
`birthday` DATETIME DEFAULT NULL COMMENT '生日', -- `birthday`列,类型为DATETIME,允许为空,并带有注释'生日'
`address` VARCHAR(200) DEFAULT NULL COMMENT '家庭住址', -- `address`列,类型为VARCHAR(200),允许为空,并带有注释'家庭住址'
`email` VARCHAR(100) DEFAULT NULL COMMENT '邮箱', -- `email`列,类型为VARCHAR(100),允许为空,并带有注释'邮箱'
PRIMARY KEY(`id`), -- 设置`id`列为主键
KEY `FK_gradeid` (`gradeid`), -- 为`gradeid`列创建一个名为`FK_gradeid`的索引
CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade`(`gradeid`) -- 添加外键约束,`FK_gradeid`引用`grade`表的`gradeid`列
) ENGINE=INNODB DEFAULT CHARSET=utf8; -- 设置表的存储引擎为InnoDB,字符集为utf8
-- 创建年级表grade,包含gradeid(年级ID)和gradename(年级名称)两个字段
CREATE TABLE `grade`(
`gradeid` INT(10) NOT NULL AUTO_INCREMENT COMMENT '', -- gradeid字段,整数类型,不允许为空,自增,无注释内容
`gradename` VARCHAR(50) NOT NULL COMMENT '', -- gradename字段,字符串类型,最大长度50,不允许为空,无注释内容
PRIMARY KEY (`gradeid`) -- 设置gradeid字段为主键
)ENGINE=INNODB DEFAULT CHARSET=utf8; -- 使用InnoDB引擎,字符集为utf8
-- 创建学生表student,包含多个字段,并在最后添加了一个外键约束
CREATE TABLE IF NOT EXISTS `student`(
`id` INT(4) NOT NULL AUTO_INCREMENT COMMENT '学号', -- id字段,整数类型,不允许为空,自增,注释为“学号”
`name` VARCHAR(30) NOT NULL DEFAULT '匿名' COMMENT '姓名',-- name字段,字符串类型,最大长度30,不允许为空,默认值为“匿名”,注释为“姓名”
`pwd` VARCHAR(20) NOT NULL DEFAULT '123456' COMMENT '密码',-- pwd字段,字符串类型,最大长度20,不允许为空,默认值为“123456”,注释为“密码”
`sex` VARCHAR(2) NOT NULL DEFAULT '女' COMMENT '性别', -- sex字段,字符串类型,最大长度2,不允许为空,默认值为“女”,注释为“性别”
`birthday` DATETIME DEFAULT NULL COMMENT '出生日期', -- birthday字段,日期时间类型,允许为空,注释为“出生日期”
`gradeid` INT(10) NOT NULL COMMENT '学生的年级', -- gradeid字段,整数类型,不允许为空,注释为“学生的年级”
`address` VARCHAR(100) DEFAULT NULL COMMENT '家庭住址', -- address字段,字符串类型,最大长度100,允许为空,注释为“家庭住址”
`email` VARCHAR(50) DEFAULT NULL COMMENT '邮箱', -- email字段,字符串类型,最大长度50,允许为空,注释为“邮箱”
PRIMARY KEY(`id`) -- 设置id字段为主键
)ENGINE=INNODB DEFAULT CHARSET=utf8; -- 使用InnoDB引擎,字符集为utf8
-- 向student表添加外键约束,将gradeid字段作为外键,引用grade表的gradeid字段
ALTER TABLE `student` ADD CONSTRAINT `FK_gradeid` FOREIGN KEY (`gradeid`) REFERENCES `grade` (`gradeid`);
-- ALTER TABLE 从表名称 ADD CONSTRAINT 外键约束名 FOREIGN KEY (从表中作为外键的列名) REFERENCES 主表名 (主表的主键列名);
外键约束名:用于标识特定外键约束的名称,在创建或修改表结构时指定,这个名称通常遵循某种命名约定,以便能够清晰地表示该约束的用途和它所涉及的表和列。一般命名为 fk_主表名_从表名
删除有外键关系的表时,必须先删除从表,再删除主表
DML语言
管理数据库数据方法:
- 通过SQLyog等管理工具管理数据库数据
- 通过DML语句管理数据库数据
定义:SQL(结构化查询语言)的一个子集,用于管理数据库中的数据。DML语句允许用户查询、插入、更新和删除数据库中的数据。
- INSERT:用于向数据库表中插入新的数据行
- UPDATE:用于修改数据库表中的数据
- DELETE:用于从数据库表中删除数据
添加数据 insert
INSERT INTO
语句用于向数据库表中插入新的记录。这些记录由值组成,这些值对应于表中的列(字段)。
插入单个值
只需要为表中的特定列插入值时,可以指定列名。例如:
INSERT INTO 表名(列名) VALUES(插入值) --只指定了一个列名,因此只需要提供一个值
插入多个值
INSERT INTO 表名 (列名1, 列名2, 列名3,..., 列名n)
VALUES
(值11, 值12, 值13, ... , 值1n), -- 插入行1的值
(值21, 值22, 值23, ... , 值2n), -- 插入行2的值
(值31, 值32, 值33, ... , 值3n), -- 插入行3的值
...
(值n1, 值n2, 值n3, ... , 值nn); -- 插入行n的值
--值qp,q对应行,p对应列
省略列名
如果表中的所有列都需要值,并且提供的值的顺序与表中的列的顺序一致,则可以省略列名,并且为所有非自增列提供值。但是,如果表有自增的主键列(如ID),通常应该省略该列,以便数据库可以自动生成值。
INSERT INTO 表名 VALUES (值1, 值2, ... , 值n);
- 确保提供的值的数量、类型和顺序与表中的列相匹配(除非您明确指定了列名)
- 注意使用正确的引号来包围字符串值(通常是单引号)
修改数据
update命令
UPDATE
语句用于修改现有记录中的值,可以将新值设置为常量、变量、表达式(SET column_name = column_name * 2
)或嵌套的SELECT
查询的结果。
修改指定记录(id)的指定字段
UPDATE 表名 SET 列名=新值 WHERE id = n;
UPDATE `student` SET name=sk WHERE id = 1; --修改`student`表中id为1的记录的name字段,将其值设置为sk
修改所有记录的指定字段
UPDATE 表名 SET 列名=新值
UPDATE `student` SET `name`='长江7号'; --修改`student`表中所有记录的name字段,将其值设置为`长江7号`
修改满足多个条件的记录的指定字段
UPDATE 表名 SET 列名1=新值1 WHERE 列名1=现值1 AND 列名2=现值2 AND 列名3=现值3 AND ... AND 列名n=现值n;
UPDATE `student` SET `name`='长江7号' WHERE `name`='sk' AND sex='男'
--修改student表中 name字段的值是sk、sex字段的值是男 的记录的name字段,将其值设置为`长江7号`
修改多个字段,用逗号隔开 列名1=新值1,列名2=新值2,列名3=新值3, ... ,列名n=新值n
字段值设置为当前的时间 UPDATE 表名 SET 列名=CURRENT_TIME (WHERE...)
将新值设置为嵌套的 SELECT 查询的结果
UPDATE 要更新的表 SET 要更新的字段 = (SELECT 从中获取值的字段 FROM 从中检索数据的表 WHERE ... ) WHERE ... ;
where 条件子句
语法 | 含义 | 示例 |
---|---|---|
=,<>,!=,>,<,>=,<= | ||
between … and … | 在某个范围内 | [2,5] |
and | 添加多个且条件 | and sex = 男 |
or | 添加多个或条件 | or sex = 男 |
IN | 选择某一字段的多个记录 | WHERE country IN ('USA', 'Canada', 'Mexico');选择 country 为 'USA'、'Canada' 或 'Mexico' 的用户 |
LIKE | 模糊匹配 |
以上操作符可以组合使用