文章目录
实验一:图书借阅管理系统设计与实现
原题
依据《图书借阅管理系统》的概念模型,运用数据库系统原理知识进行逻辑设计,并通过SQL命令完成数据库和表创建,对表进行数据的增加、修改、删除和查询操作,施加必要的完整性约束和访问控制,编写存储过程、存储函数和触发器(视需要)。
《图书借阅管理系统》的实体关系如图1-1:
图1-1 图书借阅管理系统E-R图
1.运用SQL命令创建数据表
请依据《图书借阅管理系统》的实体关系,完成数据模型的逻辑设计,并在数据库管理系统完成物理设计:
(1)图书表:T_book
(2)借书表:T_borrow
(3)借书卡表:T_card
2.创建完整性约束关系(含实体完整性、参照完整性和用户自定义完整性)
例:(1)根据物理数据模型,创建数据表间关系。且均为“级联”关系方式。
l T_borrow与T_book的外键约束名为fk_borrow_book。
l T_borrow与T_card的外键约束名为fk_borrow_card
(2)图书信息表中的字段库存册数的默认值为20。
(3)借书卡表T_card中的字段手机号码必须为11位数字组成。(约束名为:t_card_chk_1)。
3.运用SQL命令向数据表中插入数据
向数据表中插入模拟数据(插入的数据内容可行自定义,但需要考虑表间的完整性约束)。
4.运用SQL命令修改数据表中的数据值
例:(1)修改某一图书信息的【单价】。
(2)修改某一借书信息的【还书日期】。
5.运用SQL命令查询数据
例:(1)查询出库存数量小于2册的图书信息。
(2)查询没有还书的借书人的卡号、姓名、所借书名、借书日期。
6.编写存储过程
例:编写存储过程prc_CountBorrow,用于显示某一图书的借阅次数。
7.数据库应用开发
运用PHP脚本语言设计、开发一套《图书借阅管理系统》,实现对数据的增、删、改、查、排序、权限管理以及报表等功能。
一、数据库设计
1. 数据表结构
T_book(图书表)
-
主键:
book_id
-
字段:
CREATE TABLE T_book ( book_id INT AUTO_INCREMENT PRIMARY KEY, title VARCHAR(100) NOT NULL, author VARCHAR(50), price DECIMAL(10,2), stock INT DEFAULT 20, -- 默认库存20 CONSTRAINT chk_stock CHECK (stock >= 0) );
T_card(借书卡表)
-
主键:
card_id
-
字段:
CREATE TABLE T_card ( card_id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(50) NOT NULL, phone CHAR(11), -- 固定11位 reg_date DATE, CONSTRAINT t_card_chk_1 CHECK (phone REGEXP '^[0-9]{11}$') );
T_borrow(借书表)
-
主键:
borrow_id
-
外键约束:
CREATE TABLE T_borrow ( borrow_id INT AUTO_INCREMENT PRIMARY KEY, book_id INT, card_id INT, borrow_date DATE NOT NULL, return_date DATE, CONSTRAINT fk_borrow_book FOREIGN KEY (book_id) REFERENCES T_book(book_id) ON DELETE CASCADE ON UPDATE CASCADE, CONSTRAINT fk_borrow_card FOREIGN KEY (card_id) REFERENCES T_card(card_id) ON DELETE CASCADE ON UPDATE CASCADE );
二、完整性约束实现
- 外键级联关系
- 已在表创建时通过
ON DELETE CASCADE
和ON UPDATE CASCADE
实现。
- 已在表创建时通过
- 库存默认值
stock INT DEFAULT 20
。
- 手机号11位约束
- 使用
CHECK
约束结合正则表达式:phone REGEXP '^[0-9]{11}$'
。
- 使用
三、数据操快速实现作示例
1. 插入数据
-- 先插入T_card和T_book
INSERT INTO T_card (name, phone, reg_date)
VALUES ('张三', '13812345678', '2023-10-01');
INSERT INTO T_book (title, author, price)
VALUES ('数据库系统概论', '王珊', 59.99);
-- 再插入T_borrow
INSERT INTO T_borrow (book_id, card_id, borrow_date)
VALUES (1, 1, '2023-10-05');
2. 修改数据
-- 修改图书单价
UPDATE T_book SET price = 69.99 WHERE book_id = 1;
-- 修改还书日期
UPDATE T_borrow SET return_date = '2023-11-01' WHERE borrow_id = 1;
四、查询示例
-
查询库存小于2的图书
SELECT * FROM T_book WHERE stock < 2;
-
查询未还书的借阅信息
SELECT c.card_id, c.name, b.title, br.borrow_date FROM T_borrow br JOIN T_card c ON br.card_id = c.card_id JOIN T_book b ON br.book_id = b.book_id WHERE br.return_date IS NULL;
五、存储过程实现
DELIMITER $$
CREATE PROCEDURE prc_CountBorrow(IN book_id INT, OUT borrow_count INT)
BEGIN
SELECT COUNT(*) INTO borrow_count
FROM T_borrow
WHERE book_id = book_id;
END$$
DELIMITER ;
-- 调用示例
CALL prc_CountBorrow(1, @count);
SELECT @count AS '借阅次数';
六、PHP开发要点
-
功能模块
- 增删改查:通过表单和PHP脚本操作数据库。
- 权限管理:使用会话(
session
)区分管理员和用户。 - 报表生成:结合SQL查询和HTML表格展示数据。
-
安全措施
-
使用预处理语句防止SQL注入:
$stmt = $conn->prepare("INSERT INTO T_book (title, author, price) VALUES (?, ?, ?)"); $stmt->bind_param("ssd", $title, $author, $price); $stmt->execute();
-
-
代码参考【补充:PHP命令行版《图书借阅管理系统》实现】
七、难点与解决方案
-
外键约束失效
- 确保存储引擎为InnoDB,并检查外键字段类型一致。
-
手机号校验兼容性
-
若MySQL版本不支持
CHECK
约束,改用触发器:CREATE TRIGGER t_card_phone_check BEFORE INSERT ON T_card FOR EACH ROW BEGIN IF NEW.phone NOT REGEXP '^[0-9]{11}$' THEN SIGNAL SQLSTATE '45000' SET MESSAGE_TEXT = '手机号必须为11位数字'; END IF; END;
-
八、实验总结
通过本次实验,掌握了以下技能:
- 数据库逻辑设计与物理实现,包括表结构、约束和关系。
- 复杂SQL操作(存储过程、级联约束)。
- PHP与MySQL的交互开发,注重安全性和功能模块化。
改进方向:
- 增加事务处理保证数据一致性。
- 前端优化(如AJAX异步加载数据)。
- 扩展报表功能(支持导出Excel)。
补充:PHP命令行版《图书借阅管理系统》实现
<?php
// 数据库配置
$servername = "localhost";
$username = "root";
$password = "";
$dbname = "library";
// 创建数据库连接
$conn = new mysqli($servername, $username, $password, $dbname);
if ($conn->connect_error) {
die("数据库连接失败: " . $conn->connect_error);
}
// 主菜单
function showMenu() {
echo "\n====== 图书借阅管理系统 ======\n";
echo "1. 插入测试数据\n";
echo "2. 删除所有数据\n";
echo "3. 修改图书价格\n";
echo "4. 查询所有图书\n";
echo "5. 生成未还书报表\n";
echo "0. 退出系统\n";
echo "请输入选项数字: ";
}
// 插入硬编码数据
function insertData($conn) {
$sql = "INSERT INTO T_book (title, author, price)
VALUES ('PHP入门教程', '李四', 49.99)";
if ($conn->query($sql)) {
echo "[成功] 插入测试数据完成!\n";
} else {
echo "[错误] 插入失败: " . $conn->error . "\n";
}
}
// 删除所有数据(简单权限校验)
function deleteData($conn) {
// 检查是否有数据可删
$result = $conn->query("SELECT COUNT(*) AS total FROM T_book");
$row = $result->fetch_assoc();
if ($row['total'] == 0) {
echo "[提示] 暂无内容,请先添加数据!\n";
return;
}
$sql = "DELETE FROM T_book";
if ($conn->query($sql)) {
echo "[成功] 已删除所有图书数据!\n";
} else {
echo "[错误] 删除失败: " . $conn->error . "\n";
}
}
// 修改价格(硬编码修改)
function updatePrice($conn) {
$sql = "UPDATE T_book SET price = 59.99 WHERE book_id = 1";
if ($conn->query($sql)) {
echo "[成功] 已修改ID为1的图书价格!\n";
} else {
echo "[错误] 修改失败: " . $conn->error . "\n";
}
}
// 查询所有图书
function queryData($conn) {
$sql = "SELECT * FROM T_book";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "\n====== 图书列表 ======\n";
echo sprintf("%-5s | %-20s | %-10s | %-6s\n", "ID", "书名", "作者", "价格");
while ($row = $result->fetch_assoc()) {
echo sprintf("%-5d | %-20s | %-10s | %-6.2f\n",
$row['book_id'], $row['title'], $row['author'], $row['price']);
}
} else {
echo "[提示] 暂无图书数据!\n";
}
}
// 生成未还书报表
function generateReport($conn) {
$sql = "SELECT c.card_id, c.name, b.title, br.borrow_date
FROM T_borrow br
JOIN T_card c ON br.card_id = c.card_id
JOIN T_book b ON br.book_id = b.book_id
WHERE br.return_date IS NULL";
$result = $conn->query($sql);
if ($result->num_rows > 0) {
echo "\n====== 未还书记录 ======\n";
echo sprintf("%-8s | %-10s | %-20s | %-12s\n", "卡号", "姓名", "书名", "借书日期");
while ($row = $result->fetch_assoc()) {
echo sprintf("%-8d | %-10s | %-20s | %-12s\n",
$row['card_id'], $row['name'], $row['title'], $row['borrow_date']);
}
} else {
echo "[提示] 所有书均已归还!\n";
}
}
// 主循环
while (true) {
showMenu();
$input = trim(fgets(STDIN));
switch ($input) {
case '1':
insertData($conn);
break;
case '2':
deleteData($conn);
break;
case '3':
updatePrice($conn);
break;
case '4':
queryData($conn);
break;
case '5':
generateReport($conn);
break;
case '0':
echo "感谢使用,再见!\n";
exit;
default:
echo "无效选项,请重新输入!\n";
}
}
$conn->close();
?>
使用说明
-
环境要求:
- 安装PHP CLI环境(WampServer已内置,需配置环境变量)。
- 确保MySQL服务已启动。
-
运行命令:
php library_cli.php
-
操作示例:
====== 图书借阅管理系统 ====== 1. 插入测试数据 2. 删除所有数据 3. 修改图书价格 4. 查询所有图书 5. 生成未还书报表 0. 退出系统 请输入选项数字: 1 [成功] 插入测试数据完成! 请输入选项数字: 4 ====== 图书列表 ====== ID | 书名 | 作者 | 价格 1 | PHP入门教程 | 李四 | 49.99
功能特点
- 一体化命令行交互:所有操作通过命令行菜单完成,无需浏览器。
- 边界条件处理:
- 删除数据前检查表中是否有记录。
- 查询结果为空的友好提示。
- 硬编码数据操作:
- 插入固定测试数据(
PHP入门教程
)。 - 修改操作固定修改ID为1的图书价格。
- 插入固定测试数据(
- 轻量级实现:代码量少,适合快速演示核心功能。