C# SQL Server数据库表规范化ASP.NET MVC

C# SQL Server数据库表规范化ASP.NET MVC,c#,asp.net,sql-server,asp.net-mvc,database-normalization,C#,Asp.net,Sql Server,Asp.net Mvc,Database Normalization,我有一个ASP.NET MVC应用程序,默认情况下,我有一个存储用户的AspNetUsers表。事实上,我的站点上有两种类型的用户,存储在同一个表中,两种用户都有各自不同的列!显然,我意识到这不是一条路要走,我正在努力使之正常化 以下是迄今为止的表定义: CREATE TABLE [dbo].[AspNetUsers] ( [Id] NVARCHAR (128) NOT NULL, [Email] NVARCH

我有一个ASP.NET MVC应用程序,默认情况下,我有一个存储用户的AspNetUsers表。事实上,我的站点上有两种类型的用户,存储在同一个表中,两种用户都有各自不同的列!显然,我意识到这不是一条路要走,我正在努力使之正常化

以下是迄今为止的表定义:

CREATE TABLE [dbo].[AspNetUsers] 
(
    [Id]                   NVARCHAR (128)  NOT NULL,
    [Email]                NVARCHAR (256)  NOT NULL,
    [EmailConfirmed]       BIT             NOT NULL,
    [PasswordHash]         NVARCHAR (MAX)  NULL,
    [SecurityStamp]        NVARCHAR (MAX)  NULL,
    [PhoneNumber]          NVARCHAR (50)   NULL,
    [PhoneNumberConfirmed] BIT             NULL,
    [TwoFactorEnabled]     BIT             NOT NULL,
    [LockoutEndDateUtc]    DATETIME        NULL,
    [LockoutEnabled]       BIT             NOT NULL,
    [AccessFailedCount]    INT             NOT NULL,
    [FirstName]            NVARCHAR (50)   NULL,
    [LastName]             NVARCHAR (50)   NULL,
    [Role]                 NVARCHAR (50)   NOT NULL,
    [City]                 NVARCHAR (50)   NULL,
    [ZipCode]              NVARCHAR (50)   NULL,
    [Region]               NVARCHAR (50)   NULL,
    [Language]             NVARCHAR (50)   NULL,
    [University]           NVARCHAR (50)   NULL,
    [StudyProgramme]       NVARCHAR (50)   NULL,
    [Semester]             INT             NULL,
    [GraduationDate]       NVARCHAR (50)   NULL,
    [Description]          NVARCHAR (2000) NULL,
    [Skills]               NVARCHAR (2000) NULL,
    [Experience]           NVARCHAR (2000) NULL,
    [UserName]             NVARCHAR (50)   NOT NULL,
    [WorkField]            NVARCHAR (50)   NULL,
    [NrEmployees]          INT             NULL,
    [CompanyName]          NVARCHAR (50)   NULL,
    [Website]              NVARCHAR (50)   NULL,

    CONSTRAINT [PK_dbo.AspNetUsers] PRIMARY KEY CLUSTERED ([Id] ASC)
);
GO

CREATE UNIQUE NONCLUSTERED INDEX [UserNameIndex]
    ON [dbo].[AspNetUsers]([Email] ASC);
我想将学生/公司用户特定字段存储在单独的表中,但我不确定如何执行此操作:

针对学生:

    [FirstName]            NVARCHAR (50)   NULL,
    [LastName]             NVARCHAR (50)   NULL,
    [Language]             NVARCHAR (50)   NULL,
    [University]           NVARCHAR (50)   NULL,
    [StudyProgramme]       NVARCHAR (50)   NULL,
    [Semester]             INT             NULL,
    [GraduationDate]       NVARCHAR (50)   NULL,
    [Skills]               NVARCHAR (2000) NULL,
    [Experience]           NVARCHAR (2000) NULL,
[WorkField]            NVARCHAR (50)   NULL,
[NrEmployees]          INT             NULL,
[CompanyName]          NVARCHAR (50)   NULL,
[Website]              NVARCHAR (50)   NULL,
特定公司:

    [FirstName]            NVARCHAR (50)   NULL,
    [LastName]             NVARCHAR (50)   NULL,
    [Language]             NVARCHAR (50)   NULL,
    [University]           NVARCHAR (50)   NULL,
    [StudyProgramme]       NVARCHAR (50)   NULL,
    [Semester]             INT             NULL,
    [GraduationDate]       NVARCHAR (50)   NULL,
    [Skills]               NVARCHAR (2000) NULL,
    [Experience]           NVARCHAR (2000) NULL,
