为了理智还是表现而非规范化?

Mar*_*.is 8 sql normalize denormalization

我已经开始了一个新项目,他们有一个非常规范化的数据库.可以查找的所有内容都作为外键存储到查找表中.这是规范化和精细的,但我最终为最简单的查询做了5个表连接.

    from va in VehicleActions
    join vat in VehicleActionTypes on va.VehicleActionTypeId equals vat.VehicleActionTypeId
    join ai in ActivityInvolvements on va.VehicleActionId equals ai.VehicleActionId
    join a in Agencies on va.AgencyId equals a.AgencyId
    join vd in VehicleDescriptions on ai.VehicleDescriptionId equals vd.VehicleDescriptionId
    join s in States on vd.LicensePlateStateId equals s.StateId
    where va.CreatedDate > DateTime.Now.AddHours(-DateTime.Now.Hour)
    select new {va.VehicleActionId,a.AgencyCode,vat.Description,vat.Code,
vd.LicensePlateNumber,LPNState = s.Code,va.LatestDateTime,va.CreatedDate}
Run Code Online (Sandbox Code Playgroud)

我想建议我们取消一些东西.喜欢州代码.在我的一生中,我没有看到州代码的变化.类似的故事与3个字母的代理商代码.这些由代理机构发放,永远不会改变.

当我找到状态代码问题和5表连接的DBA时.我得到了"我们正常化"和"加入很快"的回应.

反规范化有一个令人信服的论据吗?如果没别的话,我会为了理智而这样做.

T-SQL中的相同查询:

    SELECT VehicleAction.VehicleActionID
      , Agency.AgencyCode AS ActionAgency
      , VehicleActionType.Description
      , VehicleDescription.LicensePlateNumber
      , State.Code AS LPNState
      , VehicleAction.LatestDateTime AS ActionLatestDateTime
      , VehicleAction.CreatedDate
FROM VehicleAction INNER JOIN
     VehicleActionType ON VehicleAction.VehicleActionTypeId = VehicleActionType.VehicleActionTypeId INNER JOIN
     ActivityInvolvement ON VehicleAction.VehicleActionId = ActivityInvolvement.VehicleActionId INNER JOIN
     Agency ON VehicleAction.AgencyId = Agency.AgencyId INNER JOIN
     VehicleDescription ON ActivityInvolvement.VehicleDescriptionId = VehicleDescription.VehicleDescriptionId INNER JOIN
     State ON VehicleDescription.LicensePlateStateId = State.StateId
Where VehicleAction.CreatedDate >= floor(cast(getdate() as float))
Run Code Online (Sandbox Code Playgroud)

Chr*_*heD 6

在某些时候,性能(和理智)原因可能需要一些非规范化.很难说没有看到你所有的表/需求等...

但为什么不只是构建一些便利视图(进行一些连接)然后使用它们来编写更简单的查询?


djn*_*jna 6

谨防想要根据你当前的习语塑造东西.现在,不熟悉的代码似乎不符合你的理解,也阻碍了你的理解.随着时间的推移你可能会适应.

如果当前(或已知的未来)要求(例如性能)未得到满足,则这是一个完全不同的问题.但是记住任何事情都可以进行性能调整,目标不是让事情尽可能快,而是要让它们足够快.


Pau*_*ott 6

我不知道我是否甚至会调用你想要进行非规范化的东西 - 它看起来更像你只想用自然外键(State Abbreviation,Agency Code)替换人工外键(StateId,AgencyId).使用varchar字段而不是整数字段会降低连接/查询性能,但是(a)如果你甚至不需要在大多数时间都加入表,因为无论如何它都是你想要的自然FK并不是什么大问题( b)你的数据库需要相当大/有很高的负载才能引人注目.

但是djna是正确的,因为在进行这样的更改之前,您需要完全了解当前和未来的需求.你确定三封信机构代码永远不会改变,即使是五年后也是如此?真的,真的很确定吗?