Database course design - library management system (2. Database implementation - based on mysql)

If it is helpful to you, you can leave a like, follow, bookmark for the humble blogger (not) 

(Cheat about the data, maybe the interview will pass in the future, thank you)

It seems that some readers said that the resources that do not need points can only be downloaded by VIP. If you can’t download them, you can leave an email to the comment area or private chat. I also put the resources on github. The address is as follows:

https://github.com/goLSX/library_manager_system

If it is helpful to you, you may wish to click a star, thank you

The database uses mysql 8.0.25 64-bit, with the use of navicat

mysql can download the installation package on the homepage, or search for it on the Internet

For database installation and configuration, you can refer to online tutorials. Many people have done tutorials, such as this blog post Mysql8.0.17 compressed package installation - super detailed and simple tutorial_singular港的博客-CSDN博客

The installation of navicat can refer to this blog post

Navicat16 Installation Tutorial-Detailed Graphics and Texts_victor_Wang Zehua's Blog-CSDN Blog

Table of contents

1. Create a new database (schema)

 2. Creation of the basic table

3. View creation

4. Creation of integrity

5. Trigger creation

6. Creation of stored procedures

7. Index Creation

8. Database permission management

9. Backup and recovery strategy


After installing navicat and mysql

Start the mysql service first, and then use navicat to connect. After the connection is successful, click New Query

1. Create a new database (schema)

For example, the name of the created database is library_db, and then our newly created tables, stored procedures, etc. all belong to this database (schema)

create database library_db;
use library_db;

 2. Creation of the basic table

readers table

CREATE TABLE readers  (

  reader_name varchar(20) ,

  password varchar(35) ,

  name varchar(10) ,

  id_num varchar(20) ,

  phone_num varchar(15)

);

managers table

create table managers(

manager_name varchar(20),

password varchar(35),

name varchar(10),

id_num varchar(20),

phone_num varchar(15),

entry_time date,

work_position varchar(20),

state varchar(5)

);

opinions table

 create table opinions(

opinion_rec_num int,

reader_name varchar(20),

opinion varchar(100),

submit_time date,

state varchar(10)

);

books table

create table books(

book_num int,

book_name varchar(30),

book_price float,

book_state varchar(10),

book_position varchar(30)

);

opinion_results table

create table opinion_results(

opinion_rec_num int,

result varchar(100),

transactor Varchar(20),

finish_time date

);

borrows表

create table borrows(

borrow_rec_num int,

reader_name varchar(20),

book_num int,

borrow_time date,

transactor varchar(20),

borrow_state varchar(10),

borrow_duration smallint

);

returns table

create table returns(

borrow_rec_num int,

return_time date,

transactor varchar(20),

fee float,

kind varchar(5)

);

3. View creation

create view reader_message as

      select reader_name,name,id_num,(substring(now(),1,4)-substring(id_num,7,4))-

(substring(id_num,11,4)-date_format(now(),'%m%d')>0) as age,phone_num from readers;

create view manager_message as

select manager_name,name,id_num,(substring(now(),1,4)-substring(id_num,7,4))-

(substring(id_num,11,4)-date_format(now(),'%m%d')>0) as age,

 phone_num,entry_time,work_position,state from managers;

create view opinion_result_message as select opinions.opinion_rec_num as opinion_rec_num,

reader_name,opinion,submit_time,state,result,transactor,finish_time

from (opinions left outer join opinion_results on

 opinions.opinion_rec_num = opinion_results.opinion_rec_num);

create view return_message as

select borrows.borrow_rec_num as borrow_rec_num,reader_name,

borrows.book_num as book_num,book_name,borrow_time,

borrows.transactor as borrow_transactor,borrow_state,return_time,

borrow_duration,returns.transactor as return_transactor,fee,kind from

borrows left outer join books on borrows.book_num = books.book_num

 left join returns on borrows.borrow_rec_num = returns.borrow_rec_num;

create view book_message as

select book_num,book_name,book_price,book_state,book_position from books;

4. 完整性的创建

(主键、外键、check、非空、唯一、用户定义完整性、自增)

readers表

alter table readers

modify reader_name varchar(20) primary key,

modify password varchar(35) not null,

modify name varchar(10) not null,

modify id_num varchar(20) unique,

add CONSTRAINT readers_check_id CHECK ((char_length(id_num) = 15) or (char_length(id_num) = 18)),

