需要哪些核心表才能支撑借阅流程
电子图书馆系统最基础的运转依赖四张表:读者、图书、借阅记录、分类。少于这个数量容易导致业务逻辑被迫写进代码,比如把“是否已还”硬编码成数字 0/1;多于这个数量(比如拆出出版社、作者独立成表)在简单场景下反而增加 JOIN 成本和维护负担。
关键设计原则是:先让
借阅表能准确记录一次动作——谁、哪本书、何时借、何时还。其他字段都是为它服务的。
reader表必须有唯一标识
reader_id(建议用自增整数),不要用身份证号作主键,涉及隐私且校验逻辑复杂
book表的
isbn字段建议设为
UNIQUE,但允许为空(部分老书无 ISBN)
borrow表中
return_date允许为
NULL,表示尚未归还;查询“当前未还”就靠
WHERE return_date IS NULL
如何定义 borrow 表的外键与时间字段
外键不是可选项,而是数据一致性的底线。没加外键时,可能出现
borrow表里存了个根本不存在的
book_id,后续统计藏书量或借阅频次全错。
时间字段别只用
DATETIME。MySQL 5.6.5+ 支持带默认值的
TIMESTAMP,更省心:
CREATE TABLE borrow ( borrow_id INT PRIMARY KEY AUTO_INCREMENT, reader_id INT NOT NULL, book_id INT NOT NULL, borrow_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, return_date TIMESTAMP NULL, FOREIGN KEY (reader_id) REFERENCES reader(reader_id) ON DELETE CASCADE, FOREIGN KEY (book_id) REFERENCES book(book_id) ON DELETE RESTRICT );
注意:
ON DELETE CASCADE表示删读者时自动清空其所有借阅记录;
ON DELETE RESTRICT表示禁止删除正在被借的图书——这是防止误操作的关键约束。
分类表要不要支持多级分类
简单系统里,“一级分类”足够用。强行做父子结构(如
category(parent_id))会逼你在每次查某类图书时写递归查询或多次 JOIN,而实际使用中管理员基本只在后台选一个下拉框填分类名。
推荐方案:用单字段 + 枚举式管理:
CREATE TABLE category (
category_id TINYINT PRIMARY KEY AUTO_INCREMENT,
name VARCHAR(20) NOT NULL UNIQUE
);
<p>-- 插入示例
INSERT INTO category (name) VALUES ('文学'), ('计算机'), ('历史'), ('少儿');然后在
book表里加
category_id TINYINT外键。别用字符串存“计算机/网络”这种路径,搜索和索引都变慢。
容易被忽略的索引和字符集问题
上线后一查“某读者所有借阅”,响应从 200ms 涨到 3s,大概率是忘了给
borrow.reader_id加索引。InnoDB 的外键列不会自动建索引,必须手动补: 在
borrow表上建复合索引:
INDEX idx_reader_borrow (reader_id, borrow_date),方便按人查最近借了什么
book表的
title字段如果要模糊搜索(如
LIKE '%Python%'),得用
utf8mb4_unicode_ci排序规则,否则中文检索不准 所有
VARCHAR字段别盲目设 255 ——
reader.name设 50 足够,节省页内空间,间接提升缓存命中率
字符集统一用
utf8mb4,哪怕现在只录中文。某天想加个 emoji 书评,或者用户昵称带 ?,不改表结构就能撑住。
