数据库设计与UML图

数据库设计与UML图详细教程

目录

  1. 数据库设计概述
  2. 数据库设计原则
  3. 数据库设计步骤
  4. UML图详解
  5. 数据库设计与UML的结合
  6. 实战案例
  7. 最佳实践

数据库设计概述

什么是数据库设计

数据库设计是指根据用户的需求,在某一具体的数据库管理系统上,设计数据库的结构和建立数据库的过程。它是信息系统开发和建设中的核心技术之一。

数据库设计的重要性

良好的数据库设计能够:

  • 减少数据冗余
  • 提高数据一致性
  • 提升系统性能
  • 简化应用程序开发
  • 便于系统维护和扩展
  • 保证数据安全性和完整性

数据库设计的目标

  • 满足用户需求: 准确反映业务逻辑和数据关系
  • 高效性: 优化查询性能和存储空间
  • 可维护性: 便于未来的修改和扩展
  • 数据完整性: 保证数据的准确性和一致性
  • 安全性: 保护敏感数据不被非法访问

数据库设计原则

1. 规范化理论

第一范式 (1NF)

确保每个列都是不可分割的原子值。

示例:

复制代码
❌ 错误设计:
学生表(学号, 姓名, 联系方式)
联系方式: "电话:13800138000,邮箱:xxx@email.com"

✅ 正确设计:
学生表(学号, 姓名, 电话, 邮箱)
第二范式 (2NF)

在1NF基础上,非主键列完全依赖于主键,消除部分依赖。

示例:

复制代码
❌ 错误设计:
订单明细表(订单号, 商品号, 商品名称, 数量, 商品价格, 商品分类)
问题: 商品名称、商品价格、商品分类只依赖于商品号

✅ 正确设计:
订单明细表(订单号, 商品号, 数量)
商品表(商品号, 商品名称, 商品价格, 商品分类)
第三范式 (3NF)

在2NF基础上,非主键列之间不存在传递依赖。

示例:

复制代码
❌ 错误设计:
员工表(员工号, 姓名, 部门号, 部门名称, 部门经理)
问题: 部门名称和部门经理依赖于部门号,而非员工号

✅ 正确设计:
员工表(员工号, 姓名, 部门号)
部门表(部门号, 部门名称, 部门经理)
BCNF (Boyce-Codd范式)

在3NF基础上,每个决定因素都包含候选键。

第四范式 (4NF) 和 第五范式 (5NF)

处理多值依赖和连接依赖的高级规范化形式。

2. 反规范化

在某些情况下,为了提高查询性能,可以适当进行反规范化:

  • 增加冗余列
  • 增加派生列
  • 表的合并
  • 表的分割

3. 命名规范

  • 使用有意义的名称
  • 保持一致的命名风格(驼峰命名或下划线命名)
  • 避免使用保留字
  • 表名使用复数或单数保持一致
  • 主键通常命名为 id表名_id
  • 外键命名为 关联表名_id

数据库设计步骤

1. 需求分析阶段

主要任务
  • 了解用户需求
  • 确定系统边界
  • 收集数据需求
  • 确定功能需求
  • 分析数据处理流程
输出物
  • 需求规格说明书
  • 数据流图 (DFD)
  • 业务流程图

2. 概念设计阶段

主要任务
  • 抽象出实体
  • 确定实体属性
  • 确定实体间关系
  • 绘制E-R图
E-R图组成元素

实体 (Entity)

  • 表示现实世界中的对象
  • 用矩形表示
  • 例如: 学生、课程、教师

属性 (Attribute)

  • 实体的特征
  • 用椭圆表示
  • 例如: 学号、姓名、性别

关系 (Relationship)

  • 实体之间的联系
  • 用菱形表示
  • 包括: 一对一、一对多、多对多

示例E-R图概念:

复制代码
学生 ----< 选课 >---- 课程
|                      |
属性:                 属性:
- 学号(主键)         - 课程号(主键)
- 姓名               - 课程名
- 性别               - 学分
- 年龄               - 学时

