【数据库基础|第1篇】数据库、表、字段、主键、外键一次讲清楚

前言

前面我们已经写完了 Spring Boot + MyBatis 知识点系列,里面经常会出现 Mapper、SQL、表字段、主键 id、关联查询这些内容。

但是如果数据库基础不牢,写项目的时候就很容易出现一些问题。

比如:

  • 实体类字段和数据库字段对不上
  • 不知道为什么每张表都要有 id
  • 不知道主键和普通字段有什么区别
  • 不知道两张表为什么要通过某个字段关联
  • 写多表查询时,不理解表和表之间的关系

所以从这一篇开始,我们进入第二个系列:数据库基础知识系列。

这一篇先不急着写复杂 SQL,而是先把数据库中最基础的几个概念讲清楚:数据库、表、字段、记录、主键、外键。

这些内容看起来简单,但是后面学习 MySQL、MyBatis、多表查询、索引、事务时都会用到。

一、数据库是什么?

数据库可以理解为一个专门用来存储数据的仓库。

比如我们做一个员工管理系统,系统中会有很多数据:

  • 员工信息
  • 部门信息
  • 班级信息
  • 学员信息
  • 登录用户信息
  • 操作日志信息

这些数据不能只放在 Java 对象里,因为程序一关闭,内存中的数据就没了。

所以我们需要把数据保存到数据库中。

常见数据库有:

数据库 说明
MySQL Java 后端学习和企业开发中非常常用
Oracle 大型企业系统中常见
SQL Server 微软体系中常见
PostgreSQL 功能强大的开源数据库
Redis 常用于缓存,不是传统关系型数据库

我们这一系列主要学习的是 MySQL。

二、数据库和表的关系

可以把数据库理解成一个文件夹,把表理解成文件夹中的 Excel 表格。

比如我们创建一个项目数据库:

sql 复制代码
create database tlias;

这个 tlias 就是一个数据库。

在这个数据库中,可以有很多张表:

text 复制代码
tlias 数据库
  ├── emp 员工表
  ├── dept 部门表
  ├── clazz 班级表
  ├── student 学员表
  └── operate_log 操作日志表

每张表专门保存一类数据。

比如:

  • emp 表保存员工信息
  • dept 表保存部门信息
  • student 表保存学员信息
  • operate_log 表保存操作日志

也就是说:

数据库负责管理多张表,表负责存储某一类具体数据。

三、表是什么?

表是数据库中真正保存数据的结构。

比如员工表 emp 可以设计成这样:

id username name gender phone
1 zhangsan 张三 1 13800000000
2 lisi 李四 1 13900000000
3 wangwu 王五 2 13700000000

这张表中,每一列表示一个字段,每一行表示一条记录。

可以简单理解为:

text 复制代码
一张表 = 一类数据
一列 = 一个字段
一行 = 一条记录

四、字段是什么?

字段就是表中的一列,用来描述数据的某个属性。

比如员工表中有这些字段:

text 复制代码
id
username
name
gender
phone

它们分别表示:

字段名 含义
id 员工编号
username 用户名
name 姓名
gender 性别
phone 手机号

在 Java 中,我们通常会写一个实体类和数据库表对应。

比如数据库表是:

sql 复制代码
create table emp (
    id int primary key auto_increment,
    username varchar(20),
    name varchar(10),
    gender tinyint,
    phone varchar(11)
);

Java 实体类可以这样写:

java 复制代码
public class Emp {
    private Integer id;
    private String username;
    private String name;
    private Integer gender;
    private String phone;

    // getter、setter 省略
}

可以看到,数据库字段和 Java 属性基本是一一对应的。

五、记录是什么?

记录就是表中的一行数据。

比如员工表中这一行:

id username name gender phone
1 zhangsan 张三 1 13800000000

这就是一条员工记录。

对应到 Java 中,可以封装成一个 Emp 对象:

java 复制代码
Emp emp = new Emp();
emp.setId(1);
emp.setUsername("zhangsan");
emp.setName("张三");
emp.setGender(1);
emp.setPhone("13800000000");

所以我们在 MyBatis 中查询数据库时,经常会看到:

java 复制代码
@Select("select id, username, name, gender, phone from emp where id = #{id}")
Emp getById(Integer id);

这句 SQL 查询出来的是数据库中的一条记录,然后 MyBatis 会把这条记录封装成一个 Emp 对象。

六、主键是什么?

主键是表中用来唯一标识一条记录的字段。

最常见的主键就是 id

比如员工表中:

id username name
1 zhangsan 张三
2 lisi 李四
3 wangwu 王五

这里的 id 就是主键。

每个员工都有自己的 id,不能重复。

创建表时可以这样写:

sql 复制代码
create table emp (
    id int unsigned primary key auto_increment comment '员工ID',
    username varchar(20) comment '用户名',
    name varchar(10) comment '姓名'
);

这里:

sql 复制代码
primary key

表示主键。

sql 复制代码
auto_increment

表示自动递增。

也就是说,我们新增员工时不用手动指定 id,数据库会自动生成。

比如:

sql 复制代码
insert into emp(username, name) values('zhangsan', '张三');
insert into emp(username, name) values('lisi', '李四');

数据库可能会自动生成:

id username name
1 zhangsan 张三
2 lisi 李四

七、为什么每张表都建议有主键?

主键非常重要,原因主要有三个。