[WorkField]            NVARCHAR (50)   NULL,
[NrEmployees]          INT             NULL,
[CompanyName]          NVARCHAR (50)   NULL,
[Website]              NVARCHAR (50)   NULL,

我不知道如何进行正常化过程。我是否只是修改AspNetUsers表并创建两个新表?我应该给它们添加什么样的约束?如何建立它们之间的关系?

基本上,您需要有两个新表-每种用户一个-并使它们通过主键引用基本AspNetUsers表

大概是这样的:

CREATE TABLE [dbo].[Student] 
(
    [StudentId] INT IDENTITY(1,1)
        CONSTRAINT PK_Student PRIMARY KEY CLUSTERED,
    [UserId] NVARCHAR(128) NOT NULL
        CONSTRAINT FK_Student_AspNetUsers
           FOREIGN KEY REFERENCES dbo.AspNetUsers(Id),
    .... your other student-specific columns....
)
公司的情况基本相同:


我强烈建议不要修改现有的AspNetUsers表!只需添加带有附加信息的连接表-但保持原样

您还不能正常化,因为: 1.您尚未指定规范化级别。 1a。您尚未指定计算字段(如果有)。 2.如果您打算使用2NF,则在区域和大学等属性中似乎有很多冗余数据。 3.如果你要去BCNF,你没有指定行列式

粗略地看一下您的模式就可以知道您甚至不在1NF中,因为您的属性技能看起来并不是原子性的,只是基于它的名称。当然,我在猜


现在我将在我被投票否决时下台

这里需要更清楚一点-你希望用户和公司/学生之间有什么样的关系?用户与学生和公司是一对一还是一对多?用户可以同时绑定到学生和公司记录吗?我想要1对1。每个用户必须是学生或公司,但不能同时是学生或公司。我将创建一个交叉引用表来存储UserID、TypeIdStudent/Company和ReferenceID。然后使交叉引用表对UserID具有唯一的约束。这种设置的缺点是不能直接在ReferenceID和Student/Company表之间使用外键引用。但是它会给你想要的保证,所以我有四个表:AspNetUsers,CrossReferenceUsers,StudentUsers,CompanyUsers。AspNetUsers将拥有学生和公司所需的所有“基本”字段。交叉引用使用的用户ID nvarchar 128是否为空、唯一?那么我猜StudentTable和CompanyTable都会有一个ReferenceID字段,该字段也有一个唯一的约束?将用户存储在单个表中。然后,任何学生或公司特定的信息都应该放在学生和公司表中,用户ID作为对用户表的引用。如果愿意,可以添加一些约束,以确保所需的1对1映射,并且两个子表中都没有用户。为什么不修改它?关键是,我不应该无缘无故地将学生的公司名称或公司的毕业日期等内容存储为NULL。首先,这是一个系统表,所以请不要插手!第二:如果将学生和公司的所有附加属性压缩到基表中,那么最终可能会有很多空列,而且你不能对那些在学生或公司域中有意义的新属性强制任何NOTNULL约束-因为你需要在一组列中容纳这两种情况,所有这些列最终都是可空的是…这就是现在的问题。。。所有内容都被放入一个表中,对学生有意义的字段在公司中存储为NULL。我不明白系统表参数。我修改了很多次,没有任何问题。添加/删除专栏30多年的经验:在这种情况下,如果某个东西是由第三方(如Microsoft)开发和提供的,不要修改它-当下一个版本出现时,突然你必须重新进行修改,10个月或2年后,你还知道你所做的所有更改吗??你有很多潜在的麻烦。如果它是一个系统/自定义提供的解决方案-只需扩展它,不要修改它-相信我…听起来肯定比现在的计划更好!我会重新考虑一切,明天之前更新我的帖子,谢谢你的回答嘿!我被选上了!我还有希望!说真的,你确实需要一次一个标准化级别,希望能一直达到BCNF。是的,我想我会花一些时间来更好地理解标准化,希望能提出一个更好的问题,或者自己找到答案。好的,所以我很确定我需要1NF。现在我已经修改了标准的AspNetUsers表,使其没有任何学生/
公司特定字段GraduationDate/CompanyName等。它的主键是Id,然后学生表和公司表都有UserId,这是外键。AspNetUsers还有一个角色字段。注册时,如果单击“我是学生或公司”,您的帐户将获得学生/公司角色,以便我可以使用[授权]。但是,当学生注册时,我该如何向学生表添加一个新条目呢?就像他们填写基本字段一样,他们需要特定于学生的?第2部分:基本上,我需要某种查询来检查User.Identity.GetUserId;变量对于Id和UserId ForeignKey是相同的