3. 逻辑设计阶段

主要任务
  • 将E-R图转换为关系模型
  • 确定表结构
  • 定义主键和外键
  • 应用规范化理论
E-R图到关系模型的转换规则

实体转换 :

每个实体转换为一个表,实体的属性转换为表的列。

关系转换:

  • 一对一: 在任一方添加外键,或合并为一个表
  • 一对多: 在"多"方添加外键
  • 多对多: 创建中间表,包含两方的外键

示例转换:

sql 复制代码
-- 学生表
CREATE TABLE Student (
    student_id INT PRIMARY KEY,
    student_name VARCHAR(50),
    gender CHAR(1),
    age INT
);

-- 课程表
CREATE TABLE Course (
    course_id INT PRIMARY KEY,
    course_name VARCHAR(100),
    credits INT,
    hours INT
);

-- 选课表 (多对多关系)
CREATE TABLE Enrollment (
    enrollment_id INT PRIMARY KEY,
    student_id INT,
    course_id INT,
    grade DECIMAL(5,2),
    enrollment_date DATE,
    FOREIGN KEY (student_id) REFERENCES Student(student_id),
    FOREIGN KEY (course_id) REFERENCES Course(course_id)
);

4. 物理设计阶段

主要任务
  • 选择合适的DBMS
  • 确定存储结构
  • 设计索引
  • 设计视图
  • 考虑分区策略
  • 估算存储空间
索引设计原则
  • 为经常查询的列创建索引
  • 为外键创建索引
  • 避免过多索引影响写入性能
  • 考虑组合索引

示例:

sql 复制代码
-- 创建索引
CREATE INDEX idx_student_name ON Student(student_name);
CREATE INDEX idx_enrollment_student ON Enrollment(student_id);
CREATE INDEX idx_enrollment_composite ON Enrollment(student_id, course_id);

5. 实施阶段

  • 创建数据库
  • 创建表结构
  • 导入初始数据
  • 创建存储过程和触发器
  • 设置权限和安全策略

6. 维护和优化阶段

  • 性能监控
  • 查询优化
  • 索引调整
  • 数据备份和恢复
  • 版本升级

UML图详解

UML简介

UML (Unified Modeling Language) 统一建模语言,是一种用于软件系统分析、设计、实现的可视化建模语言。

UML图的分类

UML 2.x 包含14种图,分为两大类:

结构图 (Structure Diagrams)
  1. 类图 (Class Diagram)
  2. 对象图 (Object Diagram)
  3. 组件图 (Component Diagram)
  4. 部署图 (Deployment Diagram)
  5. 包图 (Package Diagram)
  6. 组合结构图 (Composite Structure Diagram)
  7. 轮廓图 (Profile Diagram)
行为图 (Behavior Diagrams)
  1. 用例图 (Use Case Diagram)
  2. 活动图 (Activity Diagram)
  3. 状态机图 (State Machine Diagram)
  4. 序列图 (Sequence Diagram)
  5. 通信图 (Communication Diagram)
  6. 交互概览图 (Interaction Overview Diagram)
  7. 时序图 (Timing Diagram)

常用UML图详解

1. 类图 (Class Diagram)

类图是最常用的UML图,展示系统中的类、属性、方法以及类之间的关系。

类的表示
复制代码
┌─────────────────────┐
│   Student           │ ← 类名
├─────────────────────┤
│ - studentId: int    │ ← 属性 (- 表示private)
│ - name: String      │
│ # age: int          │   (# 表示protected)
│ + email: String     │   (+ 表示public)
├─────────────────────┤
│ + enroll(): void    │ ← 方法
│ + getGrade(): float │
│ - validate(): bool  │
└─────────────────────┘
类之间的关系

1. 关联 (Association)

  • 表示类之间的结构关系

  • 用实线表示

  • 可以有方向性

    Student ────────> Course
    (学生) (课程)
    多重性: 1 ──── 0..*

