Sql 使用外键的数据库规范化

Sql 使用外键的数据库规范化,sql,sql-server,database-normalization,Sql,Sql Server,Database Normalization,我有一个示例表,如下所示,其中存储了一名学生的课程完成状态: Create Table StudentCourseCompletionStatus ( CourseCompletionID int primary key identity(1,1), StudentID int not null, AlgorithmCourseStatus nvarchar(30), DatabaseCourseStatus nvarchar(30), Networkin

我有一个示例表,如下所示,其中存储了一名学生的课程完成状态:

Create Table StudentCourseCompletionStatus
(
    CourseCompletionID int primary key identity(1,1),
    StudentID int not null,
    AlgorithmCourseStatus nvarchar(30),
    DatabaseCourseStatus nvarchar(30),
    NetworkingCourseStatus nvarchar(30),
    MathematicsCourseStatus nvarchar(30),
    ProgrammingCourseStatus nvarchar(30)
)
Insert into StudentCourseCompletionStatus Values (1, 'In Progress', 'In Progress', 'Not Started', 'Completed', 'Completed')
Insert into StudentCourseCompletionStatus Values (2, 'Not Started', 'In Progress', 'Not Started', 'Not Applicable', 'Completed')
现在,作为规范化模式的一部分,我创建了另外两个表-
CourseStatusType
Status
,用于存储课程状态名称和状态

Create Table CourseStatusType
(
    CourseStatusTypeID int primary key identity(1,1),
    CourseStatusType nvarchar(100) not null
)

Insert into CourseStatusType Values ('AlgorithmCourseStatus')
Insert into CourseStatusType Values ('DatabaseCourseStatus')
Insert into CourseStatusType Values ('NetworkingCourseStatus')
Insert into CourseStatusType Values ('MathematicsCourseStatus')
Insert into CourseStatusType Values ('ProgrammingCourseStatus')
Insert into CourseStatusType Values ('OperatingSystemsCourseStatus')
Insert into CourseStatusType Values ('CompilerCourseStatus')

Create Table Status
(
    StatusID int primary key identity(1,1),
    StatusName nvarchar (100) not null
)

Insert into Status Values ('Completed')
Insert into Status Values ('Not Started')
Insert into Status Values ('In Progress')
Insert into Status Values ('Not Applicable')
修改后的表格如下:

Create Table StudentCourseCompletionStatus1
(
    CourseCompletionID int primary key identity(1,1),
    StudentID int not null,
    CourseStatusTypeID int not null CONSTRAINT [FK_StudentCourseCompletionStatus1_CourseStatusType] FOREIGN KEY (CourseStatusTypeID) REFERENCES dbo.CourseStatusType (CourseStatusTypeID),
    StatusID int not null CONSTRAINT [FK_StudentCourseCompletionStatus1_Status] FOREIGN KEY (StatusID) REFERENCES Status (StatusID),
)
我对此没有什么问题:

  • 这是正常化的正确方法吗?旧表非常有助于轻松获取数据-我可以将学生的课程状态存储在一行中,但现在需要5行。有更好的方法吗

  • 将数据从旧表移动到新表似乎不是一件容易的任务。我可以使用查询来实现这一点,还是必须手动实现这一点

  • 感谢您的帮助

    但现在需要5行

    不,还是一排。该行仅包含存储在其他表中的值的标识符

    这有优点也有缺点。以这种方式进行规范化的主要原因之一是为了保护数据的完整性。如果列只是一个字符串,那么任何东西都可以存储在那里。但是,如果与包含有限值集的表存在外键关系,则只能存储其中一个选项。此外,如果要更改选项的文本或添加/删除选项,请在集中的位置执行

    将数据从旧表移动到新表似乎不是一件容易的任务

    没问题。在数据表上创建新的数字列,并使用与每个数据表记录关联的查找表记录的标识符填充这些列。如果它们可以为空,您可以立即将它们设置为外键。如果它们不可为null,则需要先填充它们,然后才能生成外键。验证数据是否正确后,删除旧的非规范化列。完成了

    但现在需要5行

    不,还是一排。该行仅包含存储在其他表中的值的标识符

    这有优点也有缺点。以这种方式进行规范化的主要原因之一是为了保护数据的完整性。如果列只是一个字符串,那么任何东西都可以存储在那里。但是,如果与包含有限值集的表存在外键关系,则只能存储其中一个选项。此外,如果要更改选项的文本或添加/删除选项,请在集中的位置执行

    将数据从旧表移动到新表似乎不是一件容易的任务

    没问题。在数据表上创建新的数字列,并使用与每个数据表记录关联的查找表记录的标识符填充这些列。如果它们可以为空,您可以立即将它们设置为外键。如果它们不可为null,则需要先填充它们,然后才能生成外键。验证数据是否正确后,删除旧的非规范化列。完成了

    但现在需要5行

    不,还是一排。该行仅包含存储在其他表中的值的标识符

    这有优点也有缺点。以这种方式进行规范化的主要原因之一是为了保护数据的完整性。如果列只是一个字符串,那么任何东西都可以存储在那里。但是,如果与包含有限值集的表存在外键关系,则只能存储其中一个选项。此外,如果要更改选项的文本或添加/删除选项,请在集中的位置执行

    将数据从旧表移动到新表似乎不是一件容易的任务

    没问题。在数据表上创建新的数字列,并使用与每个数据表记录关联的查找表记录的标识符填充这些列。如果它们可以为空,您可以立即将它们设置为外键。如果它们不可为null,则需要先填充它们,然后才能生成外键。验证数据是否正确后,删除旧的非规范化列。完成了

    但现在需要5行

    不,还是一排。该行仅包含存储在其他表中的值的标识符

    这有优点也有缺点。以这种方式进行规范化的主要原因之一是为了保护数据的完整性。如果列只是一个字符串,那么任何东西都可以存储在那里。但是,如果与包含有限值集的表存在外键关系,则只能存储其中一个选项。此外,如果要更改选项的文本或添加/删除选项,请在集中的位置执行

    将数据从旧表移动到新表似乎不是一件容易的任务


    没问题。在数据表上创建新的数字列,并使用与每个数据表记录关联的查找表记录的标识符填充这些列。如果它们可以为空,您可以立即将它们设置为外键。如果它们不可为null,则需要先填充它们,然后才能生成外键。验证数据是否正确后,删除旧的非规范化列。完成。

    StudentCourseCompletionStatus1
    中,您仍然需要两个关联到
    Status
    CourseStatusType
    。所以我认为你应该考虑以下的规范化变型:

    这意味着,您的
    StudentCourseCompletionStatus
    将只保存一个CourseStatusID,而另一个表
    CourseStatus
    将保存与
    CourseType
    状态的关联


    要移动数据,您当然可以使用查询。

    StudentCourseCompletionStatus1
    中,您仍然需要两个关联到
    Status
    CourseStatusType
    。所以我想你