add CONSTRAINT readers_check_phone CHECK ((phone_num is null) or (char_length(phone_num) = 11));

managers表

alter table managers

modify manager_name varchar(20) primary key,

modify password varchar(35) not null,

modify name varchar(10) not null,

modify id_num varchar(20) unique,

modify entry_time date not null,

modify work_position varchar(20) not null,

modify state varchar(5) default '正常',

add CONSTRAINT managers_check_id CHECK ((char_length(id_num) = 15) or (char_length(id_num) = 18)),

add CONSTRAINT managers_check_phone CHECK ((phone_num is null) or (char_length(phone_num) = 11)),

add CONSTRAINT managers_check_state CHECK(state='正常' or state='注销');

books表

alter table books

modify  book_num int primary key auto_increment,

modify book_name varchar(30) not null,

modify book_price float not null,

modify book_state varchar(10) not null default '不可借',

add CONSTRAINT books_check_price CHECK (book_price > 0),

add CONSTRAINT books_check_state CHECK(book_state='可借' or book_state='不可借');

opinions表

alter table opinions

modify  opinion_rec_num int primary key  auto_increment,

modify opinion varchar(100) not null,

modify submit_time date not null,

modify state varchar(10) default '待处理',

add CONSTRAINT opinions_fkey_reader foreign key(reader_name) references readers(reader_name),

add CONSTRAINT opinions_check_state CHECK(state='待处理' or state='处理完成');

opinion_results表

alter table opinion_results

modify opinion_rec_num int primary key,

modify result varchar(100) not null,

modify finish_time date  not null,

add CONSTRAINT opinion_results_fkey_rec_num foreign key(opinion_rec_num)

references opinions(opinion_rec_num),

add CONSTRAINT opinion_results_fkey_transactor foreign key(transactor)

references managers(manager_name);

borrows表

alter table borrows

modify borrow_rec_num int primary key auto_increment,

modify borrow_time date not null,

modify borrow_state varchar(10)  not null default '待还',

modify borrow_duration smallint not null default 30,

add CONSTRAINT borrows_fkey_reader foreign key(reader_name)

references readers(reader_name),

add CONSTRAINT borrows_fkey_book foreign key(book_num)

references books(book_num),

add CONSTRAINT borrows_fkey_transactor foreign key(transactor)

references managers(manager_name),

add CONSTRAINT borrows_check_state CHECK(borrow_state in ('待还','已还'));

returns表

alter table returns

modify borrow_rec_num int primary key ,

modify return_time date not null,

modify kind varchar(5) default '正常',

add CONSTRAINT returns_fkey_rec_num foreign key(borrow_rec_num)

references borrows(borrow_rec_num),

add CONSTRAINT returns_fkey_transactor foreign key(transactor)

references managers(manager_name),

add CONSTRAINT returns_check_kind CHECK(kind in ('正常','丢失'));

5. 触发器创建

create trigger insert_opinion_results after insert on opinion_results

for each row update opinions set state='处理完成'

where new.opinion_rec_num = opinions.opinion_rec_num;

create trigger insert_borrows after insert on borrows

for each row update books set book_state='不可借'

where new.book_num = books.book_num;

create trigger insert_books before insert on  books

for each row if new.book_position is not null

       then  set new.book_state='可借';

   end if;

create trigger update_books before update on  books

for each row

if old.book_position is null and new.book_position is not null

then  set new.book_state='可借';

end if;

6. 存储过程的创建

create procedure insert_reader

(in reader_name_in varchar(20),

in  password varchar(35) ,

in   name varchar(10) ,

in  id_num varchar(20) ,

in  phone_num varchar(15))

begin

insert into readers values(reader_name_in,password,name,id_num,phone_num);

end

create procedure insert_manager

(in manager_name_in varchar(20),

in  password_in varchar(35) ,

in   name_in varchar(10) ,

in  id_num_in varchar(20) ,

in  phone_num_in varchar(15),

in entry_time_in date ,

in work_position_in varchar(20))

begin insert into managers

    (manager_name,password,name,id_num,phone_num,entry_time, work_position) values

(manager_name_in,password_in,name_in,id_num_in,phone_num_in,entry_time_in,work_position_in);  

end

create procedure insert_opinion

(in reader_name_in varchar(20),

in opinion_in varchar(100),

in submit_time_in date)