多重性表示:

  • 1: 恰好一个
  • 0..1: 零个或一个
  • *0..*: 零个或多个
  • 1..*: 一个或多个
  • n..m: n到m个

2. 聚合 (Aggregation)

  • 整体与部分的关系,部分可以独立存在

  • 用空心菱形表示

    Department ◇────── Employee
    (部门) (员工)

3. 组合 (Composition)

  • 强聚合关系,部分不能独立于整体存在

  • 用实心菱形表示

    House ◆────── Room
    (房子) (房间)

4. 依赖 (Dependency)

  • 一个类使用另一个类

  • 用虚线箭头表示

    OrderService ┈┈┈┈> EmailService

5. 继承/泛化 (Inheritance/Generalization)

  • 表示is-a关系

  • 用空心三角箭头表示

    Animal


    ├──── Dog
    └──── Cat

6. 实现 (Realization)

  • 接口与实现类的关系

  • 用虚线空心三角表示

    <<interface>>
    Drawable



    Circle

完整类图示例
复制代码
┌────────────────────┐
│   <<abstract>>     │
│   Person           │
├────────────────────┤
│ - id: int          │
│ - name: String     │
│ - birthDate: Date  │
├────────────────────┤
│ + getAge(): int    │
└────────────────────┘
         △
         │
    ┌────┴────┐
    │         │
┌───┴──────┐ ┌┴────────────┐
│ Student  │ │ Teacher     │
├──────────┤ ├─────────────┤
│ -学号    │ │ -工号       │
│ -专业    │ │ -职称       │
├──────────┤ ├─────────────┤
│ +选课()  │ │ +授课()     │
└──────────┘ └─────────────┘
     │                │
     │ 0..*      0..* │
     │                │
     └──── Course ────┘
         (课程)

2. 用例图 (Use Case Diagram)

用例图描述系统功能和参与者之间的交互。

组成元素

参与者 (Actor)

  • 与系统交互的外部实体
  • 用小人图标表示

用例 (Use Case)

  • 系统提供的功能
  • 用椭圆表示

关系

  • 关联: 参与者与用例之间
  • 包含 (include): 必须执行的子用例
  • 扩展 (extend): 可选执行的用例
  • 泛化: 用例或参与者之间的继承
示例
复制代码
               图书管理系统
         ┌──────────────────────┐
         │                      │
读者 ─── │  (搜索图书)          │
         │      │               │
         │      │ <<include>>   │
         │      ↓               │
         │  (查看图书详情)      │
         │                      │
         │  (借阅图书)          │
         │      │               │
         │      │ <<extend>>    │
         │      ↓               │
         │  (续借图书)          │
         │                      │
图书管理员 ─ (添加图书)          │
         │  (删除图书)          │
         └──────────────────────┘

3. 序列图 (Sequence Diagram)

序列图展示对象之间的交互顺序和时间关系。

组成元素
  • 对象/参与者
  • 生命线
  • 消息
  • 激活框
示例
复制代码
用户      控制器      服务层      数据库
 │          │          │          │
 │─登录请求→│          │          │
 │          │          │          │
 │          │─验证─→   │          │
 │          │          │          │
 │          │          │─查询用户→│
 │          │          │          │
 │          │          │←返回数据─│
 │          │          │          │
 │          │←验证结果─│          │
 │          │          │          │
 │←登录成功─│          │          │
 │          │          │          │

4. 活动图 (Activity Diagram)

活动图描述业务流程或算法逻辑。

组成元素
  • 开始节点 (●)
  • 活动 (矩形)
  • 决策节点 (◇)
  • 合并节点
  • 分支与汇合
  • 结束节点 (◎)
示例 - 在线购物流程
复制代码
        (●) 开始
         │
         ↓
    [浏览商品]
         │
         ↓
    [添加到购物车]
         │
         ↓
      <选择>
      是否继续购物?
       /     \
     是/       \否
     /          \
    ↓            ↓
