Как вы справляетесь с char (1) вместо логических полей и полей с тремя состояниями? - PullRequest
2 голосов
/ 11 февраля 2009

Отчасти связано с моим вопросом о целых числах вместо десятичных; Мой поставщик предоставляет множество «логических» полей в формате char (1) (т.е. Y / N). Некоторые из этих полей законно не могут быть логическими, потому что они могут иметь несколько значений, но большинство может рассматриваться как логическое. В моем предыдущем вопросе совет заключался в том, чтобы делать то, что «правильно» вместо того, что предоставляет поставщик; я должен все еще применить эту логику и создать мою схему базы данных, используя битовое поле для этих столбцов, или оставить ее как char (1) и выполнить преобразование в моем коде?

Также по этому вопросу, как я должен иметь дело с полями трех состояний, насколько идет код? Логически поле является логическим (в том смысле, что меня интересует только значение Y / N, а третье значение действительно либо да, либо нет), но значения могут быть больше, чем просто истина / ложь (например, существует UpsShippable поле, которое может быть Y, N или G); это поле имеет несколько состояний, так как мне лучше всего его инкапсулировать? Что-то вроде enum (или статических констант, поскольку Enums нельзя использовать с типом char)? В случаях с несколькими значениями данные больше похожи на индикатор типа, чем на флаг.

Подводя итог (я получаю немного скучный): 1) Имея дело со char(1) значениями в данных, вы бы сохранили их как символы или преобразовали в биты (или как бы то ни было булев тип вашей базы данных) и почему и 2) Как бы вы занялись полем char с тремя состояниями в вашем коде, предполагая, что вы оставите его как char(1) в схеме данных?

РЕДАКТИРОВАТЬ: Для пояснения, ни одно из этих полей не используется для "реальной" логики, это в основном просто индикатор. Например, если товар не может быть отправлен через UPS (т. Е. Значение N / G), то на странице, обращенной к клиенту, говорится, что товар не может быть отправлен через UPS, а на бэкэнде логика не будет вызов веб-службы UPS для расчета стоимости доставки. Другие поля Y / N просто присутствуют в качестве дополнительной информации об элементе и не имеют логики, хотя они должны быть изменяемыми (например, иметь флажок, указывающий, перерабатывается ли он в форме ввода данных на внутренней стороне); Я мог бы отобразить изображение или отфильтровать элементы по ним (например, вы можете искать все переработанные продукты, и я проверю, чтобы убедиться, что их индикатор переработанных продуктов верен), но ничего другого, по крайней мере, на данный момент.

Ответы [ 6 ]

3 голосов
/ 11 февраля 2009

Чаще всего я имею дело с Oracle, который на самом деле не имеет битовых типов, поэтому его никогда не было проблемой.

При этом поля односимвольного кода являются общими и хорошими. Что бы вы ни делали, не называйте их вводящим в заблуждение именем, которое предполагает, что это булев тип, если он имеет 3 состояния. Это просто смущает людей.

Плохое имя: SHIP_FLAG («флаг» неоднозначен, но многие интерпретируют его как Y / N или T / F)
Плохое имя: HAS_BOOKED (опять же, подразумевает логическое значение)
Плохое имя: IS_SENT (то же самое)
Хорошее имя: SHIP_CODE (это может означать все, что вы хотите, чтобы оно значило)

Кроме того, одно символьные поля позволяют расширить значение позже. Битовые поля не (действительно).

1 голос
/ 11 февраля 2009

1 :) Зависит от того, является ли char (1) только полем типа Y / NT / F, тогда да, я бы преобразовал его в бит, потому что это логическое значение, я бы сделал преобразование в специфичный для поставщика формат в на грани системы (представьте, что у вас есть несколько поставщиков, таких как fedEx и UPS, вы можете обобщить свою бэкэнд-систему для обработки как грузоотправителей, так и подключить конкретные компоненты для связи между вашей моделью и их).

2 :) Если имеется несколько состояний, то это больше не булево значение, и я бы сохранил его в формате, который имел смысл, если бы были некоторые варианты, чтобы сохранить его как поле типа char, или вы могли бы создать таблицу поиска для UpsShippable у вас может быть Да, Нет или Земля. Что ж, справочная таблица позволяет хранить более информативную информацию о том, что означает G. Если бы я использовал Enum в коде, многое зависит от того, какова цель поля и вашего проекта. Если вы собираетесь использовать логику для поля, я мог бы использовать перечисление, которое хорошо сочетается с таблицей поиска, если вы просто храните и передаете данные, возможно, я бы не стал.

1 голос
/ 11 февраля 2009

Я бы посоветовал в бистатных полях всегда делать логические преобразования.

Поле трех состояний - это нечто иное ... Есть много решений, но ни одно из них не является "правильным". Вы можете создавать таблицы для наборов опций и ссылаться по индексу ... но вы теряете удобочитаемость при очень небольшом выигрыше, кроме "правильности".

0 голосов
/ 14 февраля 2009

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

Например:

CASE UpsShippable WHEN 'Y' THEN 1 WHEN 'N' THEN 0 ELSE NULL END

Если вы создадите это представление как индексированное представление, при выборе из данных не будет никаких накладных расходов.

0 голосов
/ 12 февраля 2009

Я столкнулся с подобной ситуацией некоторое время назад. Я создавал приложение для базы данных, над которой у меня не было контроля, которая использовала поля char (1) Y / N для логических значений. Я также использовал инфраструктуру SubSonic ORM для создания своего уровня доступа к данным. Я создал еще одно свойство класса для таблицы, которую нужно преобразовать в поле char (1).

    public string SomeYNField { ... } // property generated by ORM tool

    // property added manually (in a partial class, so 
    // it doesnt get blown away by the ORM tool)
    public bool SomeYNFieldBool
    {

        get 
        { 
            // Anything other than a "Y" is false.
            return SomeYNField.Equals("Y", StringComparison.InvariantCultureIgnoreCase); 
        }
        set 
        {
            SomeYNField = value ? "Y" : "N"; 
        }
    }

Теперь вы можете использовать это логическое поле для привязки к флажкам и другим элементам управления, ожидающим логическое значение.

0 голосов
/ 12 февраля 2009

Я решил пойти дальше и реализовать простые поля Y / N в качестве полей истинных битов, но я все еще не уверен, как мне следует обрабатывать поля с несколькими состояниями.

Мне нужно будет использовать их в качестве флагов, чтобы указать, нужно ли предпринимать другие действия; например, если ShippingStatusCode не равно Y, то считается, что элемент не может быть отправлен в UPS, и применяется другой набор логики, чем если бы он был отправлен. Логика может варьироваться от не отображения определенных параметров до фактической замены элементов, введенных в форму, совершенно другим элементом или полного удаления, если поиск показывает, что нет эквивалентных элементов.

Одна проблема ... другая. Мысли о работе с полями с несколькими состояниями? Я должен оставить их как поля типа char, хотя думаю, что из-за осторожности я буду ошибаться и использую char (3) вместо char (1) на случай, если в какой-то момент требования изменятся.

...