一、系统需求分析
图书管理系统是用于图书馆、学校或其他机构管理图书借阅、归还、库存等事务的软件系统。以下是对图书管理系统的需求分析,所以此系统至少应该包含以下功能:
功能需求:
1. 用户管理
- 用户注册:用户可以注册成为系统用户,包括读者、图书管理员等角色。
- 用户登录:已注册用户可以通过用户名和密码登录系统。
- 用户权限:不同角色具有不同权限,例如读者、图书管理员、系统管理员。
2. 图书管理
- 图书录入:管理员可以将新书信息录入系统,包括书名、作者、ISBN、出版日期、分类等。
- 图书查询:用户可以根据书名、作者、ISBN、分类等条件查询图书。
- 图书修改:管理员可以修改图书信息。
- 图书删除:管理员可以删除图书信息。
3. 借阅管理
- 借阅登记:读者可以在线申请借书,管理员进行借阅登记。
- 归还登记:读者归还图书时,管理员进行归还登记。
- 借阅历史:用户可以查询个人的借阅历史,管理员可以查询所有用户的借阅历史。
4. 书架管理
按照书的类别排放在书架上,以便用户迅速的找到要借的图书的位置
5. 预约管理
当图书馆里没有用户所要借阅的书,可以生成预约记录,在对应的书被归还到图书馆时,预约的用户有机会优先借阅
6.评分管理
阅读过图书的用户可以对相应的书评分,或者写下自己对这本书的感悟,以供其他需要阅读这本书的人参考
7.挂失管理
在读者不小心弄丢了图书馆的书籍或是一时找不到,可以通过挂失来延缓所借图书的最晚还书日期
8.罚款管理
若是用户所借的书籍持有时间超过了这本书的最大借出时长就可能面临图书馆的罚款处罚,对于丢书图书和逾期未还会有不同的处罚力度
二、功能设计
概念结构设计---E-R 图设计
用户表
属性名 | 含义 | 类别 |
readerid | 用户编号 | 主码 |
password | 密码 | |
readername | 用户名 | |
sex | 性别 | |
age | 年龄 | |
phone | 电话 |
图书表
属性名 | 含义 | 类别 |
bookid | 图书编号 | 主码 |
bookname | 图书名 | |
booknumber | 数量 | |
author | 作者 | |
bookstatues | 图书状态 | |
shelfid | 书架编号 | 外键 |
Pid | 出版社编号 | 外键 |
管理员表
属性名 | 含义 | 类别 |
Mid | 管理员编号 | 主码 |
Mpassword | 管理员密码 | |
Mname | 管理员姓名 | |
Msex | 性别 | |
Mphone | 电话 |
书架表
属性名 | 含义 | 类别 |
shelfid | 书架编号 | 主码 |
shelfkinds | 类别 | |
location | 位置 |
出版社表
属性名 | 含义 | 类别 |
Pid | 出版社id | 主码 |
bookid | 图书编号 | 外键 |
Pname | 出版社名称 | |
Pplace | 出版社地点 | |
phone | 联系方式 |
借阅表
属性名 | 含义 | 类别 |
readerid | 用户编号 | 外键 |
bookid | 图书编号 | 外键 |
borrowtime | 借阅时间 | |
returntime | 归还时间 | |
duetime | 应归还时间 |
挂失表
属性名 | 含义 | 类别 |
bookid | 图书号 | 外键 |
readerid | 用户编号 | 外键 |
losstime | 挂失时间 | |
canceltime | 取消挂失时间 |
预约表
属性名 | 含义 | 类别 |
readerid | 用户编号 | 外键 |
bookid | 图书编号 | 外键 |
appotime | 预约时间 | |
apponum | 预约人数 |
罚款表
属性名 | 含义 | 类别 |
readerid | 用户编号 | 外键 |
bookid | 图书编号 | 外键 |
cost | 罚款金额 | |
cause | 罚款原因 | |
days | 天数 |
评分表
属性名 | 含义 | 类别 |
readerid | 用户编号 | 外键 |
bookid | 图书编号 | 外键 |
point | 分数 |
视图的设计
视图名 | 作用 |
用户信息 | 用户查询个人信息的结果 |
管理员信息 | 图书管理员查询个人的结果 |
图书信息 | 用户或管理员查询图书的结果 |
用户借阅以及罚款信息 | 用户或管理员查询图书借阅以及相关罚款的结果 |
用户预约信息 | 用户或管理由安查询预约的结果 |
用户图书挂失信息 | 用户或管理员查询图书挂失的结果 |
用户对图书评分信息 | 用户或管理员查询图书评分的结果 |
用户信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
readerid | 用户编号 | user.readerid |
password | 密码 | user.password |
readername | 用户名 | user.readername |
sex | 性别 | user.sex |
age | 年龄 | |
phone | 电话 | user.phone |
管理员信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
Mid | 管理员编号 | admin.Mid |
Mpassword | 管理员密码 | admin.Mpassword |
Mname | 管理员姓名 | admin.Mname |
Msex | 性别 | admin.Msex |
Mphone | 电话 | admin.Mphone |
图书信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
bookid | 图书编号 | book.bookid |
bookname | 图书名 | book.bookname |
booknumber | 图书数量 | book.booknumber |
author | 图书作者 | book.author |
shelfid | 书架编号 | shelf.shelfid |
shelfkinds | 类别 | shelf.shelfkinds |
location | 位置 | shelf.location |
Pid | 出版社id | publisher.Pid |
Pname | 出版社名称 | publisher.Pname |
Pplace | 出版社地点 | publisher.Pplace |
phone | 出版社联系方式 | publisher.phone |
用户借阅以及罚款信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
readerid | 用户编号 | user.readerid |
readername | 用户名 | user.readername |
sex | 性别 | user.sex |
age | 年龄 | user.age |
phone | 电话 | user.phone |
borrowtime | 借阅时间 | borrow.borrowtime |
returntime | 归还时间 | borrow.returntime |
bookid | 图书编号 | book.bookid |
bookname | 图书名 | book.bookname |
author | 图书作者 | book.author |
用户预约信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
readerid | 用户编号 | user.readerid |
readername | 用户名 | user.readername |
sex | 性别 | user.sex |
age | 年龄 | user.age |
phone | 电话 | user.phone |
bookid | 图书编号 | book.bookid |
bookname | 图书名 | book.bookname |
author | 图书作者 | book.author |
appotime | 预约时间 | appointment.appotime |
apponum | 预约人数 | appointment.apponum |
用户挂失信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
readerid | 用户编号 | user.readerid |
readername | 用户名 | user.readername |
sex | 性别 | user.sex |
age | 年龄 | user.age |
phone | 电话 | user.phone |
bookid | 图书编号 | book.bookid |
bookname | 图书名 | book.bookname |
author | 图书作者 | book.author |
losstime | 挂失时间 | loss.losstime |
canceltime | 取消挂失时间 | loss.canceltime |
用户评分信息视图
字段名称 | 说明 | 所来自的基本表的字段 |
readerid | 用户编号 | user.readerid |
readername | 用户名 | user.readername |
sex | 性别 | user.sex |
age | 年龄 | user.age |
phone | 电话 | user.phone |
bookid | 图书编号 | book.bookid |
bookname | 图书名 | book.bookname |
author | 图书作者 | book.author |
point | 分数 | rating.point |
三、功能实现
数据库设计
CREATE DATABASE Book;
use Book;
-- 用户表
CREATE TABLE Users (
readerid INT PRIMARY KEY,
password VARCHAR(255),
readername VARCHAR(255),
sex VARCHAR(10),
age INT,
phone VARCHAR(20),
UNIQUE (readername) -- 确保用户名唯一
);
-- 管理员表
CREATE TABLE Managers (
Mid INT PRIMARY KEY,
Mpassword VARCHAR(255),
Mname VARCHAR(255),
Msex VARCHAR(10),
Mphone VARCHAR(20)
);
-- 书架表
CREATE TABLE Shelves (
shelfid INT PRIMARY KEY,
shelfkinds VARCHAR(255),
location VARCHAR(255)
);
-- 出版社表
CREATE TABLE Publishers (
Pid INT PRIMARY KEY,
Pname VARCHAR(255),
Pplace VARCHAR(255),
phone VARCHAR(20)
);
-- 图书表
CREATE TABLE Books (
bookid INT PRIMARY KEY,
bookname VARCHAR(255),
booknumber INT,
author VARCHAR(255),
shelfid INT,
Pid INT,
FOREIGN KEY (shelfid) REFERENCES Shelves(shelfid),
FOREIGN KEY (Pid) REFERENCES Publishers(Pid),
CHECK (booknumber >= 0) -- 确保书籍数量不为负数
);
ALTER TABLE Books
ADD COLUMN bookstatus VARCHAR(20);
-- 归还表
CREATE TABLE Returns (
returnid INT AUTO_INCREMENT PRIMARY KEY,
bookid INT,
returndate DATE,
FOREIGN KEY (bookid) REFERENCES Books(bookid)
);
-- 借阅表
CREATE TABLE Borrowings (
readerid INT,
bookid INT,
borrowtime TIMESTAMP,
returntime TIMESTAMP,
PRIMARY KEY (readerid, bookid), -- 联合主键
FOREIGN KEY (readerid) REFERENCES Users(readerid),
FOREIGN KEY (bookid) REFERENCES Books(bookid),
CHECK (borrowtime < returntime) -- 确保借阅时间早于归还时间
);
ALTER TABLE Borrowings
ADD COLUMN duetimes TIMESTAMP;
-- 挂失表
CREATE TABLE Losses (
bookid INT,
readerid INT,
losstime TIMESTAMP,
canceltime TIMESTAMP,
PRIMARY KEY (bookid, readerid), -- 联合主键
FOREIGN KEY (bookid) REFERENCES Books(bookid),
FOREIGN KEY (readerid) REFERENCES Users(readerid),
CHECK (losstime < canceltime) -- 确保挂失时间早于取消挂失时间
);
-- 预约表
CREATE TABLE Appointments (
readerid INT,
bookid INT,
appotime TIMESTAMP,
apponum INT,
PRIMARY KEY (readerid, bookid), -- 联合主键
FOREIGN KEY (readerid) REFERENCES Users(readerid),
FOREIGN KEY (bookid) REFERENCES Books(bookid),
CHECK (apponum > 0) -- 确保预约人数大于0
);
-- 罚款表
CREATE TABLE Fines (
readerid INT,
bookid INT,
cost DECIMAL(10,2),
cause VARCHAR(255),
PRIMARY KEY (readerid, bookid), -- 联合主键
FOREIGN KEY (readerid) REFERENCES Users(readerid),
FOREIGN KEY (bookid) REFERENCES Books(bookid),
CHECK (cost >= 0) -- 确保罚款金额不为负数
);
ALTER TABLE Fines
ADD COLUMN days INT;
-- 评分表
CREATE TABLE Ratings (
readerid INT,
bookid INT,
point DECIMAL(3,1),
PRIMARY KEY (readerid, bookid), -- 联合主键
FOREIGN KEY (readerid) REFERENCES Users(readerid),
FOREIGN KEY (bookid) REFERENCES Books(bookid),
CHECK (point >= 0 AND point <= 10) -- 确保评分在0到10之间
);
-- 创建借书触发器
CREATE TRIGGER after_borrow_insert
AFTER INSERT ON Borrowings
FOR EACH ROW
BEGIN
DECLARE current_quantity INT;
-- 获取当前图书数量
SELECT booknumber INTO current_quantity
FROM Books
WHERE bookid = NEW.bookid;
-- 如果图书数量大于 0,则减少数量
IF current_quantity > 0 THEN
-- 减少图书表中对应图书的数量
UPDATE Books
SET quantity = quantity - 1
WHERE bookid = NEW.bookid;
ELSE
-- 记录日志或采取其他适当的处理措施
-- 这里可以记录日志或向管理员发出警告等
INSERT INTO Log (message) VALUES ('Book quantity already at minimum for bookid: ' + NEW.bookid);
END IF;
END;
-- 创建还书触发器
CREATE TRIGGER update_book_quantity
AFTER INSERT ON Returns
FOR EACH ROW
BEGIN
DECLARE returned_book_id INT;
DECLARE returned_book_quantity INT;
-- 获取归还的图书编号
SET returneid = NEW.bookid;
-- 获取归还的图书数量
SELECT booknumber INTO returned_book_quantity
FROM Books
WHERE bookid = returned_book_id;
-- 更新图书表中对应图书的数量
UPDATE Books
SET booknumber = booknumber + 1 -- 假设每次只归还一本书
WHERE bookid = returned_book_id;
END;
-- 创建状态触发器
CREATE TRIGGER after_borrow_insert
AFTER INSERT ON Borrowings
FOR EACH ROW
BEGIN
DECLARE book_count INT;
-- 查询对应图书的数量
SELECT booknumber INTO book_count
FROM Books
WHERE bookid = NEW.bookid;
-- 如果图书数量小于等于 0,则将图书状态设置为不可借
IF book_count <= 0 THEN
UPDATE Books
SET bookstatus = '不可借'
WHERE bookid = NEW.bookid;
END IF;
END;
-- 创建触发器
CREATE TRIGGER after_return_insert
AFTER INSERT ON Returns
FOR EACH ROW
BEGIN
DECLARE book_count INT;
-- 查询对应图书的数量
SELECT booknumber INTO book_count
FROM Books
WHERE bookid = NEW.bookid;
-- 如果图书数量大于 0,则将图书状态设置为可借
IF book_count > 0 THEN
UPDATE Books
SET bookstatus = '可借'
WHERE bookid = NEW.bookid;
END IF;
END;
-- 创建挂失触发器
CREATE TRIGGER handle_book_loss
AFTER INSERT ON Losses
FOR EACH ROW
BEGIN
DECLARE lost_book_id INT;
DECLARE lost_book_status VARCHAR(50);
DECLARE lost_book_comment VARCHAR(255);
-- 获取丢失的图书编号
SET lost_book_id = NEW.bookid;
-- 获取丢失的图书状态
SELECT bookstatus INTO lost_book_status
FROM Books
WHERE bookid = lost_book_id;
-- 更新图书表中对应图书的状态为挂失
UPDATE Books
SET bookstatus = '挂失'
WHERE bookid = lost_book_id;
END;
-- 创建预约触发器
CREATE TRIGGER handle_book_reservation
AFTER INSERT ON Appointments
FOR EACH ROW
BEGIN
DECLARE reserved_book_id INT;
DECLARE book_number INT;
-- 获取预约的图书编号
SET reserved_book_id = NEW.bookid;
-- 检查图书的可用性
SELECT booknumber INTO book_number
FROM Books
WHERE bookid = reserved_book_id;
-- 如果图书可用,则更新图书表中对应图书的可用性
IF book_number > 0 THEN
UPDATE Books
SET booknumber = booknumber - 1
WHERE bookid = reserved_book_id;
END IF;
END;
-- 建立罚款触发器
CREATE TRIGGER handle_late_return
AFTER UPDATE ON Borrowings
FOR EACH ROW
BEGIN
DECLARE return_date DATE;
DECLARE due_date DATE;
DECLARE fine_amount DECIMAL(10, 2);
-- 获取归还日期和应归还日期
SELECT returntime, deutime INTO return_date, due_date
FROM Borrowings
WHERE bookid = NEW.bookid;
-- 计算罚款金额(如果超过应归还日期)
IF return_date > due_date THEN
-- 计算逾期天数
DECLARE days_late INT;
SET days_late = DATEDIFF(return_date, due_date);
-- 每天的罚款金额(每天 0.50 元)
DECLARE fine_per_day DECIMAL(10, 2);
SET fine_per_day = 0.50;
-- 计算罚款金额
SET fine_amount = days_late * fine_per_day;
-- 更新罚款表
INSERT INTO Fines (readerid, days, cost, bookid)
VALUES (NEW.readerid, days_late, fine_amount, NEW.bookid);
END IF;
END;
-- 创建评分触发器
CREATE TRIGGER handle_book_rating
AFTER INSERT ON Ratings
FOR EACH ROW
BEGIN
DECLARE book_id INT;
DECLARE rating_count INT;
DECLARE total_rating INT;
DECLARE new_rating INT;
-- 获取评分的图书编号和评分值
SET book_id = NEW.bookid;
SET new_rating = NEW.point;
-- 获取图书当前的评分总分和评分次数
SELECT COUNT(*), SUM(point)
INTO rating_count, total_rating
FROM Ratings
WHERE bookid = NEW.bookid;
-- 如果该图书已有评分记录,则更新评分
IF point > 0 THEN
SET total_rating = total_rating + new_rating;
SET new_rating = total_rating / (rating_count + 1);
END IF;
-- 更新评分表中的相应记录
UPDATE 评分表
SET point = new_rating
WHERE bookid = NEW.bookid;
END;