Question

J'ai une petite question au sujet d'une base de données que je suis la conception et en vous assurant qu'il est normalisé ...

J'ai une table à la clientèle, avec une clé primaire de customerId. Il a une colonne StatusCode qui a un code qui reflète les clients état du compte-à-dire. 1 = ouvert, 2 = Fermé, 3 = Suspendu etc ...

Maintenant, je voudrais avoir un autre champ dans la table des clients que les drapeaux si le compte est autorisé à suspendre ou non ... certains clients sera automatiquement suspendu si elles briserai conditions commerciales ... d'autres pas ... de sorte que les champs de table pertinents seront comme ceci:

Les clients (CustomerId (PK): StatusCode: IsSuspensionAllowed)

Maintenant, les deux champs dépendent de la clé primaire que vous ne pouvez pas déterminer l'état ou si les suspensions sont autorisées sur un client particulier, sauf si vous connaissez le client spécifique, sauf bien sûr lorsque le champ IsSuspensionAllowed est réglé sur OUI, le client ne devrait jamais avoir un statusCode de 3 (suspendu).

Il semble de la conception de tableau ci-dessus, il est possible que cela se produise à moins qu'un chèque est ajouté à contraint ma table. Je ne vois pas comment une autre table pourrait être ajoutée à la conception relationnelle pour faire appliquer ce même si, comme il est seulement dans le cas où IsSuspensionAllowed est réglé sur OUI et StatusCode est réglé sur 3 lorsque les deux ont une dépendance à l'autre.

Alors, après ma longue explication poussif ma question est la suivante: Est-ce un problème de normalisation et je ne vois pas une conception relationnelle qui mettra en application ce ... ou est-il en fait juste une règle d'affaires qui devrait être appliquée avec un chèque et la table contraint est en fait encore normalisée.

Cheers,

Steve

Était-ce utile?

La solution

Oui, il est possible. Vous pouvez le faire avec une contrainte de vérification et une déclaration de cas:

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

Vous ne mentionne pas le type de données du PK donc je simplement inséré un espace réservé. Si vous utilisez SQL Server, vous pouvez utiliser une colonne de bits au lieu de la contrainte int et vérifier je l'ai mentionné ci-dessus (bit ne fait pas partie de la spécification ANSI).

Ceci est un bon exemple de l'endroit où les clés de substitution pour des choses comme les codes d'état ne fonctionnent pas toujours bien. Il serait préférable d'avoir des valeurs de chaîne représentent les codes d'état dans ce cas, la déclaration de cas lirait When StatusCode = 'Suspended' And IsSuspendedAllowed = 0....

Du point de vue de la normalisation, je ne vois pas mal de quoi que ce soit. Si la suspension est autorisée est un attribut spécifique à un client et non un autre attribut. Ce que vous dites avec la contrainte de vérification, que certains états de valeurs d'attributs ne peuvent pas exister ce qui est bien.

BTW, ne serait pas plus logique de dire que le statut de « Suspendu » est pas autorisée lorsque IsSuspensionAllowed = 0? Utilisation de vos données, ne devrait pas l'état non autorisé soit StatusCode = 3 and IsSuspensionAllowed = 0?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top