MYSQL学习成功展示(个人)
图书馆数据库设计
需求分析:
为了提高图书馆的借阅管理效率,设计一个图书馆借阅管理系统,要包含图书信息、读者信息、借阅的流程。功能要求如下:
图书信息管理:新书入库,现有书籍的信息查询、修改,旧书的删除。有些书为不可外借书,只能在馆内阅读,但大部分书籍皆可借阅带走。
读者信息管理:办理借书证的信息,如实名信息、办证时间,电话等。
读者类型信息:(VIP读者或普通读者),VIP读者借阅期限为4个月,一次可借30本书,普通读者借阅期限2个月,一次可借15本书。
图书藏馆信息:放置的场馆名,所在楼层等。
借阅信息:借出去的书的借出日期、归还日期,超期每天罚款0.1块。还要可以查看借阅信息。
概念结构设计:
根据分析,得到实体、属性和关系:
读者类型(借书证ID,类别名称,可借阅书籍数量,最长借阅时间,办证日期,借书证有效期)
读者(身份证号,名称,性别,生日日期,联系电话)
图书(图书编号,书名,作者,出版社,是否允许外借)
藏馆(藏馆编号,场馆名,场馆地点)
关系:一个读者有一个读者类型,一个读者类型对应一个读者;一个读者可以借多本书,每本书也可以被多个读者借阅;一本书只属于一个藏馆,一个藏馆可以放很多书。
使用E-R图为:

逻辑结构设计:
将全局E-R图转化为对应的关系模式:
因为读者和图书的关系是n :m,所以单独领出来,其余1 :n、1 :1,所以放在对应的合适位置(下面实现下划线是主键,加粗为外键,加粗加下划线是同为主键也是外键)。
读者类型(借书证ID,类别名称,可借阅书籍数量,最长借阅时间,办证日期,借书证有效期)
读者(身份证号,名称,性别,生日日期,联系电话,借书证ID)
藏馆(藏馆编号,场馆名,场馆地点)
图书(图书编号,书名,作者,出版社,是否允许外借,所在场馆编号)
借阅(身份证号,图书编号,借出日期,归还日期,实际归还日期,罚金,是否缴纳罚金)
用表格表示就是:
读者类型(ReaderType)关系
| 名称 | 数据类型 | 是否为空 | 说明 |
| sno | CHAR(10) | NOT FULL | 借书证ID |
| tname | VARCHAR(10) | NOT FULL | 类别名称 |
| maxcount | SMALLINT | NULL | 可借最大数量 |
| maxday | SMALLINT | NULL | 可借最大天数 |
| regday | DATE | NULL | 办证时间 |
| effday | DATE | NULL | 有效时间 |
读者(Reader)关系
| 名称 | 数据类型 | 是否为空 | 说明 |
| rno | CHAR(18) | NOT FULL | 身份证号 |
| rname | VARCHAR(10) | NOT FULL | 名称 |
| rsex | CHAR(2) | NULL | 性别 |
| rbirth | DATE | NULL | 生日日期 |
| rphone | CHAR(11) | NOT FULL | 联系电话 |
| sno | CHAR(10) | NOT FULL | 借书证ID |
藏馆(BookRoom)关系
| 名称 | 数据类型 | 是否为空 | 说明 |
| brno | CHAR(3) | NOT FULL | 藏馆编号 |
| brname | VARCHAR(20) | NOT FULL | 场馆名称 |
| brlocation | VARCHAR(30) | FULL | 藏馆地点 |
图书(Book)关系
| 名称 | 数据类型 | 是否为空 | 说明 |
| bno | CHAR(13) | NOT FULL | 图书编号 |
| bname | VARCHAR(30) | NOT FULL | 书名 |
| bwriter | VARCHAR(10) | FULL | 作者 |
| bpublish | VARCHAR(30) | FULL | 出版社 |
| allow | BOOL | FULL | 是否可外借 |
| brno | CHAR(3) | FULL | 藏馆编号 |
借阅(Borrow)关系
| 名称 | 数据类型 | 是否为空 | 说明 |
| rno | CHAR(18) | NOT FULL | 身份证号 |
| bno | CHAR(13) | NOT FULL | 图书编号 |
| lenddate | DATE | NOT FULL | 借出日期 |
| returndate | DATE | FULL | 归还日期 |
| actualdate | DATE | FULL | 实际归还日期 |
| forfeit | FLOAT | FULL | 罚金 |
| fflag | BOOL | FULL | 是否缴纳罚金 |
物理结构设计:
各关系的主键都是在查找或使用时经常出现,且数值皆唯一,所以可以建立唯一索引。在查找时,Reader的rno字段、Book的brno经常出现(也就是外键),使用可以在这些字段建立索引。
数据库的实施:
建立数据库BookDB:
CREATE DATABASE IF NO EXISTS BookDB;

