设计数据库的表

1.1概念须知

1. 主键(Primary Key)

定义

主键是表中一个或多个字段的组合,用于唯一标识表中的每一行记录。主键字段的值必须是唯一的,且不能NULL。一般情况下是一个字段即可,在单个字段无法表示其唯一性是会用复合主键,比如多对多关系关联表中的外键

特点

  1. 唯一性:主键字段的值必须是唯一的,不能有重复值。例如,在学生表中,学生编号(student_id)可以作为主键,因为每个学生的编号是唯一的。
  2. 非空性:主键字段的值不能为NULL。在插入或更新记录时,必须为每个主键字段提供一个值。
  3. 不可变性:主键值一旦确定,通常不应更改,因为主键值的更改可能会影响与其他表的关联关系。

示例

假设有一个学生表(Students),其结构如下:

CREATE TABLE Students (
    student_id INT PRIMARY KEY,  -- 主键字段
    student_name VARCHAR(50),
    age INT,
    class_id INT
);

在这个表中,student_id被定义为主键,用于唯一标识每个学生。 

2. 外键(Foreign Key)

定义

外键是表中的一个字段或字段组合,用于引用另一个表的主键,从而建立两个表之间的关系。外键的作用是确保数据的引用完整性,即外键字段的值必须是被引用表中主键的有效值,或者为NULL

特点

  1. 引用完整性:外键字段的值必须是被引用表中主键的有效值,或者为NULL。例如,如果学生表中的class_id是外键,引用班级表(Classes)的class_id,那么class_id的值必须在班级表中存在。
  2. 依赖性:外键字段的值依赖于被引用表的主键值。如果被引用表中的主键值被删除或更改,外键字段的值也会受到影响。
  3. 级联操作:在某些情况下,可以设置外键的级联操作,如级联删除(ON DELETE CASCADE)或级联更新(ON UPDATE CASCADE)。例如,如果删除了一个班级,可以设置级联删除,自动删除所有引用该班级的学生记录。

示例

假设有一个班级表(Classes)和学生表(Students),其结构如下:

CREATE TABLE Classes (
    class_id INT PRIMARY KEY,  -- 班级表的主键
    class_name VARCHAR(50)
);

CREATE TABLE Students (
    student_id INT PRIMARY KEY,  -- 学生表的主键
    student_name VARCHAR(50),
    age INT,
    class_id INT,
    FOREIGN KEY (class_id) REFERENCES Classes(class_id)  -- 外键字段
);

1.2数据实体间的关系

  1. 一对一关系
  • 这种关系比较少见。例如,一个学校只有一个校长,一个校长只管理一个学校。在设计表时,可以在任意一个表中添加另一个表的主键作为外键。比如学校表(school)的主键是school_id,校长表(principal)的主键是principal_id,可以在校长表中添加school_id作为外键,也可以在学校表中添加principal_id作为外键。一般选择在业务操作更频繁的表中添加外键,如果经常通过学校查找校长信息,就在校长表中添加school_id外键。
  1. 一对多关系
    • 这是最常见的关系类型。例如,一个班级有多个学生,但一个学生只属于一个班级。在这种情况下,在“多”的一方的表中添加“一”的一方表的主键作为外键。班级表(class)的主键是class_id,学生表(student)的主键是student_id,那么在学生表中添加class_id作为外键。这样可以通过class_id将学生和班级关联起来,方便查询某个班级的所有学生等操作。
  1. 多对多关系
    • 例如,学生和课程之间的关系。一个学生可以选修多门课程,一门课程也可以被多个学生选修。对于这种关系,需要创建一个关联表(也叫连接表或中间表)。关联表通常包含两个主表的主键作为外键。可以创建一个选修表(enrollment),在选修表中有student_id和course_id两个字段,它们分别作为学生表和课程表的外键。同时,这个关联表还可以添加其他属性,如成绩(score)等信息。

1.3设计数据库的表

