powered by simpleCommunicator - 2.0.61     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как связать объекты?
11 сообщений из 11, страница 1 из 1
Как связать объекты?
    #33630359
Alexander_F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Возникла такая проблема.

Есть несколько таблиц, которые описывают различные объекты.
В каждой таблице ключ состоит из 4х полей (ID1, ID2, ID3,ID4).

Есть таблица связей Relations, в которой хранятся составные ключи пары связанных объектов, типы объектов и тип связи, т.е.

Relations
=======
Object1_ID1
Object1_ID2
Object1_ID3
Object1_Id4
Object1_Type
Object2_ID1
Object2_ID2
Object2_ID3
Object2_Id4
Object2_Type
RelationType

Связь объектов не иерархическая, т.е. если мы хотим выбрать все связанные объекты с данным, необходимо смотреть как в полях Object1, так и в полях Object2.

Выбрать все связанные объекты не проблема.

Проблема возникает при выборе несвязанных объектов, т.е. необходимо вывести пользователю список объектов, которые не связаны с данным, для того, чтобы он смох их привязать.

Вопрос: как написать такой запрос, подскажите пожалуйста?
...
Рейтинг: 0 / 0
Как связать объекты?
    #33630399
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander_FВ каждой таблице ключ состоит из 4х полей (ID1, ID2, ID3,ID4).
Это сомнительное решение. Обычно в такой ситуации следует сделать дополнительный суррогатный ключ, а на эти четыре поля сделать альтернативный ключ, он же unique constraint.

Alexander_FЕсть таблица связей Relations, в которой хранятся составные ключи пары связанных объектов, типы объектов и тип связи, т.е.
То есть Вы вдобавок сделали денормализацию - вынесли поле "тип объекта" из таблицы объектов в таблицу связей? Уверены, что уместно?

Alexander_FПроблема возникает при выборе несвязанных объектов, т.е. необходимо вывести пользователю список объектов, которые не связаны с данным, для того, чтобы он смох их привязать.
Ключевое слово для поиска - antijoin. В зависимости от используемой СУБД оптимальная реализация может быть разной; самое простое

Код: plaintext
1.
2.
3.
-- выбрать записи из a, не упомянутые в b
select a.*
from a left join b on (a.id = b.id)
where b.id is null
...
Рейтинг: 0 / 0
Как связать объекты?
    #33630420
Кот Матроскин
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
Select id1, id, id3, id
from odjects o
       left join (select object1_id1 as id1, object1_id2 as id2, object1_id3 as id3, object1_id4 as id4
                    from relarions r
                    where object2_id1 = @id1 and
                             object2_id1 = @id2
                            object2_id1  = @id3
                             object2_id1 = @id4 
                     union all
                     select object2_id1, object2_id2, object2_id3, object2_id3
                    from relarions r
                    where object1_id1 = @id1 and
                             object1_id1 = @id2
                            object1_id1  = @id3
                             object1_id1 = @id4 

                            ) t
             on t.id1 = o.id1 and
                 t.id2 = o.id2 and
                 t.id3 = o.id3 and
                 t.id4 = o.id4
where t.id1 is null
...
Рейтинг: 0 / 0
Как связать объекты?
    #33630661
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Это вопрос все таки не по проектированию БД, а по реализации запроса в конкретной СУБД. А что касается проектирования, то тут действительно 4 ключевых поля громоздко слишком, если сделать суррогатный ключ, то и таблицы связей на 6 полей сократятся и запросы будут не так страшно выглядеть. Ну все от задачи естесно...
...
Рейтинг: 0 / 0
Как связать объекты?
    #33631337
Alexander_F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Я не совсем полно описал задачу. Исправляюсь.

Каждый объект имеет свою таблицу.
Например, документы, организации, лица:

Document Organization Person
======= ========== ======
ID1 ID1 ID1
ID2 ID2 ID2
ID3 ID3 ID3
ID4 ID4 ID4
DocName OrgName PersonName
... ... ...

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

СУБД использую Oracle 9i, хотя честно говоря не вижу причины как это может зависить от СУБД, SQL-запрос получается классический.

