Проект реляционной базы данных для представления сходства между строками одной таблицы - PullRequest
0 голосов
/ 17 марта 2020

Для справочных целей: я использую PostgreSQL с SQLAlchemy (Python).

Учитывая таблицу уникальных references как таковую:

references_table
-----------------------
  id | reference_code
-----------------------
   1 | CODEABCD1
   2 | CODEABCD2
   3 | CODEWXYZ9
   4 | CODEPOIU0
...

В В типичном сценарии у меня будет отдельная таблица items:

items_table
-----------------------
  id | item_descr
-----------------------
   1 | `Some item A`
   2 | `Some item B`
   3 | `Some item C`
   4 | `Some item D`
...

В таком типичном сценарии отношение «многие ко многим» между references и items устанавливается в соединительной таблице:

references_to_items
-----------------------
  ref_id (FK) | item_id (FK)
-----------------------
   1          | 4
   2          | 1
   3          | 2
   4          | 1
...

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

Однако, в моем сценарии нет items_table . Но я все же хотел бы смоделировать тот факт, что некоторые ссылки ссылаются на один и тот же (не представленный) элемент.

Я вижу возможность смоделировать это с помощью таблицы соединений многие-ко-многим как таковой (связывая FKs). таблицы references):

reference_similarities
-----------------------
  ref_id (FK) | ref_id_similar (FK)
-----------------------
   2          | 4
   2          | 8
   2          | 9
...

Где ссылки с ID 2, 4, 8 и 9 будут считаться «похожими» для целей моей модели данных.

Однако, неудобство здесь состоит в том, что такая модель требует выбора одной ссылки (выше id = 2) в качестве «точки опоры», для которой несколько других могут быть объявлены «похожими» в таблице reference_similarities. Ссылка 2 похожа на 4, а ссылка 2 похожа на 8 ==>, таким образом, 4 похожа на 8.

Таким образом, вопрос заключается в следующем: есть ли лучший дизайн, который не предполагает наличия ' pivot 'FK, как указано выше?

В идеале, я хотел бы сохранить "сходство" в виде массива FK как:

reference_similarities
------------------------
id  |  ref_ids (Array of FKs)
------------------------
  1 | [2, 4, 8, 9]
  2 | [1, 3, 5]

.. но я понимаю из https://dba.stackexchange.com/questions/60132/foreign-key-constraint-on-array-member, что в настоящее время невозможно иметь внешние ключи в PostgreSQL массивах . Поэтому я пытаюсь найти лучший дизайн для этой модели.

1 Ответ

1 голос
/ 17 марта 2020

Я понимаю, что вы хотите сгруппировать элементы в наборе и иметь возможность запрашивать набор из любого элемента в нем.

Вы можете использовать функцию ha sh, чтобы ha sh a установить, а затем использовать га sh в качестве значения поворота. Например, у вас есть набор значений (2,4,8,9), он будет хэшироваться следующим образом:

га sh = ((((31 * 1 + 2) * 31 + 4 ) * 31 + 8) * 31 + 9

Вы можете обратиться к Arrays.hashCode в Java, чтобы узнать, как получить sh список значений.

        int result = 1;

        for (Object element : a)
            result = 31 * result + (element == null ? 0 : element.hashCode());

Таблица reference_similities:

reference_similarities
-----------------------
  ref_id (FK) | hash_value
-----------------------
   2          | hash(2, 4, 8, 9) = 987204
   4          | 987204
   8          | 987204
   9          | 987204

Чтобы запросить набор, вы можете сначала запросить hash_value из ref_id, а затем получить все ref_id из hash_value.

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

Другое решение состоит в том, что вы можете просто написать функцию в Python для получения уникального значения hash_value при создании нового набора.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...