将数据插入具有两个关系的列

时间:2018-09-19 15:46:30

标签: sql sql-server foreign-keys relationship erd

因此,我要在此处执行的操作是将数据插入具有“用户名”字段的table1中,并且此“用户名”字段具有两个关系,即转到学生表和教师表。但是,当我将数据插入到用户表中时,我遇到了问题,该问题是由“用户名”字段引起的。这是因为“用户名”字段的数据与学生表中的唯一键不同,并且当我对其进行更改并使数据相同时,我也遇到错误,但是这次的数据与在教师表中是唯一的。因此,是否有可能使此“用户名”字段仅获取表之一,就像学生表和教师表的数据之一位于“用户名”中一样,仍可以使用。也许这是由于ERD不良造成的错误?这是我的ERD,如果您要询问的话:

enter image description here

好吧,我知道这确实是一个非常糟糕的主意,但我使教师表和学生表中的名称成为唯一键,因为如果不这样做,就无法创建外键。拜托,我真的很感谢你的回答。

这是这3个表的ddl:

学生桌:

CREATE TABLE [dbo].[student](
[studentid] [int] IDENTITY(2016000001,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[address] [text] NOT NULL,
[gender] [varchar](7) NOT NULL,
[dateofbirth] [date] NOT NULL,
[nohp] [varchar](13) NOT NULL,


CONSTRAINT [PK_student] 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],


CONSTRAINT [IX_student] UNIQUE NONCLUSTERED 
(
[name] 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

教师桌:

CREATE TABLE [dbo].[teacher](
[teacherid] [int] IDENTITY(1,1) NOT NULL,
[name] [varchar](50) NOT NULL,
[gender] [varchar](7) NOT NULL,

CONSTRAINT [PK_teacher] PRIMARY KEY CLUSTERED 

(
    [teacherid] ASC
)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
 CONSTRAINT [IX_teacher] UNIQUE NONCLUSTERED 
(
    [name] 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

用户表:

CREATE TABLE [dbo].[user](
[userid] [int] IDENTITY(1,1) NOT NULL,
[username] [varchar](50) NOT NULL,
[password] [varchar](20) NOT NULL,
[role] [varchar](10) NOT NULL,
 CONSTRAINT [PK_user] PRIMARY KEY CLUSTERED 
(
    [userid] 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

ALTER TABLE [dbo].[user]  WITH CHECK ADD  CONSTRAINT [FK_user_student] FOREIGN KEY([username])
REFERENCES [dbo].[student] ([name])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[user] CHECK CONSTRAINT [FK_user_student]
GO

ALTER TABLE [dbo].[user]  WITH CHECK ADD  CONSTRAINT [FK_user_teacher] FOREIGN KEY([username])
REFERENCES [dbo].[teacher] ([name])
ON DELETE CASCADE
GO

ALTER TABLE [dbo].[user] CHECK CONSTRAINT [FK_user_teacher]
GO

1 个答案:

答案 0 :(得分:1)

您面临的主要问题是因为您的数据结构不理想。它做了类似阻止您更改某人名字的事情。我整理了一个更简洁的设计示例。这里有很多假设。我假设人们都有姓和名。如果我至少没有指出这一假设并非您总是可以做的,那我将是失职的。 https://www.kalzumeus.com/2010/06/17/falsehoods-programmers-believe-about-names/但是对于学校项目来说,这已经足够了。我还假设这些地址是美国地址。同样,这在许多现实情况下都不可行。最后一个假设是,每个人都可以是男性或女性。在当今世界上,情况并非总是如此,但足以说明这一技术。

这就是我可能会进行此类设计的方式。我建议您不仅盲目地复制它,还可以将其用作使您的设计更正确地标准化的想法。

create table Users
(
    UserID int identity not null
    , FirstName varchar(50) not null
    , LastName varchar(50) not null
    , AddressLine1 varchar(50)
    , AddressLine2 varchar(50)
    , City varchar(50)
    , ST char(2)
    , ZipCode varchar(9)
    , Gender char(1)
    , constraint PK_Users primary key clustered
        (
            UserID
        )
    , constraint CHK_Users_Gender
        CHECK (Gender in ('M', 'F'))
    , constraint CHK_Users_ZipCode
        CHECK (LEN(ZipCode) in (5,9)) --This ensures you have either the 5 or 9 digiti zip code
)


create table Student
(
    StudentID int identity not null
    , UserID int not null
    , BirthDate date
    , constraint PK_Student primary key clustered
        (
            StudentID
        )
    , constraint FK_Student_Users foreign key (UserID) references Users(UserID)
)

create table Teacher
(
    TeacherID int identity not null
    , constraint PK_Teacher primary key clustered
        (
            TeacherID
        )
    , constraint FK_Teacher_Users foreign key (TeacherID) references Users(UserID)
)