如何设计这个表更好?

时间:2012-11-10 01:24:49

标签: mysql sql database database-design

我为每个学生准备了一份名为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_4interest_7设置为null

第二张表: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

我还能如何设计这张表?

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

3 个答案:

答案 0 :(得分:3)

这实际上取决于您希望的扩展程度。一方面你的设计有效。

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

另一种方法是拥有3个表:

学生 ID,姓名

ID,名称

StudentInterrests ID,StudentID,ClassID

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

您选择的学生兴趣看起来像这样:

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

你的结果是:
John,Math
约翰,英语
John,SocialStudies

满足您的最低和最高要求:我建议将需求放在应用程序级别,因为它看起来比应用程序逻辑更多,而不是对数据库的约束。

答案 1 :(得分:0)

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

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

答案 2 :(得分:0)

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

1。)具有7个利益的学生表以外键密钥到兴趣表;使用一组独特的约束来确保没有学生有两个相同的兴趣。使用可为空的外键并允许第4-7项使用空值。

2。)打破利益表。虽然强制性利益只会在选择利益后触发约束(因此学生可以拥有0 OR 3-8利益),因此该规则的工作效率为99%。这是一种稍微合理的方法,因此您可以将学生表与兴趣分开填充。这可以保持可扩展性。

这两种方法都是第三种常规形式,可以使用ANSI-92兼容的数据库。 SQL Server中#2的示例实现如下。

Table layout

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