代码之家  ›  专栏  ›  技术社区  ›  Steven

简单的数据库规范化问题

  •  2
  • Steven  · 技术社区  · 14 年前

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

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

    现在我想在customer表中有另一个字段来标记是否允许暂停帐户。。。如果某些客户违反这些交易条款,他们将被自动停牌。。。其他人不。。。因此,相关的表字段如下所示:

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

    从上面的表设计看来,除非在我的表中添加了一个检查约束,否则这种情况是可能发生的。我看不出如何将另一个表添加到关系设计中来实现这一点,因为只有当IsSuspensionAllowed设置为YES,StatusCode设置为3时,这两个表才相互依赖。

    所以在我冗长的解释之后,我的问题是:这是一个规范化的问题吗?我没有看到一个关系设计可以强制执行这一点。。。或者它实际上只是一个业务规则,应该使用check constraint强制执行,而表实际上仍然是规范化的。

    干杯,

    史蒂夫

    1 回复  |  直到 14 年前
        1
  •  0
  •   APC    14 年前

    是的,这是可能的。您可以使用check约束和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 )
            , ....
            )
    

    int bit 不是ANSI规范的一部分)。

    这是一个很好的例子,说明状态码之类的代理键并不总是很好地工作。最好让字符串值表示case语句将读取的状态码 When StatusCode = 'Suspended' And IsSuspendedAllowed = 0... .

    顺便说一句,如果IsSuspensionAllowed=0,那么说“Suspended”的状态是不允许的是不是更有意义?使用你的数据,不应该是不允许的状态吗 StatusCode = 3 and IsSuspensionAllowed = 0