[继续购物]    [结算]
    │            │
    └────→       ↓
            [选择支付方式]
                 │
                 ↓
              <支付>
              成功?
              /   \
            是/     \否
            /        \
           ↓          ↓
      [生成订单]   [返回重试]
           │            │
           │            │
           ↓            │
      [发送确认]  ←──────┘
           │
           ↓
        (◎) 结束

5. 状态图 (State Machine Diagram)

状态图描述对象在其生命周期内的状态变化。

示例 - 订单状态
复制代码
    [初始] ●
           │
           ↓
    ┌─────────────┐
    │  待支付     │
    └─────────────┘
           │ 支付完成
           ↓
    ┌─────────────┐
    │  待发货     │
    └─────────────┘
           │ 发货
           ↓
    ┌─────────────┐
    │  运输中     │
    └─────────────┘
           │ 签收
           ↓
    ┌─────────────┐
    │  已完成     │
    └─────────────┘
           │
           ↓
          ◎ [结束]

    任意状态 ──取消订单──> [已取消]

6. 组件图 (Component Diagram)

组件图展示系统的物理组件及其依赖关系。

复制代码
┌─────────────────┐
│  Web前端        │
│  (Angular)      │
└────────┬────────┘
         │
         ↓
┌─────────────────┐
│  API网关        │
└────────┬────────┘
         │
    ┌────┴────┐
    ↓         ↓
┌────────┐ ┌───────────┐
│用户服务│ │订单服务   │
└───┬────┘ └─────┬─────┘
    │            │
    └──────┬─────┘
           ↓
    ┌────────────┐
    │  数据库    │
    └────────────┘

7. 部署图 (Deployment Diagram)

部署图展示系统的硬件拓扑和软件组件的物理部署。

复制代码
┌────────────────────────┐
│  客户端浏览器          │
│  <<device>>            │
│  ┌──────────────┐      │
│  │ Web应用      │      │
│  └──────────────┘      │
└───────────┬────────────┘
            │ HTTPS
            ↓
┌────────────────────────┐
│  Web服务器             │
│  <<device>>            │
│  ┌──────────────┐      │
│  │ Nginx        │      │
│  └──────────────┘      │
└───────────┬────────────┘
            │
            ↓
┌────────────────────────┐
│  应用服务器            │
│  <<device>>            │
│  ┌──────────────┐      │
│  │ Spring Boot  │      │
│  └──────────────┘      │
└───────────┬────────────┘
            │ JDBC
            ↓
┌────────────────────────┐
│  数据库服务器          │
│  <<device>>            │
│  ┌──────────────┐      │
│  │ MySQL        │      │
│  └──────────────┘      │
└────────────────────────┘

数据库设计与UML的结合

1. 从类图到数据库表

类图中的每个类通常对应数据库中的一个表,类的属性对应表的字段。

映射规则

基本映射:

复制代码
类图中的类 → 数据库表
类的属性 → 表的字段
类的方法 → 存储过程/业务逻辑层

关系映射:

一对一关系:

复制代码
类图:
Person ──── Passport
(1)         (1)

数据库:
Person表: id, name, passport_id (外键)
Passport表: id, number, issue_date

一对多关系:

复制代码
类图:
Department ────< Employee
(1)             (*)

数据库:
Department表: id, name
Employee表: id, name, department_id (外键)

多对多关系:

复制代码
类图:
Student ──── Course
(*)         (*)

数据库:
Student表: id, name
Course表: id, title
Enrollment表: id, student_id, course_id (中间表)

继承关系映射:

有三种策略:

策略1: 单表继承

复制代码
所有子类存储在一个表中:
Person表: id, name, type, student_major, teacher_title

策略2: 类表继承

复制代码
每个类一个表:
Person表: id, name
Student表: person_id, major
Teacher表: person_id, title

策略3: 具体表继承

复制代码
每个具体类一个表:
Student表: id, name, major
Teacher表: id, name, title

2. 完整示例: 电商系统

