Bezdepbonusu7Программирование: статьи и ответы

Вопрос

Недостатки использования целого числа в качестве битового поля?

Автор вопроса: mpenОтветов: 5

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

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

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

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

djangodatabase-designbit-manipulation

Ответы

Ответ 1 · рейтинг 1 · dimo414

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

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

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

Ответ 2 · рейтинг 6 · btreat

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

Ответ 3 · рейтинг 2 · Byron Whitlock

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

Определите таблицу под названием PaymentTypes

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

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

Ответ 4 · рейтинг 2 · Justin K

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

Ответ 5 · рейтинг 1 · Java Drinker

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

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

Перевод вопроса и ответов сообщества Stack Overflow, лицензия CC BY-SA. Оригинал на Stack Overflow.

Похожие материалы