【问题标题】:Simple Database normalization question简单的数据库规范化问题
【发布时间】:2011-03-03 03:36:10
【问题描述】:

我有一个关于我正在设计并确保它被规范化的数据库的快速问题......

我有一个客户表,主键是 customerId。它有一个 StatusCode 列,其中包含一个反映客户帐户状态的代码,即。 1 = 打开,2 = 关闭,3 = 暂停等...

现在我想在客户表中有另一个字段来标记是否允许暂停帐户...某些客户如果违反交易条款将被自动暂停...其他人不会...所以相关的表字段将是这样的:

客户(CustomerId(PK):StatusCode:IsSuspensionAllowed)

现在这两个字段都取决于主键,因为除非您知道特定客户,否则您无法确定特定客户的状态或是否允许暂停,当然当 IsSuspensionAllowed 字段设置为 YES 时,客户状态码不应为 3(已暂停)。

从上面的表格设计看来,除非在我的表格中添加检查约束,否则可能会发生这种情况。我看不出如何将另一个表添加到关系设计中来强制执行此操作,因为它仅在 IsSuspensionAllowed 设置为 YES 且 StatusCode 设置为 3 时两者相互依赖。

所以在我冗长的解释之后,我的问题是:这是一个规范化问题,我没有看到一个可以强制执行此操作的关系设计......或者它实际上只是一个应该通过检查来强制执行的业务规则约束和表格实际上仍然是规范化的。

干杯,

史蒂夫

【问题讨论】:

    标签: sql database normalization 3nf


    【解决方案1】:

    是的,这是可能的。您可以使用检查约束和 Case 语句来做到这一点:

    Create Table Customer   (
            CustomerId <datatype> not null Primary Key
            , StatusCode int not null
            , IsSuspensionAllowed int not null Default( 1 )
            , Constraint CK_Customer_IsSuspensionAllowed 
                        Check ( IsSuspensionAllowed In(0,1) )
            , Constraint CK_Customer_StatusCodeRange 
                        Check ( StatusCode Between 0 And ?? )
            , Constraint CK_Customer_StausCodeValid 
                        Check ( Case
                    When StatusCode = 3 And IsSuspensionAllowed = 1 Then 0
                                                                    Else 1
                                                                    End = 1 )
            , ....
            )
    

    您没有提到 PK 的数据类型,所以我只是插入了一个占位符。如果您使用的是 SQL Server,则可以使用位列代替 int 并检查我上面提到的约束(bit 不是 ANSI 规范的一部分)。

    这是一个很好的例子,说明状态代码之类的代理键并不总是很好。最好让字符串值表示状态代码,在这种情况下,Case 语句将显示为When StatusCode = 'Suspended' And IsSuspendedAllowed = 0...

    从规范化的角度来看,我没有发现任何问题。是否允许暂停是特定于客户的属性,而不是另一个属性。你所说的检查约束,属性值的某些状态不能存在,这很好。

    顺便说一句,当 IsSuspensionAllowed = 0 时,不允许“暂停”状态是不是更有意义?使用你的数据,不允许的状态不应该是StatusCode = 3 and IsSuspensionAllowed = 0吗?

    【讨论】:

    • 谢谢,我正在为规范化而努力,“整个钥匙,只有钥匙”这件事让人有些怀疑。我觉得 Status 和 IsSuspended 之间可能存在传递依赖关系。正如您所提到的,尽管每个属性都是特定于客户的。我承认我喜欢在大多数情况下使用代理键进行标准化。我通常不会的唯一一次是当有一个已经开发的标准时,比如货币,或者在代表多对多关系的表格中。我接受您关于提高板载可读性的评论,并认为它是不变的代码。干杯
    猜你喜欢
    • 2011-11-04
    • 1970-01-01
    • 1970-01-01
    • 2011-02-06
    • 1970-01-01
    • 2012-07-30
    • 1970-01-01
    • 2012-10-08
    相关资源
    最近更新 更多