begin

insert into opinions(reader_name,opinion,submit_time) values

(reader_name_in,opinion_in,submit_time_in);

end

create procedure insert_book

(in book_name_in varchar(30),

in book_price_in float,

in book_position_in varchar(30))

begin

    insert into book_message(book_name,book_price,book_position) values

(book_name_in,book_price_in,book_position_in);

end

create procedure insert_opinion_result

(in opinion_rec_num_in int,

in result_in varchar(100),

in transactor_in int,

in finish_time_in date)

begin

    insert into opinion_results(opinion_rec_num,result,transactor,finish_time)

values (opinion_rec_num_in,result_in,transactor_in,finish_time_in);

end

create procedure insert_borrow

(in reader_name_in varchar(20),

in book_num_in int,

in borrow_time_in date,

in transactor_in varchar(20),

out result varchar(10))

begin

       select exists(select * from reader_message where binary reader_name = reader_name_in)

into result;

if result = '0' then  set result = '读者不存在';

select result;

commit;

end if;

select exists(select * from book_message where  book_num = book_num_in) into result;

if result = '0' then  set result = '图书不存在';

select result;

commit;

end if;

insert into borrows(reader_name,book_num,borrow_time,transactor)

values (reader_name_in,book_num_in,borrow_time_in,transactor_in);

select '成功';

end

create procedure insert_return

(in borrow_rec_num_in int,

in return_time_in date,

in transactor_in varchar(20),

in kind_in varchar(5),

out fee_out float)

begin

declare price float;

DECLARE latetime SMALLINT ;

declare fee_out float default null;

declare book_num_temp int;

declare borrow_time_temp date;

declare borrow_duration_temp smallint;

SELECT book_num ,borrow_time ,borrow_duration INTO

 book_num_temp,borrow_time_temp,borrow_duration_temp

FROM borrows WHERE borrow_rec_num = borrow_rec_num_in ;

SELECT book_price into price FROM books WHERE book_num = book_num_temp;

    SET latetime = datediff(return_time_in,borrow_time_temp) - borrow_duration_temp;

    UPDATE borrows SET borrow_state = '已还' WHERE borrow_rec_num = borrow_rec_num_in;

IF kind_in = '正常' THEN UPDATE books SET book_state = '可借' WHERE

                       book_num = book_num_temp;

IF latetime > 0 THEN SET fee_out = 0.1 * latetime;

END IF;

ELSE UPDATE books SET book_position = NULL WHERE book_num = book_num_temp;

                    set fee_out = price;

end if;

    insert into returns(borrow_rec_num,return_time,transactor,fee,kind)

values (borrow_rec_num_in,return_time_in,transactor_in,fee_out,kind_in);

   select fee_out;

end

create procedure select_reader_message(in reader_name_in varchar(20))

begin  

select * from reader_message where binary reader_name = reader_name_in;

end

create procedure select_manager_message(in manager_name_in varchar(20))

begin

select * from manager_message where binary manager_name = manager_name_in;

end

CREATE procedure select_book_message(in book_name_in varchar(30))

begin

select * from book_message where book_name like CONCAT('%',book_name_in,'%');

end

CREATE PROCEDURE select_book_by_num(in book_num_in int)

begin

select * from book_message where book_num = book_num_in;

end

CREATE  PROCEDURE select_opinion(in opinion_rec_num_in  int)

begin

select opinion,state  from opinion_result_message where opinion_rec_num = opinion_rec_num_in;

end

create procedure select_opinion_result_message(in reader_name_in varchar(20))

begin

  select * from opinion_result_message where binary reader_name

       = reader_name_in order by submit_time desc  limit 10;

end

create procedure select_pending_opinion()

begin

  select * from opinions where state = '待处理' order by submit_time limit 10;

end

create procedure select_return_message(in reader_name_in varchar(20))

begin

  select * from return_message where binary reader_name

       = reader_name_in order by borrow_time desc  limit 10;

end

CREATE  PROCEDURE select_borrow_by_booknum(in book_num_in int)

begin

select * from return_message where borrow_state = '待还' and

book_num = book_num_in limit 1;

end

create procedure update_reader_message

(in reader_name_in varchar(20),

in name_in varchar(10),

in id_num_in varchar(20),

in phone_num_in varchar(15))

