Как моделировать открытые / закрытые статусы в базе данных? - PullRequest
1 голос
/ 26 июля 2009

Представьте, что у меня есть таблица заказов со столбцами OrderID (PK), CustomerID, CustomerOrderN и так далее. Теперь мне нужно добавить возможность «закрыть» ордера с указанием причины, по которой ордер закрыт (например, «предложенная цена слишком высока для клиента», «недоступен», «клиент попросил закрыть заказ»).

Вопрос 1. Каков наилучший и правильный способ реализовать это при проектировании базы данных?

Я думаю, что лучший способ - создать закрытый столбец, который может быть нулевым(если ордер открыт) и если не ноль (т.е. если ордер закрыт), то значение указывает на другую таблицу OrderCloseReasons.

Вопрос 2. Что если у меня уже есть :) булев столбец Закрыто в таблице «Заказы», ​​и теперь мне нужно реализовать возможность указать причины закрытия. Я не могу много реорганизовать, потому что система уже не такая маленькая, поэтому сложно реорганизовать схему базы данных. Как лучше всего добавить возможность указать причины закрытия в таком случае?

Я думаю, что если я просто добавлю столбец CloseReasonID в таблицу Orders, это не будет хорошо. Но я не уверен.

Заранее спасибо.

Ответы [ 5 ]

4 голосов
/ 26 июля 2009

Если у вас есть несколько конкретных близких причин, которые вы хотели бы использовать, и если вам нужно иметь возможность выполнять запросы на основе определенного типа близкой причины (скажем, получить все по причине X), то что вы предлагаетехорошая идея - нулевой или закрытый идентификатор причины.

С другой стороны, если вам не нужен поиск и т. д., можно просто закрыть закрытый столбец и другой столбец, в котором описано, почему он былзакрыто.

3 голосов
/ 26 июля 2009

Я бы порекомендовал столбец StatusCode (возможно, тип данных int) и отдельную таблицу, содержащую StatusCode (int) и StatusCodeDescription (varchar). Это дает вам больше гибкости, если вы или ваши конечные пользователи подумаете о другом возможном статусе позже.

1 голос
/ 26 июля 2009

Лично я бы сделал таблицу поиска, как вы предлагаете, но назову ее Status. Я бы сделал внешний ключ для таблицы «Состояние» в таблице «Заказы» целым, а не нулевым со значением по умолчанию 1.

Тогда записи в таблице «Состояние» будут (1) Открыты, (2) Закрытыпервая причина, (3) закрытая причина вторая и т. д. Таким образом, вы можете отобразить перечисление на более высоком уровне, не делая ничего особенного в ваших хранимых процедурах. То есть все, что вы делаете, это включаете StatusID в ваш SELECT вместо того, чтобы возиться с обработкой нулевого значения как означающего одно, а с поисковыми значениями как другого.

0 голосов
/ 26 июля 2009

Дополнительная таблица, содержащая причину закрытия только для тех ордеров, которые закрыты.

Она не нарушает 1NF, потому что вы не вводите нули в схему базы данных, и у вас есть абсолютная гарантия того, чтоВаши изменения не повлияют на существующий материал (который вы четко указали в данном случае, является серьезной проблемой).

РЕДАКТИРОВАТЬ

См., например, «Что в действительности означает первая нормальная форма» в «Дата в базе данных»:Сочинения 2000-2006 (Springer-Verlag, 2006). Возможно также найти в качестве отдельной статьи в Интернете.

И из "Введение в системы баз данных", 8ed. : «Relvar находится в 1NF тогда и только тогда, когда в каждом допустимом значении этого relvar каждый кортеж содержит ровно одно значение для каждого атрибута». (и ноль не может быть значением, потому что он не равен самому себе).

0 голосов
/ 26 июля 2009

Объединение значения NULL и причины в один обнуляемый текстовый столбец не является хорошей идеей, поскольку другие программисты или даже вы не сможете легко прочитать его через несколько дней.

Наличие двух столбцов - логического или кода состояния в видеуказанный Дэвидом, и отдельная колонка для причины. Это делает ваш дизайн более читабельным.

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

"Кто закрыл заказ?""Во сколько это было закрыто?"«Был ли он снова открыт?»

Контрольный журнал обычно состоит из другой таблицы, например:

OrderAudit -> AuditID -> OrderID -> ChangeMadeBy -> ChangeDateTime -> ChangeColumn -> ChangeValue

Что даст полный контроль над тем, кто что сделал с этим приказом и когда.

...