类图设计
复制代码
┌──────────────┐          ┌──────────────┐
│   User       │          │   Product    │
├──────────────┤          ├──────────────┤
│ - userId     │          │ - productId  │
│ - username   │          │ - name       │
│ - email      │          │ - price      │
│ - password   │          │ - stock      │
├──────────────┤          ├──────────────┤
│ + register() │          │ + update()   │
│ + login()    │          └──────────────┘
└──────┬───────┘                 │
       │ 1                       │ *
       │                         │
       │ *               *       │
       └──── Order ──────────────┘
           ┌──────────────┐
           │   Order      │
           ├──────────────┤
           │ - orderId    │
           │ - orderDate  │
           │ - totalPrice │
           │ - status     │
           ├──────────────┤
           │ + create()   │
           │ + cancel()   │
           └──────┬───────┘
                  │ 1
                  │
                  │ *
           ┌──────────────┐
           │ OrderItem    │
           ├──────────────┤
           │ - itemId     │
           │ - quantity   │
           │ - price      │
           └──────────────┘
对应的数据库设计
sql 复制代码
-- 用户表
CREATE TABLE users (
    user_id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    email VARCHAR(100) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP
);

-- 商品表
CREATE TABLE products (
    product_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(200) NOT NULL,
    description TEXT,
    price DECIMAL(10, 2) NOT NULL,
    stock INT NOT NULL DEFAULT 0,
    category_id INT,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
    INDEX idx_category (category_id),
    INDEX idx_name (name)
);

-- 订单表
CREATE TABLE orders (
    order_id INT PRIMARY KEY AUTO_INCREMENT,
    user_id INT NOT NULL,
    order_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    total_price DECIMAL(10, 2) NOT NULL,
    status ENUM('pending', 'paid', 'shipped', 'delivered', 'cancelled') DEFAULT 'pending',
    shipping_address TEXT,
    FOREIGN KEY (user_id) REFERENCES users(user_id),
    INDEX idx_user (user_id),
    INDEX idx_status (status),
    INDEX idx_date (order_date)
);

-- 订单明细表
CREATE TABLE order_items (
    item_id INT PRIMARY KEY AUTO_INCREMENT,
    order_id INT NOT NULL,
    product_id INT NOT NULL,
    quantity INT NOT NULL,
    price DECIMAL(10, 2) NOT NULL,
    FOREIGN KEY (order_id) REFERENCES orders(order_id) ON DELETE CASCADE,
    FOREIGN KEY (product_id) REFERENCES products(product_id),
    INDEX idx_order (order_id),
    INDEX idx_product (product_id)
);

-- 商品分类表
CREATE TABLE categories (
    category_id INT PRIMARY KEY AUTO_INCREMENT,
    name VARCHAR(100) NOT NULL,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES categories(category_id)
);

实战案例: 图书馆管理系统

需求分析

功能需求:

  • 读者管理: 注册、登录、信息维护
  • 图书管理: 添加、删除、修改、查询
  • 借阅管理: 借书、还书、续借
  • 预约管理: 预约图书
  • 罚款管理: 超期罚款计算

用例图

复制代码
┌────────────────────────────────────┐
│       图书馆管理系统               │
│                                    │
│  读者          ┌─────────────┐    │
│   │────────────│ 搜索图书    │    │
│   │            └─────────────┘    │
│   │            ┌─────────────┐    │
│   │────────────│ 借阅图书    │    │
│   │            └─────────────┘    │
│   │            ┌─────────────┐    │
│   │────────────│ 归还图书    │    │
│   │            └─────────────┘    │
│   │            ┌─────────────┐    │
│   └────────────│ 预约图书    │    │
│                └─────────────┘    │
│                                    │
│  管理员        ┌─────────────┐    │
│   │────────────│ 管理图书    │    │
│   │            └─────────────┘    │
│   │            ┌─────────────┐    │
│   │────────────│ 管理读者    │    │
│   │            └─────────────┘    │
│   │            ┌─────────────┐    │
│   └────────────│ 统计报表    │    │
│                └─────────────┘    │
└────────────────────────────────────┘

