Как предотвратить логические дубликаты в унарных таблицах отношения один ко многим SQL - PullRequest
0 голосов
/ 15 марта 2020

В ненаправленных унарных отношениях, что было бы лучшим вариантом для предотвращения логических дубликатов?

EG

Основная таблица

ID
--
1
2

Реляционная таблица

ID1    ID2
-----------
1      2
2      1

Запись два в реляционной таблице уже логически представлена ​​первой записью, поскольку связь не является направленной

1 Ответ

2 голосов
/ 15 марта 2020

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

Во-первых, настаивайте на том, чтобы id1 < id2 и чтобы пара была уникальной:

alter table relations add constraint check (id1 < id2);
alter table relations add constraint unique (id1, id2);

Это может иметь некоторые непредвиденные последствия , Вы не можете вставить (2, 1) в таблицу.

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

create unique index unq_id1_id2
    on (least(id1, id2), greatest(id1, id2));

На SQL Сервере вы можете сделать это с помощью вычисляемых столбцов:

alter table relations add least_id1_id2 as
    (case when id1 < id2 then id1 else id2 end) persisted;

alter table relations add greatest_id1_id2 as
    (case when id1 < id2 then id2 else id1 end) persisted;

create unique index unq_relations_id1_id2 on relations(least_id1_id2, greatest_id1_id2);

Здесь - это дБ <> скрипка.

...