отношение «многие ко многим», разумное сравнение с таблицей линкеров - PullRequest
2 голосов
/ 06 августа 2010

Таблица базы данных, скажем, бургер, содержит поле, в котором биты хранятся как целочисленное значение, поэтому оно имеет значение 1,2,4,8,16 ...

Вторичная таблица содержит значения 1 = сыр, 2 = помидор, 4 = яйцо, 8 = салат, 16 = майонез

Сравнение по битам позволяет любому бургеру иметь любую комбинацию начинки (для непосвященного бургер с валом 24 будет иметь майонез и салат (16 + 8), а бургер с валом 5 будет иметь сыр, яйцо и т. Д.) .

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

Однако я беру на себя кого-то, кто был, как правило, очень хорош в техническом отношении; так есть ли какие-то другие преимущества, которые мне не хватает? Как мне кажется, есть два недостатка: он ограничивает количество различных наполнений, и это странно / необычно (зависание от того, когда память была основным соображением?).

Ответы [ 3 ]

1 голос
/ 06 августа 2010

Единственное преимущество, которое я вижу, состоит в том, что это может сделать относительно легким возврат поля, разделенного запятыми, содержащего все начинки гамбургера и другие данные, все в одной строке.Впрочем, я не знаю, как это будет сделано.Мне было бы интересно увидеть этот SQL, если это так.

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

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

0 голосов
/ 06 августа 2010

Вы можете обойти это решение, добавив таблицу, которая будет выглядеть следующим образом:

Table: Fillings
Id  Cheese Tomato Egg Lettuce Mayo
 0     N      N     N     N     N
 1     Y      N     N     N     N
 2     N      Y     N     N     N
 3     Y      Y     N     N     N
...
31     Y      Y     Y     Y     Y

, тогда вы можете сказать:

select
    count(1) as WithCheeseButNoTomato
from Burger as b
join Fillings as f on f.Id = b.FillingId
where Cheese = 'Y'
  and Tomato = 'N' ;

Любые предполагаемые преимущества содержатся в заполнении интерфейсавыделение или на прикладном уровне.

0 голосов
/ 06 августа 2010

Используя битовые маски таким способом, вы не сможете использовать возможности проверок ссылочной целостности SQL.Что произойдет, если я введу значение 128?Нет такой записи в вашей таблице поиска.При правильном выполнении ограничений внешнего ключа, если я попытаюсь загрузить значение, которое не существует в таблице поиска, я получу ошибку, и значение (должным образом) не будет загружено в базу данных.

Этоможет быть быстрее и проще (и интереснее) реализовать побитовые операторы, но должным образом нормализованные базы данных могут быть намного проще поддерживать и поддерживать их со временем.

...