数据库设计问题:) 制作大量互连的表(规范化)是否更聪明,或者复制数据更聪明,以便查询更简单?
以下是我的情况:
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; }
}
Crew继续说道:
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; }
}
等等。你明白了。我应该简化这种情况吗?跟随这一点变得混乱。
答案 0 :(得分:2)
复制是腐败的途径 - 如果您更新一个副本,并忘记 1 更新另一个副本,您将无法再确定这两个中的哪一个副本有效。您已经有效地破坏了数据。
规范化的整个目标是消除这种重复,从而减少数据损坏的方式。并且由于规范化处于数据模型级别,因此它将数据库的能力提高到自主&#34;防御&#34;来自有缺陷的客户。
如果数据不正确,性能 2 意味着很少,因此规范化是常态(没有双关语意)。非规范化只有在明智地以有限的方式完成时才被认为是可接受的,以解决非常大的性能问题(无法解决otherwise),并且您可以通过测量来证明性能优势 representative amounts of data。
简而言之:首先规范化,然后
1 请注意,在并发环境中,两个独立客户端可能会尝试并行更新不同的副本(代表同一条信息),保持数据同步非常重要。即使在单客户端环境中,错误也是生活中的事实。 2 或简化客户端代码。