1. 确定主键

非关联表主键设计:

把握主键特性,唯一,非Null,不可改变等特性即可,类比身份证号。

关联表主键设计:

    1. 一种是将两个外键组合成复合主键
    2. 新建一个单独的主键

2. 确定外键

    1. 外键的数据类型和长度要与被引用的主键完全一致
    2. 要设置外键约束,以保证数据的完整性,例如外键引用其他表的主键
    3. 当被引用的主键记录被删除时,可以设置级联删除(关联表中对应的记录也会被删除)或者设置为禁止删除(除非先删除关联表中的记录)等操作

3. 确定其他字段

  1. 自己表本身需要的字段,比如学生的姓名班级课程等等
  2. 关联表中的其他字段也可以引用进来

4. 考虑数据库的完整性约束

  1. 实体完整性
    • 确保每个表都有主键,主键值必须唯一且非空。在设计关联表时,无论是作为主表还是关联表,都要遵循这个原则。例如,在学生表中,student_id作为主键,数据库系统会自动保证每个学生的student_id是唯一的,且在插入数据时不能插入空值。
  1. 参照完整性
    • 这是通过外键约束来实现的。在外键字段中,只能插入被引用表中存在的主键值,或者插入空值(如果外键字段允许为空)。例如,在选修表中插入数据时,student_id和course_id必须是学生表和课程表中存在的主键值,否则插入操作会失败。这样可以保证关联表中的数据与被关联表中的数据保持一致,避免出现孤立的记录。
  1. 用户定义的完整性
    • 根据业务规则添加约束。例如,在选修表中,成绩字段score的值应该在0 - 100之间,可以在数据库表结构中设置检查约束(CHECK约束),如CHECK (score >= 0 AND score <= 100),以确保数据符合业务逻辑。

5. 优化关联表设计

  1. 索引优化
    • 在关联表的外键字段上创建索引。因为关联查询经常会在外键字段上进行连接操作,索引可以加快连接速度。例如,在选修表的student_id和course_id上创建索引,当执行类似SELECT * FROM students JOIN enrollment ON students.student_id = enrollment.student_id;这样的查询时,数据库可以利用索引快速找到匹配的记录。
    • 对于多对多关系的关联表,如果查询经常基于某个属性字段(如成绩),也可以在这个字段上创建索引。但是要注意,索引会占用额外的存储空间,并且在插入、更新和删除数据时会增加维护索引的开销,所以要合理创建索引。
  1. 表结构简化
    • 避免在关联表中添加过多冗余字段。例如,在选修表中,不需要添加学生的姓名和课程的名称等冗余信息,这些信息可以通过关联学生表和课程表来获取。过多的冗余字段会增加存储空间的浪费,并且在数据更新时需要同步更新多个地方,容易出现数据不一致的情况。

6. 示例

我们有三个表:

  1. 学生表(Students:存储学生的基本信息。
  2. 课程表(Courses:存储课程的基本信息。
  3. 选修表(Enrollments:存储学生选修课程的记录,使用复合主键来确保唯一性。
--学生表
CREATE TABLE Students (
    student_id INT,
    student_name VARCHAR(50),
    age INT,
    PRIMARY KEY (student_id)  -- 主键
);
--课程表
CREATE TABLE Courses (
    course_id INT,
    course_name VARCHAR(50),
    PRIMARY KEY (course_id)  -- 主键
);
--选修表
CREATE TABLE Enrollments (
    student_id INT,
    course_id INT,
    grade CHAR(2),  -- 学生在这门课程的成绩
    PRIMARY KEY (student_id, course_id),  -- 复合主键
    FOREIGN KEY (student_id) REFERENCES Students(student_id),  -- 外键引用学生表
    FOREIGN KEY (course_id) REFERENCES Courses(course_id)  -- 外键引用课程表
);

猜你喜欢

转载自blog.csdn.net/MEABUG/article/details/145269562
今日推荐