Недостатки использования целого числа в качестве битового поля? - PullRequest
1 голос
/ 17 июня 2010

У меня есть куча булевых опций для таких вещей, как «приемлемые типы платежей», которые могут включать в себя такие вещи, как наличные, кредитные карты, чеки, PayPal и т. Д. Вместо того, чтобы иметь полдюжины логических значений в моей БД, я могу просто целое число и присваивайте каждому методу оплаты целое число, например

PAYMENT_METHODS = (
    (1<<0, 'Cash'),
    (1<<1, 'Credit Card'),
    (1<<2, 'Cheque'),
    (1<<3, 'Other'),
)

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

Почему я делаю это: у меня уже около 15 логических значений, разделенных на 3 разных логических "набора". Это уже много полей, и использование трех таблиц «многие ко многим» для сохранения группы данных, которые редко изменяются, кажется неэффективным. Использование целых чисел позволяет мне добавлять до 32 флагов в каждое поле без необходимости изменять БД.

Ответы [ 5 ]

6 голосов
/ 17 июня 2010

Главный недостаток, который я могу придумать, - это ремонтопригодность. Кто-то, пишущий запрос к базе данных, должен понимать соглашение по битам, вместо того, чтобы искать более удобочитаемый набор столбцов. Кроме того, если удаляется один из «принятых типов платежей», необходимо перенести сами данные, а не просто удалить столбец в таблице.

2 голосов
/ 18 июня 2010

Не уверен, какую базу данных вы используете, но MySQL имеет установленный тип .

2 голосов
/ 17 июня 2010

Это не худшее, но может быть и лучший способ.

Определите таблицу с именем PaymentTypes

id, paymentId, key (string), value (boolean)

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

1 голос
/ 17 июня 2010

Я думаю, что предыдущие плакаты были правильными. Самый простой способ сделать это в «реляционной» базе данных - это определить новую таблицу отношений, в которой будут храниться типы платежей. На практике это обычно доставляет больше хлопот, чем стоит.

Использование перечислений в вашем коде и использование чего-то похожего в БД (проверьте ограничения в Oracle, AFAIK) должно помочь поддерживать его в обслуживании и быть очевидным для бедной души, чья работа будет заключаться в добавлении нового типа через много лет ты ушел

1 голос
/ 17 июня 2010

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

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

Некоторые комментарии к перечислениям / битовым полям в Django

...