2

我有一张名为interests每个学生的学校科目的表格。

学生必须至少有 3 个学科兴趣,最多 7 个。

可能的主题兴趣是:

  • 科学
  • 数学
  • 英语
  • 历史
  • 艺术
  • 体育
  • 外语

但是,在我的两种表格设计中,我都无法弄清楚如何规范化表格。


第一个表:interests(8列)

student_id(pk) | interest_1 | interest_2 | ... | interest_7

在这个设计interests_1interest_7是列。如果一个学生选择科学、数学和英语作为他的兴趣,那么

  • interest_1被设定为science
  • interest_2被设定为math
  • interest_3被设定为english
  • interest_4设置interest_7null

第二个表:interests(8列)

student_id(pk) | science | math | english | ... | foreign_lanaguage

在这个设计中,学校科目现在是列。如果学生的兴趣是科学、数学和英语,则这些列设置为true,其余列设置为false

  • science被设定为true
  • math被设定为true
  • english被设定为true
  • history被设定为false
  • art被设定为false
  • physical_education被设定为false
  • foreign_language被设定为false

我还能如何设计这张桌子?

而且,我如何只选择特定学生感兴趣的科目?

4

3 回答 3

3

这实际上取决于您想要的可扩展性。一方面,您的设计有效。

另一方面,如果要添加新类,则必须进入并修改表。

另一种方法是有 3 个表:

学生 证、姓名

ID、名称

StudentInterrests ID、StudentID、ClassID

如果学生班级组合没有出现在 studentinterrests 表中,则他们对课程不感兴趣

您选择的学生兴趣如下所示:

SELECT StudentName, CourseName
FROM Student
LEFT JOIN StudentInterrests ON Student.ID = StudentInterrests.StudentID
LEFT JOIN Class ON StudentInterrests.ClassID = Class.ID

您的结果将是:
John、Math
John、English
John、SocialStudies

对于您的最小和最大要求:我建议将要求放在应用程序级别,因为它似乎比对数据库的约束更多的是应用程序逻辑。

于 2012-11-10T01:38:44.987 回答
0

好的,为了满足您的要求,您的设计将起作用。我看到另外两个可以满足给定规范的易于实现的选项。

1.) 7个兴趣表外键为兴趣表的学生表;使用一组独特的约束来确保没有学生有两个相同的兴趣。使用可为空的外键并允许在项目 4-7 上使用空值。

2.) 打破利益表。该规则的工作原理 99% 相同,尽管强制性兴趣只会在选择兴趣后触发约束(因此学生可以有 0 或 3-8 个兴趣)。这是一种稍微合理的方法,因此您可以将学生表与兴趣分开填充。这使事情具有可扩展性。

这两种方法都属于第三范式,适用于符合 ANSI-92 的数据库。SQL server 中#2 的示例实现如下。

表格布局

USE [DB]
GO
/****** Object:  Table [dbo].[Interests]    Script Date: 11/9/2012 8:32:39 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Interests](
    [interestID] [int] IDENTITY(1,1) NOT NULL,
    [interestText] [varchar](255) NOT NULL,
    [interestDescription] [varchar](max) NULL,
 CONSTRAINT [PK_Interests] PRIMARY KEY CLUSTERED 
(
    [interestID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
/****** Object:  Table [dbo].[StudentInterests]    Script Date: 11/9/2012 8:32:39 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
CREATE TABLE [dbo].[StudentInterests](
    [studentInterestID] [int] IDENTITY(1,1) NOT NULL,
    [studentID] [int] NOT NULL,
    [interestID_1] [int] NOT NULL,
    [interestID_2] [int] NOT NULL,
    [interestID_3] [int] NOT NULL,
    [interestID_4] [int] NULL,
    [interestID_5] [int] NULL,
    [interestID_6] [int] NULL,
    [interestID_7] [int] NULL,
    [interestID_8] [int] NULL,
 CONSTRAINT [PK_StudentInterests] PRIMARY KEY CLUSTERED 
(
    [studentInterestID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_1] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_1] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_2] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_2] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_3] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_3] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_4] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_4] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_4] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_5] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_5] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_6] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_6] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_7] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_7] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_8] UNIQUE NONCLUSTERED 
(
    [studentInterestID] ASC,
    [interestID_8] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_StudentInterests_9] UNIQUE NONCLUSTERED 
(
    [studentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
/****** Object:  Table [dbo].[Students]    Script Date: 11/9/2012 8:32:39 PM ******/
SET ANSI_NULLS ON
GO
SET QUOTED_IDENTIFIER ON
GO
SET ANSI_PADDING ON
GO
CREATE TABLE [dbo].[Students](
    [studentID] [int] IDENTITY(1,1) NOT NULL,
    [firstName] [varchar](255) NOT NULL,
    [lastName] [varchar](255) NOT NULL,
 CONSTRAINT [PK_Students] PRIMARY KEY CLUSTERED 
(
    [studentID] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY]
) ON [PRIMARY]

GO
SET ANSI_PADDING OFF
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests] FOREIGN KEY([interestID_1])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests1] FOREIGN KEY([interestID_2])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests1]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests2] FOREIGN KEY([interestID_3])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests2]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests3] FOREIGN KEY([interestID_4])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests3]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests4] FOREIGN KEY([interestID_5])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests4]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests5] FOREIGN KEY([interestID_6])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests5]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests6] FOREIGN KEY([interestID_7])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests6]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Interests7] FOREIGN KEY([interestID_8])
REFERENCES [dbo].[Interests] ([interestID])
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Interests7]
GO
ALTER TABLE [dbo].[StudentInterests]  WITH CHECK ADD  CONSTRAINT [FK_StudentInterests_Students] FOREIGN KEY([studentID])
REFERENCES [dbo].[Students] ([studentID])
ON DELETE CASCADE
GO
ALTER TABLE [dbo].[StudentInterests] CHECK CONSTRAINT [FK_StudentInterests_Students]
GO
于 2012-11-10T02:34:19.687 回答
0

规范化时,为您正在创建的每个表识别正确的主键很重要。将字段分解为最基本的形式。你有什么?你有 student_id 和兴趣。由于兴趣可以是真或假,您可以将兴趣的名称存储在与其他兴趣相同的列中,因此如果它们不存在于学生 ID 上,则该学生对它们不感兴趣。

这是一个家庭作业问题,所以为你解决这个问题似乎很愚蠢。相反,我会让你走上正轨。student_id 不是您要查找的主键,而是一个索引。您正在寻找最理想的数据结构的 3 列表。

于 2012-11-10T01:36:11.053 回答