begin

  update reader_message set name = name_in , id_num = id_num_in ,

  phone_num = phone_num_in where binary reader_name = reader_name_in;

end

create procedure update_reader_password

(in password_in varchar(35))

begin

 update readers set password = password_in where binary reader_name = reader_name_in;

end

CREATE  PROCEDURE update_manager_message(in manager_name_in varchar(20),

in name_in varchar(10),

in id_num_in varchar(20),

in phone_num_in varchar(15))

begin

 update manager_message set name = name_in , id_num = id_num_in ,

 phone_num = phone_num_in where binary manager_name = manager_name_in;

end

CREATE  PROCEDURE update_manager_password

(in manager_name_in varchar(20),

in password_in varchar(35))

begin

 update managers set password = password_in where binary manager_name = manager_name_in;

end

CREATE  PROCEDURE update_manager_work

(in manager_name_in varchar(20),

in work_position_in varchar(20),

in state_in varchar(5))

begin

update managers set work_position = work_position_in ,state = state_in

where binary manager_name = manager_name_in;

end

CREATE  PROCEDURE update_book

(in book_num_in int,

in book_name_in varchar(30),

in book_price_in float,

in book_state_in varchar(10),

in book_position_in varchar(30))

begin

update book_message set book_name = book_name_in ,book_price = book_price_in,

book_state = book_state_in,book_position = book_position_in

where book_num = book_num_in;

end

CREATE  PROCEDURE delete_book

(in book_num_in int,

out result varchar(10))

begin

select exists(select * from book_message where  book_num = book_num_in) into result;

if result = '0' then  set result = '图书不存在';

select result;

commit;

end if;

update book_message set book_state = '不可借',book_position = null

where book_num = book_num_in;

select '成功';

end

CREATE  PROCEDURE delete_manager

(in manager_name_in varchar(30))

begin

update managers set state = '注销'

where binary manager_name = manager_name_in;

end

CREATE PROCEDURE extend_time

(in book_num_in int ,

out result varchar(5))

begin declare latetime smallint;

declare result varchar(5) default '成功';

declare borrow_rec_num_in int;

set borrow_rec_num_in =

(select borrow_rec_num from borrows where borrow_state = '待还' and book_num = book_num_in);

      select CURDATE() - borrow_time - borrow_duration into latetime

   from borrows where borrow_rec_num = borrow_rec_num_in;

if latetime > 0  then set result = '超期';

else  update borrows set borrow_duration = borrow_duration + 15

  where borrow_rec_num = borrow_rec_num_in;

   end if;   

select result;

end

create procedure check_reader

(in reader_name_in varchar(20),

in password_in varchar(35),

out result varchar(5))

begin

    if password_in = (select password from readers where binary reader_name = reader_name_in)

  then  set result = '正确';

else set result = '错误';

end if;

select result;

end

create procedure check_manager

(in manager_name_in varchar(20),

in password_in varchar(35),

out result varchar(5))

begin

set result = '错误';

    if password_in =

(select password from managers where binary manager_name = manager_name_in)

then  set result = '正确';

if '注销' = (select state from managers where binary manager_name = manager_name_in)

then  set result = '注销';

end if;

end if;

select result;

end

create procedure check_manager_sigh_up

(in manager_name_in varchar(20),

in  id_num_in varchar(20) ,

out result varchar(10))

begin

    select exists(select * from managers where binary manager_name = manager_name_in) into result;

if result = '1' then  set result = '用户名已存在';

select result;

commit;

end if;

select exists(select * from managers where id_num = id_num_in) into result;

if result = '1' then set result = '身份证号已被注册';

end if;

if result = '0' then select 'OK';

else select result;

end if;

end

create procedure check_reader_sigh_up

(in reader_name_in varchar(20),

in  id_num_in varchar(20) ,

out result varchar(10))

begin

    select exists(select * from readers where binary reader_name = reader_name_in) into result;

if result = '1' then  set result = '用户名已存在';

select result;

commit;

end if;

select exists(select * from readers where id_num = id_num_in) into result;

if result = '1' then set result = '身份证号已被注册';

end if;

if result = '0' then select 'OK';

else select result;

end if;

end

7. 索引创建

mysql创建表时默认引擎InnoDB,如果表有主键,会建立主键聚集索引,如果一个字段有unique约束,会建立unique索引,如果一个字段有外键约束,会建立外键索引。在此基础上我们只多建立一个索引,books表的book_name字段建立非聚集索引。

