Сокращение избыточности данных для хранения в MySQL - PullRequest
2 голосов
/ 08 декабря 2010

У меня такое чувство, что на него уже ответили, но я не знаю правильной терминологии и не смог найти ничего в моем поиске.

Я работаю над системой рекомендаций по продукту. И у меня есть база данных предметов, и я проверяю, какие предметы похожи. Например, ItemID 1 похож на 5, 7 и 8. Проблема заключается в избыточности данных. Когда я перебираю весь набор предметов, я получаю что-то вроде этого:

1 5,7,8
5 7,8,1
7 8,5,1
8 5,1,7

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

Ответы [ 3 ]

1 голос
/ 08 декабря 2010

Это называется «структура данных графа». Числа (1,5,7,8) являются узлами. Каждое соединение (1-5,1-7,1-8,5-7 и т. Д.) Являются ребрами.

http://en.wikipedia.org/wiki/Graph_(data_structure)

В MySQL вы должны хранить ребра как одно ребро на строку. Если каждое ребро соединяется в обоих направлениях, вы должны добавить каждое ребро, идущее в обоих направлениях (то есть 1-5 и 5-1). Я бы настроил таблицу примерно так:

TABLE edges (
  id PRIMARY KEY AUTO_INC,
  from INT,
  to INT
)

Вам понадобится индекс в зависимости от (от) или, возможно, (от, до). Чтобы найти все объекты, относящиеся к тому, на который вы смотрите:

SELECT to FROM edges WHERE from = X;

В эту простую модель можно внести множество улучшений, но это только начало.

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

1 голос
/ 08 декабря 2010

Крис прав и неправ одновременно.Он прав в том, что это «структура данных графа», но не упоминает, что его подход заставил бы вас оказаться в нескольких подзапросах для поиска графа.

Пожалуйста, сделайте одолжение и посмотрите на Nested Set модель.Вы можете обратиться к руководству MySQL , чтобы начать работу.

С уважением

1 голос
/ 08 декабря 2010

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

Вместо (1, {5,7,8}), (5, {7,8,1}) у вас будет (1, 5), (1, 7), (1, 8), ( 5, 7), (5, 8), (5, 1). Затем, чтобы увидеть, какие предметы похожи на пункт 8, вам нужно просто выбрать источник, где пункт назначения = 8.

...