类图设计

复制代码
┌──────────────────┐
│   User           │
├──────────────────┤
│ - userId         │
│ - username       │
│ - password       │
│ - userType       │
├──────────────────┤
│ + login()        │
│ + logout()       │
└────────△─────────┘
         │
    ┌────┴────┐
    │         │
┌───┴────┐ ┌──┴──────┐
│ Reader │ │ Admin   │
├────────┤ ├─────────┤
│ -name  │ │ -level  │
│ -email │ └─────────┘
│ -phone │
│ -limit │
└───┬────┘
    │ 1
    │
    │ *
┌───┴──────────┐
│ BorrowRecord │
├──────────────┤
│ - recordId   │
│ - borrowDate │
│ - dueDate    │
│ - returnDate │
│ - status     │
└──────┬───────┘
       │ *
       │
       │ 1
┌──────┴───────┐
│   Book       │
├──────────────┤
│ - bookId     │
│ - isbn       │
│ - title      │
│ - author     │
│ - publisher  │
│ - category   │
│ - status     │
├──────────────┤
│ + search()   │
└──────────────┘

数据库设计

sql 复制代码
-- 用户基础表
CREATE TABLE users (
    user_id INT PRIMARY KEY AUTO_INCREMENT,
    username VARCHAR(50) UNIQUE NOT NULL,
    password VARCHAR(255) NOT NULL,
    user_type ENUM('reader', 'admin') NOT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- 读者信息表
CREATE TABLE readers (
    reader_id INT PRIMARY KEY,
    name VARCHAR(100) NOT NULL,
    email VARCHAR(100),
    phone VARCHAR(20),
    address TEXT,
    borrow_limit INT DEFAULT 5,
    current_borrowed INT DEFAULT 0,
    FOREIGN KEY (reader_id) REFERENCES users(user_id)
);

-- 管理员信息表
CREATE TABLE admins (
    admin_id INT PRIMARY KEY,
    admin_level INT DEFAULT 1,
    department VARCHAR(100),
    FOREIGN KEY (admin_id) REFERENCES users(user_id)
);

-- 图书分类表
CREATE TABLE categories (
    category_id INT PRIMARY KEY AUTO_INCREMENT,
    category_name VARCHAR(100) NOT NULL,
    parent_id INT,
    FOREIGN KEY (parent_id) REFERENCES categories(category_id)
);

-- 图书表
CREATE TABLE books (
    book_id INT PRIMARY KEY AUTO_INCREMENT,
    isbn VARCHAR(20) UNIQUE,
    title VARCHAR(200) NOT NULL,
    author VARCHAR(100),
    publisher VARCHAR(100),
    publish_date DATE,
    category_id INT,
    total_copies INT DEFAULT 1,
    available_copies INT DEFAULT 1,
    location VARCHAR(50),
    status ENUM('available', 'borrowed', 'reserved', 'maintenance') DEFAULT 'available',
    FOREIGN KEY (category_id) REFERENCES categories(category_id),
    INDEX idx_title (title),
    INDEX idx_author (author),
    INDEX idx_isbn (isbn)
);

-- 借阅记录表
CREATE TABLE borrow_records (
    record_id INT PRIMARY KEY AUTO_INCREMENT,
    reader_id INT NOT NULL,
    book_id INT NOT NULL,
    borrow_date DATE NOT NULL,
    due_date DATE NOT NULL,
    return_date DATE,
    status ENUM('borrowed', 'returned', 'overdue') DEFAULT 'borrowed',
    fine_amount DECIMAL(10, 2) DEFAULT 0.00,
    FOREIGN KEY (reader_id) REFERENCES readers(reader_id),
    FOREIGN KEY (book_id) REFERENCES books(book_id),
    INDEX idx_reader (reader_id),
    INDEX idx_book (book_id),
    INDEX idx_status (status)
);

-- 预约表
CREATE TABLE reservations (
    reservation_id INT PRIMARY KEY AUTO_INCREMENT,
    reader_id INT NOT NULL,
    book_id INT NOT NULL,
    reservation_date TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    status ENUM('pending', 'notified', 'fulfilled', 'cancelled') DEFAULT 'pending',
    FOREIGN KEY (reader_id) REFERENCES readers(reader_id),
    FOREIGN KEY (book_id) REFERENCES books(book_id),
    INDEX idx_reader (reader_id),
    INDEX idx_book (book_id)
);

-- 罚款表
CREATE TABLE fines (
    fine_id INT PRIMARY KEY AUTO_INCREMENT,
    record_id INT NOT NULL,
    amount DECIMAL(10, 2) NOT NULL,
    reason VARCHAR(200),
    paid BOOLEAN DEFAULT FALSE,
    payment_date DATE,
    FOREIGN KEY (record_id) REFERENCES borrow_records(record_id)
);

触发器示例

sql 复制代码
-- 借书时更新图书可用数量
DELIMITER //
CREATE TRIGGER after_borrow_insert
AFTER INSERT ON borrow_records
FOR EACH ROW
BEGIN
    UPDATE books 
    SET available_copies = available_copies - 1
    WHERE book_id = NEW.book_id;
    
    UPDATE readers 
    SET current_borrowed = current_borrowed + 1
    WHERE reader_id = NEW.reader_id;
END//
DELIMITER ;

-- 还书时更新图书可用数量
DELIMITER //
CREATE TRIGGER after_return_update
AFTER UPDATE ON borrow_records
FOR EACH ROW
BEGIN
    IF NEW.return_date IS NOT NULL AND OLD.return_date IS NULL THEN
        UPDATE books 
        SET available_copies = available_copies + 1
        WHERE book_id = NEW.book_id;
        
        UPDATE readers 
        SET current_borrowed = current_borrowed - 1
        WHERE reader_id = NEW.reader_id;
    END IF;
END//
DELIMITER ;

存储过程示例

sql 复制代码
-- 借书存储过程
DELIMITER //
CREATE PROCEDURE borrow_book(
    IN p_reader_id INT,
    IN p_book_id INT,
    OUT p_result VARCHAR(100)
)
BEGIN
    DECLARE v_available INT;
    DECLARE v_current_borrowed INT;
    DECLARE v_borrow_limit INT;
    
    -- 检查图书是否可借
    SELECT available_copies INTO v_available
    FROM books WHERE book_id = p_book_id;
    
    -- 检查读者借阅限制
    SELECT current_borrowed, borrow_limit INTO v_current_borrowed, v_borrow_limit
    FROM readers WHERE reader_id = p_reader_id;
    
    IF v_available <= 0 THEN
        SET p_result = '图书不可借';
    ELSEIF v_current_borrowed >= v_borrow_limit THEN
        SET p_result = '已达借阅上限';
    ELSE
        INSERT INTO borrow_records (reader_id, book_id, borrow_date, due_date)
        VALUES (p_reader_id, p_book_id, CURDATE(), DATE_ADD(CURDATE(), INTERVAL 30 DAY));
        
        SET p_result = '借阅成功';
    END IF;
END//
DELIMITER ;

最佳实践

1. 数据库设计最佳实践

命名规范
  • 使用小写字母和下划线
  • 表名使用复数形式或保持一致性
  • 使用有意义的列名
  • 主键统一命名为 id表名_id
  • 外键命名为 关联表名_id
性能优化
  • 为经常查询的字段建立索引
  • 避免使用 SELECT *
  • 使用适当的数据类型
  • 对大表进行分区
  • 定期分析和优化查询
安全性
  • 使用参数化查询防止SQL注入
  • 实施最小权限原则
  • 加密敏感数据
  • 定期备份数据
  • 审计日志记录
可维护性
  • 添加适当的注释
  • 使用视图简化复杂查询
  • 文档化数据库设计
  • 版本控制数据库变更

2. UML建模最佳实践

保持简洁
  • 一个图表达一个主要思想
  • 避免过度复杂的图
  • 使用适当的抽象级别
一致性
  • 统一命名约定
  • 保持风格一致
  • 使用标准UML符号
实用性
  • 根据受众调整详细程度
  • 关注重要的业务逻辑
  • 及时更新文档

3. 从UML到数据库的转换技巧

识别实体
  • 类图中的持久化类对应数据库表
  • 临时类不需要映射到表
  • 值对象可以内嵌到主表
处理继承
  • 根据查询需求选择合适的继承策略
  • 单表继承适合子类少且差异小的情况
  • 类表继承适合子类多且差异大的情况
优化关系
  • 多对多关系必须使用中间表
  • 一对一关系可以考虑合并表
  • 一对多关系在"多"方添加外键
添加技术字段
sql 复制代码
-- 常用的技术字段
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
created_by INT,
updated_by INT,
is_deleted BOOLEAN DEFAULT FALSE,  -- 软删除
version INT DEFAULT 1  -- 乐观锁

4. 常见陷阱和解决方案

过度规范化

问题 : 表过多导致查询复杂
解决: 适当反规范化,添加冗余字段

缺少索引

问题 : 查询性能差
解决: 为经常查询和关联的字段建立索引

忽视数据完整性

问题 : 数据不一致
解决: 使用外键约束、检查约束、触发器

缺乏扩展性

问题 : 需求变化时难以修改
解决: 预留扩展字段,使用配置表


工具推荐

UML建模工具

  1. Enterprise Architect - 专业的UML工具
  2. Visual Paradigm - 功能全面
  3. StarUML - 开源免费
  4. Draw.io - 在线绘图工具
  5. PlantUML - 文本生成UML图

数据库设计工具

  1. MySQL Workbench - MySQL官方工具
  2. Navicat - 支持多种数据库
  3. DbSchema - 可视化数据库设计
  4. DBeaver - 开源数据库工具
  5. PowerDesigner - 企业级建模工具

代码生成工具

  1. MyBatis Generator - 自动生成持久层代码
  2. JPA Buddy - JPA实体生成
  3. Hibernate Tools - Hibernate映射生成

总结

数据库设计和UML建模是软件开发中的重要环节,两者相辅相成:

数据库设计关注:

  • 数据的组织和存储
  • 性能优化
  • 数据完整性和一致性

UML建模关注:

  • 系统的结构和行为
  • 业务逻辑的可视化
  • 团队沟通和文档

结合使用的优势:

  • UML类图可以直接转换为数据库表
  • 用例图帮助理解功能需求
  • 序列图指导事务设计
  • 活动图优化业务流程

掌握这两项技能,能够帮助你设计出结构清晰、性能优良、易于维护的数据库系统。记住,好的设计来自于充分的需求分析和不断的实践优化。


参考资源

相关推荐
codecrafter1232 小时前
MATLAB中的while循环:从入门到精通的完整指南
java·数据库·其他·matlab
程序新视界3 小时前
三种常见的MySQL数据库设计最佳实践
数据库·后端·mysql
寒士obj3 小时前
MyCat实现分库分表
数据库
Savvy..3 小时前
Redis 黑马点评-商户查询缓存
数据库·redis·缓存
可DRAK鸦|・ω・`)3 小时前
ArcGIS数据迁移问题汇总(postgresql)
数据库·postgresql
奶糖 肥晨3 小时前
批量重命名技巧:使用PowerShell一键整理图片文件命名规范
android·服务器·数据库
数据与人4 小时前
MySQL 8.0 InnoDB ReplicaSet 完整配置指南与切换
数据库·mysql·adb
JIngJaneIL5 小时前
图书馆自习室|基于SSM的图书馆自习室座位预约小程序设计与实现(源码+数据库+文档)
java·数据库·vue.js·spring boot·论文·毕设·图书馆自习室
不要再敲了5 小时前
SSM框架下的redis使用以及token认证
数据库·spring boot·redis·缓存·mybatis