create index book_name_index on books(book_name);

给books表的book_name创建非聚集索引,其他索引由数据库引擎创建

                                完成后各表上的索引如下

各字段解析如下

Table

表示创建索引的数据表名。

Non_unique

表示该索引是否是唯一索引。若不是唯一索引,则该列的值为 1;若是唯一索引,则该列的值为 0。

Key_name

表示索引的名称。

Seq_in_index

表示该列在索引中的位置,如果索引是单列的,则该列的值为 1;如果索引是组合索引,则该列的值为每列在索引定义中的顺序。

Column_name

表示定义索引的列字段。

Collation

表示列以何种顺序存储在索引中。在 MySQL 中,升序显示值“A”(升序),若显示为 NULL,则表示无分类。

Cardinality

索引中唯一值数目的估计值。基数根据被存储为整数的统计数据计数,所以即使对于小型表,该值也没有必要是精确的。基数越大,当进行联合时,MySQL 使用该索引的机会就越大。

Sub_part

表示列中被编入索引的字符的数量。若列只是部分被编入索引,则该列的值为被编入索引的字符的数目;若整列被编入索引,则该列的值为 NULL。

Packed

指示关键字如何被压缩。若没有被压缩,值为 NULL。

Null

用于显示索引列中是否包含 NULL。若列含有 NULL,该列的值为 YES。若没有,则该列的值为 NO。

Index_type

显示索引使用的类型和方法(BTREE、FULLTEXT、HASH、RTREE)。

Comment

显示评注。

8. 数据库权限管理

使用严格的权限管理,只有允许的操作才能进行;有三类用户使用数据库,创建reader,manager,sys_manager。每个用户只授权某些函数的执行,不允许修改,也不允许权限传递,更不能直接接触到表,这样保证数据库的安全性和独立性(只通过函数接口访问)。

除了这三个用户外,实现时还使用一个checker用户,这个用户负责在我们没有登录成功前,连接数据库进行用户检查,检查通过后,建立用户连接进行数据库操作(reader/manager/sys_manager), 同时checker连接释放,另外读者用户注册也需要checker帮助传递读者信息到数据库完成注册,manager的注册有sys_manager负责验证。

                                                        各用户授予权限如下

 

 

(关于创建用户和授权可以参考以下代码

CREATE USER 'checker'@'localhost' IDENTIFIED BY 'checkerpassword';  #其他类似

...................

grant execute on procedure library_db.insert_opinion to 'reader'@'localhost';

........................)

(也可以使用navicat图形化的方式创建,百度一下)

9. 备份与恢复策略(可不做,但是做了的话比较完善)

采取海量+增量的方式备份数据。 每周进行一次海量备份,两次海量备份之间采用增量备份方式。由于mysql不直接提供增量备份方式,故采用日志记录的方式来实现增量备份。

备份流程如下:

1.在配置文件开启二进制日志功能,设置日志地址(根据),服务id  如图

       

 注:backup 文件夹需要自己创建、mysql-bin是日志文件的命名方式,不用创建,结合下图看看

 

2. Perform mass backup first, such as

mysqldump -u root -p -R library_db> C:\Users\Administrator\Desktop\library_db.sql

Or use navicat to backup graphically

3. After that, mysql will record the execution log and save it to the address we specified. The name is mysql-bin.00000x, so that we can restore the data through massive backup and log. (counting from mysql-bin.000001)

An example recovery is as follows:

1. First restore the massive backup

mysql -u root -p  < C:\Users\Administrator\Desktop\library_db.sql

2. Reuse the log to restore the incremental backup one by one (go to the log directory folder to execute the restore command)

mysqlbinlog --no-defaults mysql-bin.000001 | mysql -uroot -p+password

(如mysqlbinlog --no-defaults mysql-bin.000001 | mysql -uroot -p123456) 

mysqlbinlog --no-defaults mysql-bin.00000 2  | mysql -uroot -p+password

.........

The actual runtime backup method uses navicat to create a batch job, specify to perform a full backup, and then reset the log, (counting from 000001), the execution time is 2:00 am every Sunday, and the settings are as follows

Note: After each recovery, the stored procedure needs to be re-authorized

At this point the database implementation is complete.

Guess you like

Origin blog.csdn.net/ass133755/article/details/128645404