数据库设计

devtools/2025/2/12 11:37:23/

文章目录

    • MySQL系列:
    • 第一范式
    • 第二范式
    • 第三范式
    • 数据库设计过程
      • (一)、实例之间的关系
      • (二)、数据库设计过程
      • (三)、实体-关系图(ER 图)
      • (四)、代码实现:

MySQL系列:

初识MySQL,MySQL常用数据类型和表的操作,增删改查(CRUD)操作(总),数据库约束

第一范式

第一范式(1NF)要求每个列都是原子性的,不可再分。

比如,如果一个表中有个字段存储多个值,像电话号码有多个,这就不符合1NF。应该拆分成多行或者多个字段。不过,可能用户需要具体的例子,比如订单表,如果订单中的产品被放在一个字段里用逗号分隔,这就不符合1NF。拆分后每个产品单独一行,这样每个字段都是单一的。

不符合第一范式的列子:
在这里插入图片描述
当不能再拆分时满足第一范式:
在这里插入图片描述

第二范式

第二范式 (2NF):消除部分依赖
规则:在满足 1NF 的基础上,所有非主属性必须完全依赖于主键(不存在部分依赖)。

例子:不符合 2NF 的表,假设有一个 订单明细表,主键是 订单ID + 产品ID:

订单ID 产品ID 产品名称 数量 订单日期
1001 P001 手机 2 2023-10-01
1001 P002 耳机 1 2023-10-01
问题:
产品名称 仅依赖于 产品ID(部分依赖主键)。
订单日期 仅依赖于 订单ID(部分依赖主键)。

改进为符合 2NF,拆分表,消除部分依赖:

订单表(主键:订单ID):
订单ID 订单日期
1001 2023-10-01

产品表(主键:产品ID):
产品ID 产品名称
P001 手机
P002 耳机

订单明细表(主键:订单ID + 产品ID):
订单ID 产品ID 数量
1001 P001 2
1001 P002 1
现在所有非主属性完全依赖主键。

第三范式

第三范式 (3NF):消除传递依赖
规则:在满足 2NF 的基础上,非主属性不能依赖于其他非主属性(即消除传递依赖)。

例子:不符合 3NF 的表,假设有一个 学生信息表:

学生ID 学生姓名 学院 学院电话
1 张三 计算机 010-12345678
2 李四 物理 010-87654321
问题:学院电话 依赖于 学院,而 学院 又依赖于 学生ID,形成传递依赖。

改进为符合 3NF:拆分表,消除传递依赖:

学生表(主键:学生ID):
学生ID 学生姓名 学院
1 张三 计算机
2 李四 物理

学院表(主键:学院):
学院 学院电话
计算机 010-12345678
物理 010-87654321
现在 学院电话 直接依赖于主键 学院。

数据库设计过程

(一)、实例之间的关系

  1. 用户与账户的一对一关系
    关系描述:一个用户对应一个账户,一个账户也只能属于一个用户。
    实现方式:
    在 users 表中添加 account_id 外键(唯一约束),指向 account 表的主键 id。
    通过外键确保用户和账户的严格一对一绑定。

  2. 学生与班级的一对多关系
    关系描述:一个班级可以包含多个学生,但一个学生只能属于一个班级。
    实现方式:
    在 student 表中添加 class_id 外键,指向 class 表的主键 id。
    通过外键将学生与班级关联,实现“一对多”关系。

  3. 学生、课程与成绩的多对多关系
    关系描述:
    一个学生可以选修多门课程。
    一门课程可以被多个学生选修。
    每个学生的每门课程对应一个成绩。
    实现方式:
    创建中间表 score,包含 student_id 和 course_id 作为联合主键,并存储成绩。
    通过外键关联 student 和 course 表,实现多对多关系。

