Как я могу сохранить массив логических значений в базе данных MySql? - PullRequest
3 голосов
/ 01 июля 2010

В моем случае каждый «предмет» либо имеет свойство, либо нет.Свойств может быть несколько сотен, поэтому мне понадобится, скажем, не более 1000 истинных / ложных битов на элемент

Есть ли способ сохранить эти биты в одном поле элемента?

Ответы [ 4 ]

3 голосов
/ 01 июля 2010

Если вы ищете способ сделать это способом, доступным для поиска, то нет.

Пара методов поиска (включающих более 1 столбца и / или таблицы):

  • Используйте набор из SET столбцов.Вы ограничены 64 предметами (вкл / выкл) в наборе, но вы, вероятно, не можете найти способ сгруппировать их.
  • Используйте 3 таблицы: Предметы (id, ...), FlagNames (id), name) и сводная таблица ItemFlags (item_id, flag_id).Затем вы можете запросить элементы с помощью объединений .

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

  • Использовать встроенные в ваш язык средства (сериализация / десериализация PHP).
  • Объединить серию символов "y" и "n" вместе.
  • Бит-упаковать ваши значения в строку (8 бит на символ) в клиенте перед вызовом базы данных MySQL и распаковатьих при извлечении данных из базы данных.Это наиболее эффективный механизм хранения (если все строки одинаковы, используйте char [x], а не varchar [x]) за счет отсутствия данных для поиска и немного более сложного кода.
3 голосов
/ 01 июля 2010

Я бы предпочел что-то вроде:

Properties
ID, Property
1, FirsProperty
2, SecondProperty

ItemProperties
ID, Property, Item
1021, 1, 10
1022, 2, 10

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

0 голосов
/ 01 июля 2010

Строго говоря, вы можете сделать это, используя следующее:

$bools = array(0,1,1,0,1,0,0,1);
$for_db = serialize($array);

// Insert the serialized $for_db string into the database. You could use a text type
// make certain it could hold the entire string.
// To get it back out:

$bools = unserialize($from_db);

Тем не менее, я настоятельно рекомендую посмотреть на альтернативные решения.

В зависимости от варианта использования вы можете попробовать создать таблицу «item», которая имеет отношение «многие ко многим» со значениями из таблицы «attribute». Это будет стандартная реализация шаблона проектирования общей базы данных значений атрибутов сущности для хранения переменных точек данных об общем наборе объектов.

0 голосов
/ 01 июля 2010

В худшем случае вам придется использовать символ (1000) [ynnynynnynynnynny ...] или тому подобное.Если вы хотите упаковать его (например, в гекс не так уж плохо), вы можете сделать это с символом (64) [шестнадцатеричные символы].

Если он меньше 64, тогдаТип SET будет работать, но, похоже, этого недостаточно.

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

Так что да, похоже, что вам лучше всего упаковать ее в строку, а затем сохранить это.

Следует отметить, что VARCHAR будет тратить пространство впустую, поскольку вы точно знаете, сколько места занимают ваши данныевозьму, и могу точно его выделить.(Хорошо иметь строки фиксированной ширины)

...