-- 创建数据库(若不存在)  
CREATE DATABASE IF NOT EXISTS library;
USE library;

-- 创建用户表,并增加角色字段
CREATE TABLE users (
user_id INT AUTO_INCREMENT PRIMARY KEY, -- 用户ID,主键
username VARCHAR(50) NOT NULL UNIQUE, -- 用户名,唯一
password VARCHAR(255) NOT NULL, -- 密码
email VARCHAR(100) NOT NULL UNIQUE, -- 邮箱,唯一
role ENUM('admin', 'user') DEFAULT 'user', -- 角色字段,默认值为'user'
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP -- 创建时间,默认当前时间
);

-- 创建图书表
CREATE TABLE books (
book_id INT AUTO_INCREMENT PRIMARY KEY, -- 图书ID,主键
title VARCHAR(255) NOT NULL, -- 图书标题
author VARCHAR(255) NOT NULL, -- 作者
published_date DATE, -- 出版日期
available BOOLEAN DEFAULT TRUE -- 是否可借,默认值为 TRUE
);

-- 创建借阅记录表
CREATE TABLE borrow_records (
record_id INT AUTO_INCREMENT PRIMARY KEY, -- 借阅记录ID,主键
user_id INT, -- 用户ID,外键关联users表
book_id INT, -- 图书ID,外键关联books表
borrow_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP, -- 借书日期,默认当前时间
return_date TIMESTAMP NULL, -- 还书日期
FOREIGN KEY (user_id) REFERENCES users(user_id), -- 外键约束,关联users表
FOREIGN KEY (book_id) REFERENCES books(book_id) -- 外键约束,关联books表
);

-- 插入包含管理员和普通用户的初始数据
INSERT INTO users (username, password, email, role) VALUES
('admin1', 'adminpassword1', 'admin1@example.com', 'admin'), -- 管理员
('user1', 'password1', 'user1@example.com', 'user'), -- 普通用户
('user2', 'password2', 'user2@example.com', 'user'); -- 普通用户

-- 插入一些图书数据
INSERT INTO books (title, author, published_date) VALUES
('Book Title 1', 'Author 1', '2020-01-01'), -- 图书1
('Book Title 2', 'Author 2', '2021-02-02'); -- 图书2

1. 一、绪论

2. 二、系统分析

(一)用例图、分角色功能图

用例图

分角色功能图

  1. 管理员功能
    • 管理员能管理用户信息:添加图书、新增用户、更新图书信息等。
    • 管理员有高级权限,比如可以查看所有用户、删除图书。
  2. 普通用户功能
    • 普通用户只能查找图书、借阅图书等。

(二)数据需求—数据流图

画板

3. 三、系统设计

3.1.1. (一)概念结构设计-ER图系统功能模块图

users

画板

books

画板

loans

画板

图书类别

画板

出版社

画板

整体

画板

3.1.2. (二)系统功能模块图

3.1.2.1. 用户注册流程

3.1.2.2. 借书流程

3.1.3. (三)逻辑结构设计-关系模式-表

3.1.4. 实体关系分析

主要实体:用户、图书、出版社、图书类别、借阅记录

关系:

  • 一个出版社可以出版多本图书(1:n)
  • 一个类别可以包含多本图书(1:n)
  • 一个用户可以借多本图书(1:n)
  • 一本图书可以被多个用户借阅(记录在借阅历史中)(1:n)

3.1.5. 关系模式(表结构)

3.1.5.1. 用户表 (用户)

字段名 类型 约束 说明
用户编号 INT 主键, 自增 用户唯一标识
用户名 VARCHAR(50) 非空, 唯一 登录账号
密码 VARCHAR(255) 非空 登录密码
邮箱 VARCHAR(100) 非空, 唯一 联系邮箱
角色 ENUM 非空, 默认’用户’ 用户角色:管理员/用户
创建时间 TIMESTAMP 默认当前时间 账号创建时间

3.1.5.2. 出版社表 (出版社)

字段名 类型 约束 说明
出版社编号 INT 主键, 自增 出版社唯一标识
出版社名称 VARCHAR(100) 非空, 唯一 出版社名称
地址 VARCHAR(255) 可空 出版社地址
联系电话 VARCHAR(20) 可空 联系方式
联系邮箱 VARCHAR(100) 可空 业务邮箱
创建时间 TIMESTAMP 默认当前时间 记录创建时间

3.1.5.3. 图书类别表 (图书类别)

字段名 类型 约束 说明
类别编号 INT 主键, 自增 类别唯一标识
类别名称 VARCHAR(50) 非空, 唯一 类别名称
类别描述 TEXT 可空 类别详细描述
创建时间 TIMESTAMP 默认当前时间 记录创建时间