(二)、数据库设计过程

  1. 需求分析
    业务需求:
    用户与账户需一对一绑定。
    学生需按班级分类。
    学生可选修多门课程,并记录每门课程的成绩。
    数据实体:
    用户(users)、账户(account)、班级(class)、学生(student)、课程(course)、成绩(score)。

  2. 规范化设计
    第一范式 (1NF):
    确保字段原子性,例如:
    phone_num 存储单个手机号(varchar(11)),而非多个值。
    score 表拆分为单独的中间表,避免多值存储。
    第二范式 (2NF):
    消除部分依赖:
    score 表中的 score 字段完全依赖于联合主键 (student_id, course_id)。
    users 表的 account_id 完全依赖于主键 id。
    第三范式 (3NF):
    消除传递依赖:
    避免在 student 表中直接存储年龄(age),而是存储出生日期(birthdate),通过计算得到年龄。
    若班级表中需要存储班主任信息,需拆分为 class 表和 teacher 表,避免传递依赖。

3.具体设计步骤
步骤 1:定义实体和属性
用户(users):id、name、nickname、phone_num、email、gender、account_id。
账户(account):id、username、password。
班级(class):id、name。
学生(student):id、name、sno、birthdate、gender、enroll_date、class_id。
课程(course):id、name。
成绩(score):student_id、course_id、score。

步骤 2:建立关系
一对一:users.account_id → account.id。
一对多:student.class_id → class.id。
多对多:score.student_id → student.id,score.course_id → course.id。。

(三)、实体-关系图(ER 图)

  1. 实体定义
    用户(users):
    主键:id
    属性:name、nickname、phone_num、email、gender、account_id(外键)。
    账户(account):
    主键:id
    属性:username、password。
    班级(class):
    主键:id
    属性:name。
    学生(student):
    主键:id
    属性:name、sno、birthdate、gender、enroll_date、class_id(外键)。
    课程(course):
    主键:id
    属性:name。
    成绩(score):
    主键:(student_id, course_id)
    属性:score。
  2. 关系图示
    ±------------+ ±------------+
    | account | | users |
    |-------------| 1 1 |-------------|
    | id (PK) |<--------| account_id |
    | username | | name |
    | password | | nickname |
    ±------------+ ±------------+

    |
    | 1
    ±------------+ ±------------+
    | student | | class |
    |-------------| N 1 |-------------|
    | id (PK) |-------->| id (PK) |
    | name | | name |
    | sno | ±------------+
    | birthdate |
    | gender |
    | enroll_date |
    ±------------+

    |
    | N
    ±------------+ ±------------+
    | score | | course |
    |-------------| N 1 |-------------|
    | student_id |-------->| id (PK) |
    | course_id |-------->| name |
    | score | ±------------+
    ±------------+
  3. 关系说明
    用户 ↔ 账户:通过 users.account_id 实现一对一关联。
    学生 ↔ 班级:通过 student.class_id 实现一对多关联。
    学生 ↔ 课程:通过中间表 score 实现多对多关联。

(四)、代码实现:

#1.用户与账户的一对一
#在用户实体中添加对账户实体的关联
#账户表
drop table if exists account;
create table account(
id bigint primary key auto_increment,
username varchar(20) not null,
password varchar(32) not null
);
#用户表
drop table if exists users;
create table users(
id bigint primary key auto_increment,
name varchar(20) not null,
nickname varchar(20) comment'昵称',
phone_num varchar(11) comment'手机号',
email varchar(30) comment'邮箱编号',
gender tinyint(1) comment'性别',
account_id bigint,
foreign key(account) references account(id)
);# 在账户实体中添加对用户实体的关联
drop table if exists users;
create table users(
id bigint primary key auto_increment,
name varchar(20) not null,
nickname varchar(20),
phone_num varchar(20),
email varchar(30),
gender tinyint(1),
);
drop table if exists account;
create table account(
id bigint primary key auto_increment,
username varchar(20) not null,
password varchar(32) not null,
users_id bigint,
foreign key(users_id) references users(id)
);#2.学生与班级的一对多
#班级表
drop table if exists class;
create table class(
id bigint primary key auto_increment,
name varchar(20)
);
#学生表
drop table if exists student;
create table student(
id bigint primary key auto_increment,
name varchar(20) not null,
sno varchar(10) not null comment'学号',
age int default 18,
gender tinyint(1),
enroll_date date comment'入学日期',
class_id bigint,
foreign key(class_id) references class(id)
);#学生,课程与成绩的多对多关系
drop table if exists student;
create table student(
id bigint primary key auto_increment,
name varchar(20)not null,
sno varchar(10) not null,
age int default 18,
gender tinyint(1),
enroll_date date,
class_id bigint,
foreign key (class_id) references class(id)
);
#课程表
drop table if exists course;
create table course(
id bigint primary key auto_increment,
name varchar(20)
);
#成绩表
drop table id exists score;
create table score(
id bigint primary key auto_increment,
score float,
student_id bigint,
course_id bigint,
foreign key (student_id) references student(id),
foreign key (course_id) references course(id)
);

