图书管理系统是MySQL实战中非常典型的应用场景,完整的系统需要覆盖图书信息管理、读者信息管理、图书借阅与归还等核心功能,对应的数据库设计需要支撑这些业务场景的正常运行。

一、需求分析与核心实体梳理
在设计数据库之前,先明确系统需要管理的核心对象和业务流程:
- 图书:需要记录图书的基本信息,包括书名、作者、出版社、库存数量等
- 读者:需要记录读者的基本信息,包括姓名、联系方式、可借数量等
- 借阅记录:需要记录每一次图书借还的详细信息,包括借阅时间、应还时间、实际归还时间等
二、核心数据表设计
1. 图书信息表 book
该表用于存储所有图书的基础信息,设计字段如下:
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| book_id | INT | 主键、自增 | 图书唯一标识 |
| book_name | VARCHAR(100) | 非空 | 图书名称 |
| author | VARCHAR(50) | 非空 | 作者 |
| press | VARCHAR(50) | 可空 | 出版社 |
| total_num | INT | 默认1 | 图书总数量 |
| remain_num | INT | 默认1 | 剩余可借数量 |
| create_time | DATETIME | 默认当前时间 | 入库时间 |
2. 读者信息表 reader
该表用于存储读者的基础信息,设计字段如下:
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| reader_id | INT | 主键、自增 | 读者唯一标识 |
| reader_name | VARCHAR(50) | 非空 | 读者姓名 |
| phone | VARCHAR(20) | 唯一 | 联系电话 |
| max_borrow | INT | 默认5 | 最大可借数量 |
| borrowed_num | INT | 默认0 | 已借数量 |
| register_time | DATETIME | 默认当前时间 | 注册时间 |
3. 借阅记录表 borrow_record
该表用于记录每一次图书借阅和归还的操作记录,设计字段如下:
| 字段名 | 类型 | 约束 | 说明 |
|---|---|---|---|
| record_id | INT | 主键、自增 | 记录唯一标识 |
| book_id | INT | 外键关联book表 | 借阅的图书ID |
| reader_id | INT | 外键关联reader表 | 借阅的读者ID |
| borrow_time | DATETIME | 非空 | 借阅时间 |
| due_time | DATETIME | 非空 | 应还时间 |
| return_time | DATETIME | 可空 | 实际归还时间,未归还时为NULL |
| status | TINYINT | 默认1 | 状态:1未归还,0已归还 |
三、建表SQL语句示例
以下是创建上述三张表的完整SQL代码:
-- 创建图书信息表
CREATE TABLE IF NOT EXISTS book (
book_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '图书ID',
book_name VARCHAR(100) NOT NULL COMMENT '图书名称',
author VARCHAR(50) NOT NULL COMMENT '作者',
press VARCHAR(50) COMMENT '出版社',
total_num INT DEFAULT 1 COMMENT '总数量',
remain_num INT DEFAULT 1 COMMENT '剩余可借数量',
create_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '入库时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='图书信息表';
-- 创建读者信息表
CREATE TABLE IF NOT EXISTS reader (
reader_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '读者ID',
reader_name VARCHAR(50) NOT NULL COMMENT '读者姓名',
phone VARCHAR(20) UNIQUE COMMENT '联系电话',
max_borrow INT DEFAULT 5 COMMENT '最大可借数量',
borrowed_num INT DEFAULT 0 COMMENT '已借数量',
register_time DATETIME DEFAULT CURRENT_TIMESTAMP COMMENT '注册时间'
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='读者信息表';
-- 创建借阅记录表
CREATE TABLE IF NOT EXISTS borrow_record (
record_id INT PRIMARY KEY AUTO_INCREMENT COMMENT '记录ID',
book_id INT NOT NULL COMMENT '图书ID',
reader_id INT NOT NULL COMMENT '读者ID',
borrow_time DATETIME NOT NULL COMMENT '借阅时间',
due_time DATETIME NOT NULL COMMENT '应还时间',
return_time DATETIME COMMENT '归还时间',
status TINYINT DEFAULT 1 COMMENT '状态:1未归还,0已归还',
FOREIGN KEY (book_id) REFERENCES book(book_id),
FOREIGN KEY (reader_id) REFERENCES reader(reader_id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COMMENT='借阅记录表';
四、核心业务SQL实现
1. 图书借阅操作
借阅图书需要同时完成三个操作:减少图书剩余可借数量、增加读者已借数量、新增借阅记录,建议使用事务保证操作一致性:
-- 开启事务 START TRANSACTION; -- 更新图书剩余数量 UPDATE book SET remain_num = remain_num - 1 WHERE book_id = 1 AND remain_num > 0; -- 更新读者已借数量 UPDATE reader SET borrowed_num = borrowed_num + 1 WHERE reader_id = 1 AND borrowed_num < max_borrow; -- 新增借阅记录,假设借阅周期为30天 INSERT INTO borrow_record (book_id, reader_id, borrow_time, due_time) VALUES (1, 1, NOW(), DATE_ADD(NOW(), INTERVAL 30 DAY)); -- 提交事务 COMMIT;
2. 图书归还操作
归还图书需要更新借阅记录状态、恢复图书剩余数量、减少读者已借数量:
START TRANSACTION; -- 更新借阅记录状态 UPDATE borrow_record SET return_time = NOW(), status = 0 WHERE record_id = 1 AND status = 1; -- 恢复图书剩余数量 UPDATE book SET remain_num = remain_num + 1 WHERE book_id = 1; -- 减少读者已借数量 UPDATE reader SET borrowed_num = borrowed_num - 1 WHERE reader_id = 1; COMMIT;
3. 查询当前未归还的借阅记录
可以通过关联三张表查询详细的未归还记录:
SELECT
r.reader_name,
b.book_name,
br.borrow_time,
br.due_time
FROM borrow_record br
JOIN reader r ON br.reader_id = r.reader_id
JOIN book b ON br.book_id = b.book_id
WHERE br.status = 1
ORDER BY br.due_time ASC;
五、设计注意事项
在实际项目设计中还需要注意以下几点:
- 外键约束可以保证数据一致性,但如果系统并发量较高,也可以考虑在应用层做数据校验,避免外键带来的性能开销
- 图书的
remain_num字段需要和total_num做逻辑校验,避免出现剩余数量大于总数量的情况 - 借阅记录表建议定期归档历史数据,避免单表数据量过大影响查询性能
- 可以给
borrow_record表的book_id和reader_id字段添加普通索引,提升关联查询的效率
以上设计是图书管理系统的基础版本,实际项目中可以根据需求扩展更多功能,比如图书分类管理、逾期罚款计算、读者权限分级等,对应的数据库表也可以按需增加字段或新增关联表。