Rails: дизайн базы данных для уникального набора предметов с переменной длиной - PullRequest
1 голос
/ 18 декабря 2011

У меня есть таблица предметов. В этой таблице, скорее всего, будет около 5 пунктов, и я не ожидаю, что она значительно вырастет. У меня есть другая таблица под названием Orders с сотнями тысяч строк. Каждый заказ должен ссылаться на некоторую комбинацию из 5 пунктов (может быть 0 пунктов (ноль), может быть все 5 или где-то посередине). Ни один предмет не может быть посчитан дважды, и порядок предметов не имеет значения. Это отношения многие ко многим.

Я хочу извлечь выгоду из того факта, что комбинация предметов конечна. Таким образом, если Орден уже ссылался на конкретную комбинацию элементов, второй Орден может ссылаться на тот же набор элементов вместо дублирования связей «многие ко многим» в таблице соединений. При таком количестве заказов таблица соединения items_orders будет огромной, и я считаю, что это излишне.

Как бы вы решили эту проблему?

Ответы [ 2 ]

1 голос
/ 18 декабря 2011

Чтобы подсчитать комбинации:

  • 1 комбинация из 5 предметов
  • 5 комбинаций из 4 предметов
  • 10 комбинаций из 3 предметов
  • 10 комбинаций из 2 предметов
  • 5 комбинаций из 1 предмета

Итак, вы хотели бы исправить таблицу из 31 различных комбинаций из 5 предметов. Тогда у вас будет стол

class Combo < ActiveRecord::Base
   has_many :items
   has_many :orders
end
class Item < ActiveRecord::Base
   belongs_to :item
end
class Order < ActiveRecord::Base
   belongs_to :combo
end

И это кажется хорошим, потому что ваши столы красивые и компактные. Таблица позиций ограничена 5 элементами, комбинированная таблица - 31 позицией, а таблица заказов варьируется до 1000000 записей.

Вы могли бы еще больше упростить и избавиться от таблиц Item и Combo и просто жестко их кодировать. В конце концов, они оба ограничены в довольно небольшом количестве. Аналогия в том, что если у вас есть приложение, которое должно выполнять факторные вычисления до 100, вы можете сделать это очень быстро, просто имея жестко закодированную таблицу поиска.

У этого решения есть пара проблем. Ваша программа обеспечения заказа должна знать обо всех комбинациях и определять, какую из них выбрал пользователь. Так что это просто таблица поиска или цепочка операторов с 31 вариацией. Возможно, но подвержено ошибкам. Y

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

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

class ItemOrder < ActiveRecord::Base
   belongs_to :item
   belongs_to :order
end
class Item < ActiveRecord::Base
   has_many :item_combo
end
class Order < ActiveRecord::Base
   has_many :item_combo
end
1 голос
/ 18 декабря 2011

Таблицы базы данных могут обрабатывать миллионы, если не миллиарды записей. Я думаю, что @coreyward достиг того, что вы не должны преждевременно оптимизировать код. Создайте его так, чтобы он вам подходил, и решайте проблемы с производительностью по мере их возникновения. Кроме того, всегда есть вероятность, что к тому времени, когда вам понадобится повысить производительность, вы все равно захотите изменить свое приложение или базу данных. Время, которое вы сэкономили, не пытаясь выжать все до конца, можно использовать для устранения реальных проблем.

...