http://www.ppmy.cn/devtools/158194.html

相关文章

电脑黑屏按什么键恢复?电脑黑屏的解决办法

电脑黑屏的原因有很多&#xff0c;可能是硬件、软件、系统或者病毒等方面造成的。那么&#xff0c;当我们遇到电脑黑屏时&#xff0c;应该怎么做呢&#xff1f;有没有什么快捷的方法可以恢复正常呢&#xff1f;本文将为您介绍一些常见的电脑黑屏情况及其解决办法。 一、电脑开机…

数据库开发常识(10.6)——SQL性能判断标准及索引误区(1)

10.6. 数据库开发常识 作为一名专业数据库开发人员,不但需要掌握数据库开发相关的语法和功能实现,还要掌握专业数据库开发的常识。这样,才能在保量完成工作任务的同时,也保质的完成工作任务,避免了为应用的日后维护埋下性能和稳定性方面的隐患。可遗憾的是,现实中,很大…

C# COM 组件在.NET 平台上的编程介绍

.NET学习资料 .NET学习资料 .NET学习资料 一、COM 组件简介 COM&#xff08;Component Object Model&#xff09;即组件对象模型&#xff0c;是一种微软提出的软件组件技术&#xff0c;它允许不同的软件模块在二进制层面进行交互。COM 组件可以用多种编程语言开发&#xff0…

机器学习实战(零基础到精通)

1. 机器学习实战概述 1.1 机器学习定义与应用场景 机器学习是人工智能的一个重要分支&#xff0c;它使计算机系统能够从数据中自动学习并改进。其定义可以追溯到阿瑟塞缪尔在 1959 年的描述&#xff1a;“机器学习是让计算机无需明确编程就能学习的领域。”如今&#xff0c;机…

MySQL中DDL操作是否支持事务

MySQL中DDL不支持事务。 传统MySQL&#xff08;5.7及以前版本&#xff09;&#xff1a; DDL操作不支持事务执行DDL操作时会隐式提交当前会话的事务无法回滚DDL操作 MySQL 8.0版本&#xff1a; 引入了原子DDL特性&#xff08;Atomic DDL&#xff09;DDL操作变为原子性的&…

用Llama Factory单机多卡微调Qwen2.5时报torch.OutOfMemoryError: CUDA out of memory的解决办法

接着上一篇博客&#xff1a;在Ubuntu上用Llama Factory命令行微调Qwen2.5的简单过程_llamafactory 微调qwen 2.5-CSDN博客 如果需要微调比较大的模型&#xff0c;例如Qwen2.5-32B&#xff0c;那么在两个3090上可能不够用&#xff0c;这里我用A60004的服务器。但如果仿照上篇博…

QML非可视控件

目录 1.MouseArea 2.Keys 3.Timer 4.Loader 5.Component 1.MouseArea MouseArea是一个用于处理鼠标事件的不可见组件&#xff0c;通常与可见的项目配合使用&#xff0c;为其提供鼠标交互功能。 属性&#xff1a; enabled&#xff1a;用于设置是否启用鼠标处理&#xff…

PL/SQL 变量以及数据类型(下篇)

目录 二、数据类型 1.复合类型 记录类型 记录类型定义方式 记录类型的操作 表类型 嵌套表 可变数组 记录类型与表类型的区别 2.引用类型&#xff08;未深入研究&#xff09; 3.LOB(long object)类型 LOB类型的种类 4.属性类型(记录类型中已有示例&#xff0c;不过…