Pergunta

Tenho uma pergunta rápida sobre um banco de dados que estou projetando e certificando -se de que está normalizado ...

Eu tenho uma tabela de clientes, com uma chave primária do clienteID. Ele possui uma coluna de statusCode que possui um código que reflete o status da conta do cliente, ie. 1 = aberto, 2 = fechado, 3 = suspenso etc ...

Agora eu gostaria de ter outro campo na tabela de clientes que sinalizam se a conta pode ser suspensa ou não ... certos clientes serão suspensos automaticamente se eles quebrarem os termos de negociação ... outros não ... então o relevante Os campos da tabela serão assim:

Clientes (CustomerID (PK): STATUSCODE: ISSUSPENSONALIDODED)

Agora, ambos os campos dependem da chave primária, pois você não pode determinar o status ou se as suspensões são permitidas em um cliente em particular, a menos que você conheça o cliente específico, exceto, é claro, quando o campo IssuspensionAleded está definido como sim, o cliente nunca deve ter um código de status de 3 (suspenso).

Parece que, no design da tabela acima, é possível que isso aconteça, a menos que uma contragem de verificação seja adicionada à minha tabela. Não consigo ver como outra tabela poderia ser adicionada ao design relacional para fazer cumprir isso, pois é apenas no caso em que a ISSUSPONSOUNDED é definida como sim e o STATUSCODE é definido como 3 quando os dois dependem um do outro.

Então, depois da minha explicação há muito tempo, minha pergunta é a seguinte: isso é um problema de normalização e não estou vendo um design relacional que aplicará isso ... ou na verdade é apenas uma regra de negócios que deve ser aplicada com uma contratação de cheque e o A tabela ainda é normalizada.

Saúde,

Steve

Foi útil?

Solução

Sim, é possível. Você pode fazer isso com uma restrição de cheque e uma declaração de caso:

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 )
        , ....
        )

Você não mencionou o tipo de dados do PK, então eu simplesmente inseri um espaço reservado. Se você estiver usando o SQL Server, pode usar uma coluna um pouco em vez do int e verifique a restrição que mencionei acima (bit não faz parte da especificação ANSI).

Este é um bom exemplo de onde as chaves substitutas para coisas como códigos de status nem sempre funcionam bem. Seria melhor ter valores de string representam os códigos de status, caso em que a declaração do caso lia When StatusCode = 'Suspended' And IsSuspendedAllowed = 0....

Do ponto de vista da normalização, não vejo nada de errado. Se a suspensão é permitida é um atributo específico para um cliente e não outro atributo. O que você está dizendo com a restrição de cheque, que certos estados de valores de atributo não podem existir, o que é bom.

Aliás, não faria mais sentido dizer que o status de "suspenso" não é permitido quando ISSUSPENSONSALIDADO = 0? Usando seus dados, o estado não é permitido ser StatusCode = 3 and IsSuspensionAllowed = 0?

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top