Database design 复杂关系与简单表实体框架代码优先

Database design 复杂关系与简单表实体框架代码优先,database-design,ef-code-first,relational-database,asp.net-mvc-5,entity-relationship,Database Design,Ef Code First,Relational Database,Asp.net Mvc 5,Entity Relationship,数据库设计问题:) 制作大量相互关联的表(规范化)是更明智的做法还是复制数据以使查询更简单更明智 以下是我的情况: public class TransferRequest { [Key] public int TransferRequestId { get; set; } public int By { get; set; } public int? For { get; set; } public int PersonId { get; set;

数据库设计问题:) 制作大量相互关联的表(规范化)是更明智的做法还是复制数据以使查询更简单更明智

以下是我的情况:

public class TransferRequest
{
    [Key]
    public int TransferRequestId { get; set; }

    public int By { get; set; }

    public int? For { get; set; }

    public int PersonId { get; set; }
    public virtual Person Person { get; set; }

    [ForeignKey("Transfer")]
    public int? ExistingTransferId { get; set; }
    public virtual Transfer ExistingTransfer { get; set; }

    [Required]
    [Range(1, 999)]
    public int Pax { get; set; }

    [Range(0, 999)]
    public int PaxChild { get; set; }

    [Range(0, 999)]
    public int PaxInfant { get; set; }

    public int StartPortId { get; set; }
    public virtual Port StartPort { get; set; }

    public int EndPortId { get; set; }
    public virtual Port EndPort { get; set; }

    [Required]
    [DataType(DataType.DateTime)]
    [UIHint("PickupTimePicker")]
    [Display(Name = "Pickup time"), DisplayFormat(DataFormatString = "{0:dd.MM.yyyy HH:mm}")]
    public DateTime PickupTime { get; set; }

    public bool Cargo { get; set; }

    public string CargoDescription { get; set; }

    public int Status { get; set; }

    [ForeignKey("Transfer")]
    public int? TransferId { get; set; }
    public virtual Transfer Transfer { get; set; }
}
在此之后,将创建:

public class Transfer
{
    public Transfer()
    {
        Crew = new List<CrewOnTransfer>();
        TransferPoints = new List<TransferPoint>();
        TransferRequests = new List<TransferRequest>();
    }

    [Key]
    public int TransferId { get; set; }

    [ForeignKey("Ship")]
    public int ShipId { get; set; }
    public virtual Ship Ship { get; set; }

    [ForeignKey("ShipCrew")]
    public int CaptainId { get; set; }
    public virtual ShipCrew ShipCrew { get; set; }

    public virtual ICollection<CrewOnTransfer> Crew { get; set; }

    public virtual ICollection<TransferPoint> TransferPoints { get; set; }

    public virtual ICollection<TransferRequest> TransferRequests { get; set; }
}

等等。你明白了。我应该简化情况吗?这将变得越来越混乱。

复制是导致损坏的途径如果您更新了一个副本,而忘记更新另一个副本,那么您就不再有好的方法来确定这两个副本中的哪一个是有效的。您已经有效地破坏了数据

规范化的全部目标是消除这种重复,从而减少数据损坏的方式。由于规范化是在数据模型级别进行的,因此它提高了数据库的能力,使其能够自主地“保护”自己不受有缺陷的客户机的影响

如果数据不正确,Performance2就没有什么意义,因此规范化是标准(没有双关语)。非规范化只有在明智地、以有限的方式来解决一个非常大的性能问题(无法解决)时才被认为是可以接受的,并且您可以通过测量来证明性能优势

简言之:首先进行规范化,如果测量结果证明了这一点,则进行反规范化


1请注意,在并发环境中,两个独立的客户端可能会尝试并行更新不同的副本(表示同一条信息),保持数据同步并非易事。即使在单客户端环境中,bug也是一个事实


2或简单的客户端代码。

复制数据被认为违反了规范化规则。我知道,但最后我决定复制其中的一些,以避免通过表进行往返。此外,编写所有include语句也不是一件有趣的事情:(我认为规范化是更好的做法,除非出现性能问题。甚至可能不需要规范化。依我看,必须编写一堆include语句并不是违反规则的有效理由;这确实是所选技术的副作用。难道你不能使用设计优先的方法,让VS自动生成你的类吗?
public class CrewOnTransfer
{
    [Key]
    public int CrewOnTransferId { get; set; }

    [ForeignKey("ShipCrew")]
    public int ShipCrewId { get; set; }
    public virtual ShipCrew ShipCrew { get; set; }

    [ForeignKey("Transfer")]
    public int TransferId { get; set; }
    public virtual Transfer Transfer { get; set; }
}