Эффективность множественных логических флагов по сравнению с мультиплексированным целым числом (битами) в Java и MySQL

Это вопрос дизайна, связанный как с Java, так и с MySQL.

Клиент требует добавления 14 логических флагов (T/F) для отслеживания некоторой новой информации в существующем классе/таблице.

Я могу добавить эти флаги в существующую таблицу или создать новый класс и таблицу только для этих данных. Добавление 14 логических флагов к существующей таблице даст ей довольно много атрибутов, которых я склонен избегать (особенно если количество флагов со временем увеличивается). Создание нового класса/таблицы чище, но действительно ли оно необходимо в данном случае?

В качестве альтернативы я мог бы использовать 16-битное целое число с масками для мультиплексирования данных, а затем я добавляю только одну переменную в существующий класс/таблицу.

Мой основной вопрос заключается в следующем: более эффективно хранить 14 отдельных логических переменных в базе данных MySQL и загружать их в класс, или было бы лучше хранить одно целое число, а затем (в Java) мультиплексировать флаги, используя манипуляции с битами ( то есть маски)?

Второстепенный вопрос, если отдельные флаги более эффективны, то лучше ли иметь много атрибутов в одной таблице или разделить их? Каков штраф за хранение большого количества логических флагов в таблице, которая уже имеет довольно много сущностей?

Если ответ на основной вопрос «целое число + мультиплекс», то второй вопрос становится спорным.

Спасибо.

-R


person Huntrods    schedule 07.12.2011    source источник
comment
оказывается, я не мог использовать логический тип. Клиент изменил спецификацию таким образом, что требовался множественный выбор. Закончилось использованием массива int[] в классе, а затем преобразователем из int[] в одну строку (и обратно). Сохраните строку в базе данных из-за требований к интерфейсу. Работает вполне нормально.   -  person Huntrods    schedule 28.12.2011


Ответы (4)


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

1- пространство не должно учитываться, если класс/таблица не может вырасти до огромных объемов. для имитации логических флагов достаточно крошечного int (1), и все, что вам нужно, это значения 0/1.

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

3- будет намного сложнее построить индексы по этому столбцу, когда они понадобятся, если это вообще будет возможно (на основе базы данных)

4. Больше работать и писать больше кода не должно быть проблемой. Сейчас вы работаете больше, но в будущем вы будете работать меньше. Думать, что это меньше работы для программиста / администратора баз данных, - это просто иллюзия ИМХО. вот некоторые соображения:

a- будет сложнее поддерживать код и писать запросы к базе данных. возможно, вы делаете все в своем Java-коде сейчас, но вы никогда не знаете, что ждет вас в будущем.

b- сделать структурные изменения становится сложнее. что, если клиент требует удалить два флага и добавить 4? Вы сохраняете исходные два бита, которые содержали удаленные флаги в базе данных, и добавляете 4 бита? или вы используете их для двух новых флагов, а затем добавляете еще два бита? как это повлияет на уже написанный код? и насколько легко было бы отслеживать все места и фактически вносить изменения в код?

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

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

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

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

person Community    schedule 07.12.2011

взгляните на Тип столбца SET

person zed_0xff    schedule 07.12.2011

Вы можете использовать EnumSet. Это лучший способ эмулировать флаги — гораздо более понятный по дизайну и почти такой же производительности, как int. Может быть легко переведен в int (для чтения/помещения в базу данных). Для получения дополнительной информации см. книгу «Эффективная Java», глава «EnumSet».

person korifey    schedule 07.12.2011

В основном вопросе вы спрашиваете, что эффективнее, чем лучше. Это усложняет ответ.

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

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

Как по мне, я предпочитаю маски - Меньше изменений в коде - Лучшее управление (здесь есть риск ограниченной целочисленной емкости)

person Damian Leszczyński - Vash    schedule 07.12.2011