На сколько я понял, мне нужно идти от обратного, т.е. ,например, смотреть в таблице документов объекты, которых нет в таблице связей (Relations), причем смотреть как в полях Object1, так и в полях Object2.
...
Рейтинг: 0 / 0
Как связать объекты?
    #33632026
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Проще всего
Код: plaintext
1.
2.
3.
4.
select ID1, ID2,  ID3, Id4 from objects
minus ( 
  select Object1_ID1, Object1_ID2,  Object1_ID3, Object1_Id4 from relations
  union
  select Object2_ID1, Object2_ID2,  Object2_ID3, Object2_Id4 from relations)
а далее зависит от СУБД и таблиц - индексы и прочая оптимизация
...
Рейтинг: 0 / 0
Как связать объекты?
    #33634420
Alexander_F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Ну хорошо, допустим. Хотя я писал, что таблицы Objects нет, есть отдельная таблица для каждого объекта.

А как из этого запроса, зная полученные ключи, получить полную информацию об объектах?
...
Рейтинг: 0 / 0
Как связать объекты?
    #33634455
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Э, ну как Вы обычно это делаете - Join , IN и т.д. В SQL для этого достаточно средств, а про оптимизацию лучше спрашивать на форумах по конкретным СУБД.
...
Рейтинг: 0 / 0
Как связать объекты?
    #33634503
Alexander_F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
JOIN, IN - это понятно. Хотя IN не получится с составным ключем из 4-х полей.
Можно конечно сделать отображение в одно поле... подумаю...

А как можно прменить JOIN к вашему примеру?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select ID1, ID2,  ID3, Id4 from objects
minus 
( 
  select Object1_ID1, Object1_ID2,  Object1_ID3, Object1_Id4 from relations
  union
  select Object2_ID1, Object2_ID2,  Object2_ID3, Object2_Id4 from relations
)
...
Рейтинг: 0 / 0
Как связать объекты?
    #33634699
Alexander_F
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Разобрался. Вот пример:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
SELECT D1.RegionID, D1.CopyID, D1.ProgID, D1.ID, D1.DocName FROM
(
SELECT D.RegionID, D.CopyID, D.ProgID, D.ID FROM Documents D
MINUS
( 
  SELECT R1.RegionID1, R1.CopyID1, R1.ProgID1, R1.ID1 
  FROM Relations R1
  WHERE (R1.RegionID2 =  77 ) AND (R1.CopyID2 =  1 ) AND (R1.ProgID2 =  1 ) AND (R1.ID2 =  61 ) AND (R1.Object1Type = 'DOC') AND (R1.Object2Type = 'DOC')  
  UNION
  SELECT R2.RegionID2, R2.CopyID2, R2.ProgID2, R2.ID2 
  FROM Relations R2
  WHERE (R2.RegionID1 =  77 ) AND (R2.CopyID1 =  1 ) AND (R2.ProgID1 =  1 ) AND (R2.ID1 =  61 ) AND (R2.Object1Type = 'DOC') AND (R2.Object2Type = 'DOC')
  UNION
  SELECT  77 ,  1 ,  1 ,  61  
  FROM Relations R3
)
) P
LEFT OUTER JOIN Documents D1 ON D1.RegionID = P.RegionID AND D1.CopyID = P.CopyID AND D1.ProgID = P.ProgID AND D1.ID=P.ID
...
Рейтинг: 0 / 0
Как связать объекты?
    #33634776
_spy_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Alexander_FХотя IN не получится с составным ключем из 4-х полей
Ну почему же. А если как-нибудь так?

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
select * from Documents 
  where id1 <> id1_trgt and id2 <> id2_trgt and id3 <> id3_trgt and id4 <> id4_trgt
  and (id1, id2, id3, id4) not in
  (select id1_1, id1_2, id1_3, id1_4 from Relations
     where id1_trgt <> id2_1 and id2_trgt <> id2_2 and id3_trgt <> id2_3 and id_trgt <> id2_4
  union
  select id2_1, id2_2, id2_3, id2_4 from Relations
     where id1_trgt <> id1_1 and id2_trgt <> id1_2 and id3_trgt <> id1_3 and id_trgt <> id1_4)
где id[x]_trgt - идентификатор объекта, для которого нужно найти несвязанные.
...
Рейтинг: 0 / 0
11 сообщений из 11, страница 1 из 1
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Как связать объекты?
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]