选择数据库后创建基础表;
USE BookDB;

读者类型(ReaderType):
CREATE TABLE ReaderType (
sno CHAR(10) PRIMARY KEY,
tname VARCHAR(10) NOT NULL,
maxcount SMALLINT,
maxday SMALLINT,
regday DATE,
effday DATE
);

读者(Reader):
CREATE TABLE Reader(
rno CHAR(18) PRIMARY KEY,
rname VARCHAR(10) NOT NULL,
rsex CHAR(2),
rbirth DATE,
rphone CHAR(11),
sno CHAR(10) NOT NULL,
FOREIGN KEY(sno) REFERENCES ReaderType(sno)
);

藏馆(BookRoom):
CREATE TABLE BookRoom(
brno CHAR(3) PRIMARY KEY,
brname VARCHAR(20) NOT NULL,
brlocation VARCHAR(30)
);

图书(Book):
CREATE TABLE Book(
bno CHAR(13) PRIMARY KEY,
bname VARCHAR(30) NOT NULL,
bwriter VARCHAR(10),
bpublish VARCHAR(30),
allow BOOL,
brno CHAR(3),
FOREIGN KEY(brno) REFERENCES BookRoom(brno)
);

借阅(Borrow):
CREATE TABLE Borrow (
rno CHAR(18) NOT NULL,
bno CHAR(13) NOT NULL,
lenddate DATE,
returndate DATE,
actualdate DATE,
forfeit FLOAT,
fflag BOOL,
PRIMARY KEY(rno, bno, lenddate),
FOREIGN KEY(rno) REFERENCES Reader(rno),
FOREIGN KEY(bno) REFERENCES Book(bno)
);


这样基本表就都创建好啦,然后是
索引:
CREATE INDEX idx_reader_tno ON Reader(tno);
CREATE INDEX idx_book_brno ON Book(brno);

视图:
创建视图BorrowView,查看查阅信息:
CREATE VIEW BorrowView
AS
SELECT rno, bname, bwriter, lenddate, returndate
FROM Book, Borrow WHERE Book.bno= Borrow . bno;

创建Fi呢View视图,查看罚款信息。
CREATE VIEW FineView
AS
SELECT Reader .rno, rname, forfeit FROM Reader,Borrow
WHERE Reader.rno= Borrow.rno AND forfeit IS NOT NULL;

之后是
创建触发器:
创建触发器trg_Reader_Delete, 实现当删除Reader关系中的读者信息时,级联删除Borrow关系中该读者的借阅信息。
CREATE TRIGGER trg_Reader_Delete
BEFORE DELETE ON Reader
FOR EACH ROW
DELETE FROM Borrow WHERE rno=old.rno;

创建触发器trg_Borrow_Update,实现当更新Borrow关系中实际归还日期时,计算罚金。
DELIMITER //
CREATE TRIGGER trg_Borrow_Update
BEFORE UPDATE ON Borrow
FOR EACH ROW
BEGIN
IF NEW.actualdate > OLD.returndate THEN
SET NEW.fflag = DATEDIFF(NEW.actualdate, OLD.returndate);
END IF;
END //
DELIMITER ;

然后
创建存储过程:
创建存储过程Insert_Reader, 向读者关系中插人新记录。
DELIMITER //
CREATE PROCEDURE Insert_Reader(
p_rno CHAR(18),
p_rname VARCHAR(10),
p_rsex CHAR(2),
p_rbirth DATE,
p_rphone CHAR(11),
p_tno CHAR(10)
)
BEGIN
DECLARE info VARCHAR(20) DEFAULT '插入成功';
DECLARE CONTINUE HANDLER FOR 1062 SET info = '插入失败,不能插入重复的数据';
INSERT INTO Reader
VALUES (p_rno, p_rname, p_rsex, p_rbirth, p_rphone, p_tno);
SELECT info;
END //
DELIMITER ;

创建存储过程Search_Reader,根据给定的读者编号返回该读者证件的有效日期:
DELIMITER //
CREATE PROCEDURE Search_Reader (
p_rno CHAR(18),
OUT p_effday DATE
)
BEGIN
DECLARE info VARCHAR(30) DEFAULT '查询成功';
DECLARE CONTINUE HANDLER FOR NOT FOUND SET info = '该读者不存在!';
SELECT effday INTO p_effday FROM ReaderType
INNER JOIN Reader ON ReaderType.sno = Reader.sno
WHERE Reader.rno = p_rno;
SELECT info;
END //
DELIMITER ;

还是有很多存储过程要写,例如注册时的信息录入存储过程,还可以和Insert_Reader联动,查询书籍的等等。
当然,后面还有运行和维护什么的,这些就是要靠代码编辑软件的时候用啦,目前我还不会,后面也会对这一方面进行学习,但目前会先开单片机的学习,qt的学习也在同步学习,但可惜没什么笔记。
