2010-06-13 3 views
2

У меня есть быстрый вопрос о базе данных, я проектирование и убедившись, что он нормализуется ...Простой нормализация базы данных вопроса

У меня есть таблица клиентов, с первичным ключом CustomerID. Он имеет столбец StatusCode, который имеет код, который отражает статус учетной записи клиентов, т.е. 1 = разомкнуто, 2 = закрыто, 3 = приостановлено и т. Д.

Теперь я хотел бы иметь другое поле в таблице клиентов, которое указывает, разрешено ли отключение учетной записи или нет ... некоторые клиенты будут автоматически приостанавливается, если они нарушат там торговые условия ... другие не ... поэтому соответствующие поля таблицы будут как так:

Клиенты (CustomerId (PK): StatusCode: IsSuspensionAllowed)

Теперь оба поля зависят на первичный ключ, так как вы не можете определить статус или разрешено ли приостановление для конкретного клиента, если вы не знаете конкретного клиента, за исключением, конечно, если для поля IsSuspensionAllowed установлено значение YES, у клиента никогда не должно быть StatusCode 3 (приостановлено).

Кажется, что из приведенного выше табличного дизайна это возможно, если к моей таблице не добавлен контрольный значок. Я не вижу, как можно добавить другую таблицу в реляционный дизайн, чтобы обеспечить ее выполнение, хотя, поскольку это только в случае, когда IsSuspensionAllowed установлен в YES, а StatusCode установлен на 3, когда они имеют зависимость друг от друга.

Итак, после моего долгого объяснения, мой вопрос заключается в следующем: Является ли это проблемой нормализации, и я не вижу реляционного дизайна, который обеспечит это ... или это фактически просто бизнес-правило, которое должно выполняться с помощью проверьте противоречие, и таблица на самом деле все еще нормализована.

Приветствия,

Стив

ответ

0

Да, это возможно. Вы можете сделать это с помощью проверочного ограничения и саза:

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

Вы не упоминались типа данных ПК, так что я просто вставлен заполнителем. Если вы используете SQL Server, вы можете использовать столбец бит вместо int и проверить ограничение, упомянутое выше (bit не входит в спецификацию ANSI).

Это хороший пример того, где суррогатные ключи для таких вещей, как коды состояния, не всегда хорошо работают. Было бы лучше иметь строковые значения, представляющие коды состояния, и в этом случае оператор Case будет читать When StatusCode = 'Suspended' And IsSuspendedAllowed = 0....

С точки зрения нормализации, я не вижу ничего плохого. Разрешено ли приостановление, является атрибутом, специфичным для Клиента, а не другим атрибутом. Что вы говорите с помощью ограничения проверки, что определенные состояния значений атрибутов не могут существовать, что хорошо.

Btw, не имеет смысла говорить, что статус «приостановлено» не разрешен, когда IsSuspensionAllowed = 0? Используя данные, не должно быть состояния, которое не разрешено, StatusCode = 3 and IsSuspensionAllowed = 0?

+0

Спасибо, Я вскочил на нормализацию, и «весь ключ» и ничего, кроме ключа », вызывали некоторые сомнения. Я чувствовал, что может существовать переходная зависимость между статусом и IsSuspended. Как вы упомянули, каждый атрибут специфичен для клиента. Я признаю, что мне нравится использовать суррогатные ключи в большинстве ситуаций для стандартизации. Единственный раз, когда я обычно привык, когда есть уже разработанный стандарт, такой как валюта, или в таблицах, представляющих отношения «многие ко многим». Я беру ваш комментарий об улучшении читаемости на борту, хотя и буду рассматривать его неизменный код. Cheers – Steven

Смежные вопросы