1. 唯一标识数据

如果没有主键,数据库很难准确区分两条看起来相似的数据。

比如:

name gender phone
张三 1 13800000000
张三 1 13800000000

这两条数据完全一样时,如果没有 id,就很难区分到底是哪一条。

有了主键后:

id name gender phone
1 张三 1 13800000000
2 张三 1 13800000000

即使其他字段一样,也可以通过 id 区分。

2. 方便查询、修改和删除

项目中经常会根据 id 操作数据。

比如根据 id 查询员工:

sql 复制代码
select * from emp where id = 1;

根据 id 修改员工:

sql 复制代码
update emp set name = '张三丰' where id = 1;

根据 id 删除员工:

sql 复制代码
delete from emp where id = 1;

这也是为什么我们在 Spring Boot 项目中经常写:

java 复制代码
@GetMapping("/{id}")
public Result getById(@PathVariable Integer id) {
    Emp emp = empService.getById(id);
    return Result.success(emp);
}

这里的 id 本质上就是数据库表中的主键。

3. 方便建立表关系

两张表之间建立关系时,也经常会用到主键。

比如员工属于某个部门。

部门表 dept

id name
1 学工部
2 教研部

员工表 emp

id name dept_id
1 张三 1
2 李四 2

这里 emp.dept_id 保存的是部门表中的 dept.id

这样就可以知道:

text 复制代码
张三属于学工部
李四属于教研部

八、外键是什么?

外键是用来建立两张表之间关系的字段。

比如部门表:

sql 复制代码
create table dept (
    id int unsigned primary key auto_increment,
    name varchar(20)
);

员工表:

sql 复制代码
create table emp (
    id int unsigned primary key auto_increment,
    name varchar(10),
    dept_id int unsigned
);

这里的 dept_id 就可以理解为员工表中的外键字段。

它指向部门表的 id

关系如下:

text 复制代码
emp.dept_id  ->  dept.id

也就是说:

员工表中的 dept_id 用来表示这个员工属于哪个部门。

九、要不要真的添加外键约束?

在数据库中,可以真正添加外键约束:

sql 复制代码
alter table emp
add constraint fk_emp_dept_id
foreign key (dept_id) references dept(id);

这样数据库会帮我们保证:

text 复制代码
emp.dept_id 必须是 dept 表中真实存在的 id

比如部门表中没有 id 为 10 的部门,那么员工表中就不能插入 dept_id = 10 的数据。

但是在很多 Java 后端项目中,实际开发时不一定会在数据库层面添加外键约束,而是通过业务代码控制数据关系。

原因是:

  • 外键约束会让删除、修改数据时更严格
  • 大项目中表关系复杂,外键维护成本较高
  • 有些项目更倾向于在业务层保证数据一致性

所以初学阶段需要先理解外键思想:

一个表中的字段,保存另一个表的主键 id,用来建立两张表之间的关系。

至于是否真的添加数据库外键约束,要看项目规范。

十、数据库表和 Java 项目的关系

学习数据库不是孤立的,它和 Java 后端项目是直接关联的。

比如在 Spring Boot + MyBatis 项目中,常见关系是:

数据库 Java 项目
实体类
字段 属性
一条记录 一个对象
多条记录 List 集合
主键 id 根据 id 查询、修改、删除
外键字段 多表关联查询

比如数据库表:

sql 复制代码
select id, username, name, gender, phone from emp;

查询出来多条记录后,在 Java 中通常就是:

java 复制代码
List<Emp> empList = empMapper.list();

如果查询一条记录:

sql 复制代码
select id, username, name, gender, phone from emp where id = 1;

在 Java 中通常就是:

java 复制代码
Emp emp = empMapper.getById(1);

所以理解数据库结构之后,再看 Mapper 层代码就会清楚很多。

十一、常见问题总结

1. 数据库和表有什么区别?

数据库可以包含多张表。

表是真正保存数据的地方。

比如 tlias 是数据库,empdeptstudent 是数据库中的表。

2. 字段和记录有什么区别?

字段是表中的列,记录是表中的行。

比如 name 是字段,张三 这一整行数据是一条记录。

3. 主键一定要叫 id 吗?

不一定。

主键可以叫 id,也可以叫 emp_iduser_id

但是在学习项目和很多企业项目中,最常见的主键字段名就是 id

4. 主键可以重复吗?

不可以。

主键的作用就是唯一标识一条数据,所以不能重复,也不能随便为空。

5. 外键一定要加数据库约束吗?

不一定。

外键思想很重要,但是否添加数据库外键约束,要看项目规范。

很多项目会保留外键字段,但不一定真的添加外键约束。

十二、总结

这一篇主要学习了数据库中最基础的几个概念:数据库、表、字段、记录、主键、外键。

数据库可以理解成存储数据的仓库,表是数据库中真正保存数据的结构。表中的一列叫字段,一行叫记录。

主键用来唯一标识一条数据,最常见的主键就是 id。外键用来建立两张表之间的关系,比如员工表中的 dept_id 可以关联部门表中的 id

这些概念是后面学习 SQL、MyBatis、多表查询、索引和事务的基础。尤其是在写 Java 后端项目时,数据库表结构和实体类、Mapper 查询、接口参数都会联系在一起。

下一篇我们继续学习 MySQL 中常见的数据类型,看看 intvarchardatetimedecimal 到底应该怎么选。