3.1.5.4. 图书表 (图书)

字段名 类型 约束 说明
图书编号 INT 主键, 自增 图书唯一标识
书名 VARCHAR(255) 非空 图书名称
作者 VARCHAR(255) 非空 作者姓名
出版社编号 INT 外键 关联出版社表
类别编号 INT 外键 关联图书类别表
出版日期 DATE 可空 出版日期
ISBN码 VARCHAR(13) 唯一 图书标准编号
是否可借 BOOLEAN 默认TRUE 借阅状态
创建时间 TIMESTAMP 默认当前时间 记录创建时间

3.1.5.5. 借阅记录表 (借阅记录)

字段名 类型 约束 说明
记录编号 INT 主键, 自增 借阅记录唯一标识
用户编号 INT 外键 关联用户表
图书编号 INT 外键 关联图书表
借出时间 TIMESTAMP 默认当前时间 借书时间
归还时间 TIMESTAMP 可空 还书时间

3.1.6. 主要关系说明

  1. 图书与出版社:
    • 一对多关系
    • 通过图书表的出版社编号关联到出版社表
  2. 图书与类别:
    • 一对多关系
    • 通过图书表的类别编号关联到图书类别表
  3. 用户与借阅记录:
    • 一对多关系
    • 通过借阅记录表的用户编号关联到用户表
  4. 图书与借阅记录:
    • 一对多关系
    • 通过借阅记录表的图书编号关联到图书表

这种设计实现了:

  • 完整的图书管理功能
  • 清晰的数据关系
  • 可追踪的借阅历史
  • 灵活的用户权限控制
  • 完善的分类管理

通过这样的结构,可以方便地实现:

  • 图书检索
  • 借阅管理
  • 库存统计
  • 用户管理
  • 分类统计等功能

3.2. 四、系统实现(程序流程图,实现的界面)数据库连接

import tkinter as tk  
from tkinter import messagebox
import mysql.connector

# 连接到数据库
db = mysql.connector.connect(
host="localhost",
user="root",
password=" ",
database="library"
)

cursor = db.cursor()

# 注册功能
def register():
username = entry_username.get()
password = entry_password.get()
email = entry_email.get()

if username and password and email:
try:
# 往数据库中插入用户信息,默认 role 为 'user'
cursor.execute(
"INSERT INTO users (username, password, email) VALUES (%s, %s, %s)",
(username, password, email)
)
db.commit()
messagebox.showinfo("Success", "Registration successful!")
except mysql.connector.Error as err:
# 捕获数据库错误并弹窗提示
messagebox.showerror("Error", f"Error: {err}")
else:
# 如果输入框空白,则报错
messagebox.showerror("Error", "All fields are required!")

# 登录功能
def login():
username = entry_username.get()
password = entry_password.get()

if username and password:
# 查询用户的角色和登录状态
cursor.execute(
"SELECT role FROM users WHERE username=%s AND password=%s",
(username, password)
)
user = cursor.fetchone() # 获取结果
if user:
role = user[0] # 获取用户角色
if role == 'admin':
messagebox.showinfo("Success", "Login successful! Welcome, Admin!")
else:
messagebox.showinfo("Success", "Login successful! Welcome, User!")
else:
# 用户名或密码错误时
messagebox.showerror("Error", "Invalid username or password!")
else:
# 输入框为空时
messagebox.showerror("Error", "All fields are required!")

# 创建主窗口
root = tk.Tk()
root.geometry("400x300") # 调整主窗口大小
root.title("Library System")

# 创建标签和输入框
tk.Label(root, text="Username").grid(row=0, column=0, padx=10, pady=10)
entry_username = tk.Entry(root, width=40) # 调整输入框宽度
entry_username.grid(row=0, column=1, padx=10, pady=10)

tk.Label(root, text="Password").grid(row=1, column=0, padx=10, pady=10)
entry_password = tk.Entry(root, show="*", width=40) # 输入框隐藏内容
entry_password.grid(row=1, column=1, padx=10, pady=10)

tk.Label(root, text="Email").grid(row=2, column=0, padx=10, pady=10)
entry_email = tk.Entry(root, width=40)
entry_email.grid(row=2, column=1, padx=10, pady=10)

# 创建按钮
tk.Button(root, text="Register", command=register).grid(row=3, column=0, padx=10, pady=10)
tk.Button(root, text="Login", command=login).grid(row=3, column=1, padx=10, pady=10)

# 运行主循环
root.mainloop()

此处为语雀卡片,点击链接查看