Как хранить двунаправленные отношения - PullRequest
6 голосов
/ 17 сентября 2010

Я пишу код, чтобы найти дубликаты данных о клиентах в базе данных. Я буду использовать расстояние Левенштейна.

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

Что меня смущает, так это как хранить двунаправленный характер отношений.

Я начал приводить несколько примеров ниже, но подумал, есть ли лучшая практика для хранения данных такого типа,

Пример данных

id, адрес

001, 5 Мейн-стрит
002, 5 Главный ул.
003, 5 Главная ул.
004, 6 High Street
005, Малая улица, 7
006, 7 Low St

Предложение 1

customer_id1, customer_id2, relations_strength
001, 002, 0,74
001, 003, 0,77
002, 003, 0,76
005, 006, 0,77

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

например, потребуется включить: 002, 001, 0,74

Предложение 2

customer_id, grouping_id
001, 1
002, 1
003, 1
005, 2
006, 2

Ответы [ 3 ]

7 голосов
/ 17 сентября 2010

Способ работы с симметричными отношениями в реляционной системе заключается в следующем:

  • выберите каноническую форму, в которой хранятся симметричные пары, например, customer_id1
  • Определить представление SYMM_TBL как выбрать id1, id2, ... from ... UNION выбрать id2 как id1, id1 как id2, ... FROM ...

Приличные системы не должны наказывать вас в области производительности при запросе этого представления.

6 голосов
/ 17 сентября 2010

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

Думайте об этом как о матрице.Если мы пойдем на оптимальную обработку, мы не будем выполнять дублирование выигрышей.Таким образом, мы оцениваем адрес 1 по всем другим адресам, мы оцениваем адрес 2 по всем другим адресам, кроме адреса 1, мы оцениваем адрес 3 по всем другим адресам, кроме адресов 1 и 2 и т. Д.как таблица футбольной лиги:

          addr  
          1    2     3    4     5
addr
  1       -   95    95   80    76 
  2       -    -   100   75    72
  3       -    -     -   75    72
  4       -    -     -    -    83
  5       -    -     -    -     -

Эти данные лучше всего хранить в предложении 1, таблице ID1, ID2, SCORE.Хотя нам нужно повернуть данные, чтобы результат выглядел следующим образом:)

В правильной таблице лиги есть два набора результатов - Хозяева и Гости - поэтому таблица симметрична.Но это здесь не применимо, так как расстояние редактирования для 1 > 2 такое же, как 2 > 1.Однако это сделает запрос результатов более простым, если в набор результатов будут включены отраженные результаты.То есть для записей (1,5,76), (2,5,72) и т. Д. Мы генерируем записи (5,1,76), (5,2,72).Это может быть сделано в конце процесса оценки.

          addr  
          1    2     3    4     5
addr
  1       -   95    95   80    76 
  2      95    -   100   75    72
  3      95  100     -   75    72
  4      80   75    75    -    83
  5      76   72    72   83     -

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

select case when id1 = 5 then id1 else id2 end as id1
       , case when id1 = 5 then id2 else id1 end as id2 
       , score
from   your_table
where  id1 = 5 
or     id2 = 5
/
1 голос
/ 17 сентября 2010

Как всегда, это зависит от того, что вы хотите сделать с данными после их расчета.

Если предположить, что просто идентифицировать или найти дубликаты, то ваше предложение 1 - это то, что я бы использовал, то естьВторая таблица, которая просто хранит пары и сильные стороны.Мое единственное предложение - сделать сильные числа масштабными целыми числами, а не десятичными.

...