powered by simpleCommunicator - 2.0.59     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Отношение многие ко многим
17 сообщений из 17, страница 1 из 1
Отношение многие ко многим
    #35441679
_aleksa_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
Есть ли в Cache возможность организовать подобное отношение напрямую, или же придется ваять доп. класс, реализующий связку М-1-1-М?
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35441703
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Через класс...
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35441718
_aleksa_
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
так и знала.... изобретение велосипеда... на каждое такое отношение - по классу... :(
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35441875
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Выбор реализации много-ко-многим
Ссылка из документации на отношения (четвертая характеристика).

_aleksa_так и знала.... изобретение велосипеда... на каждое такое отношение - по классу... :(
Caché кроме объектного поддерживает ещё и реляционный подход. Как бы Вы работали с этими классами через SQL, если бы поддерживалось нативно many-to-many?
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35454450
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос в продолжение:
Если для реализации отношения "многие-ко-многим" используем класс-связь, как правильнее распределить мощность отношений? "Многие" должны быть со стороны связи или со стороны тех классов, которые связываем?
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35454526
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
На табличках же все показано...
servit Выбор реализации много-ко-многим
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35454560
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Что-то вот эдакое...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
/// Граждане
Class tmp.Mans Extends %Persistent
{

/// ФИО
Property FIO As %String;

/// Является работником
Relationship Workers As tmp.Workers [ Cardinality = many, Inverse = Man ];

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
/// Предприятия
Class tmp.Enterprises Extends %Persistent
{

/// Название
Property Name As %String;

/// Работники
Relationship Worker As tmp.Workers [ Cardinality = many, Inverse = Enterprise ];

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
/// Работники
Class tmp.Workers Extends %Persistent
{

/// Гражданин
Relationship Man As tmp.Mans [ Cardinality = one, Inverse = Workers ];

Index ManIndex On Man;

/// Предприятие
Relationship Enterprise As tmp.Enterprises [ Cardinality = one, Inverse = Worker ];

Index EnterpriseIndex On Enterprise;

}
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35456687
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Вопрос как раз о том, КАК это лучше сделать.

Так:
/// Граждане
...
Relationship Worker s As tmp.Workers [ Cardinality = many, Inverse = Man ];
...
или так:

/// Граждане
...
Relationship Worker As tmp.Worker [ Cardinality = one, Inverse = Man s ];
...
(ну и у связи и у второй стороны тоже мощности поменять)

Вроде бы разницы нет (есть подозрение, что в реализации это сведется просто к изменению порядка следования значений в индексе), а вот есть ли подводные камни?

И, следовательно, вопрос - где в таком случае удобнее(правильнее, выгоднее) держать мощность "много" - на классе-связке или на тех классах, для которых нужна реализация "*-*"?
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35456770
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesovВроде бы разницы нет
Странно что ты ее не видиш...
Вроде даже на словах понятно.
- Гражданин может работать в много каких местах
- У предприятия может быть много работников

А как ты опишеш свой "перевертыш"?
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35457209
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krvsa kolesovВроде бы разницы нет
Вроде даже на словах понятно.


Если считать что класс "Работник" - синтетический и создан исключительно для реализации связи **, тогда возникает желание убедиться в том, что:
- или оба способа ведет к одному результату, и тогда делать как кажется логичным (Ваш вариант);
- или один из способов дает бОльшие возможности.

Во втором случае мне сложно - я физик, а не математик. Т.е. рассуждаю примерно так:

Пусть есть "х" объектов класса "А" и "у" объектов класса "В". Каждый объект класса "А" имеет связь в среднем с "н" объектами класса "В"...

При каких значениях "х", "у", "н" выгоднее способ 1, а при каких - способ 2. Дальше могу предложить только эмпирически посчитать - генерируя данные и проводя на них выборки с джойном из "А" в "В" и обратно. В уравнениях не силен ;)

Начал я вот с чего...

один вариант:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
Class test1.App Extends %Persistent
{

Property P1 As %String;

Relationship Links As test1.User2App [ Cardinality = many, Inverse = App ];

}

Class test1.User Extends %Persistent
{

Property P1 As %String;

Relationship Links As test1.User2App [ Cardinality = many, Inverse = User ];

}

Class test1.User2App Extends %Persistent
{

Relationship App As test1.App [ Cardinality = one, Inverse = Links ];

Index AppIndex On App;

Relationship User As test1.User [ Cardinality = one, Inverse = Links ];

Index UserIndex On User;

}


Другой вариант:

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
Class test2.App Extends %Persistent
{

Property P1 As %String;

Relationship Link As test2.User2App [ Cardinality = one, Inverse = Apps ];

Index LinkIndex On Link;

}


Class test2.User Extends %Persistent
{

Property P1 As %String;

Relationship Link As test2.User2App [ Cardinality = one, Inverse = Users ];

Index LinkIndex On Link;

}

Class test2.User2App Extends %Persistent
{

Relationship Users As test2.User [ Cardinality = many, Inverse = Link ];

Relationship Apps As test2.App [ Cardinality = many, Inverse = Link ];

}

Потом заполняем это дело данными (пока по 1 записи):

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
test1()	//
	s a1 = ##class(test1.App).%New()
	s l1 = ##class(test1.User2App).%New()
	s u1 = ##class(test1.User).%New()
	
	s a1.P1 = $h
	s u1.P1 = $h
	s l1.User = u1
	s l1.App = a1
	d l1.%Save()
	
	s a2 = ##class(test2.App).%New()
	s l2 = ##class(test2.User2App).%New()
	s u2 = ##class(test2.User).%New()
	
	s a2.P1 = $h
	s u2.P1 = $h
	s a2.Link = l2
	s u2.Link = l2
	d l2.%Save()

Получаем такую картину (опуская счетчики):

^test1.AppD(1) = $lb("","61206,64593")
^test1.User2AppD(1) = $lb("","1","1")
^test1.User2AppI("AppIndex",1,1) = ""
^test1.User2AppI("UserIndex",1,1) = ""
^test1.UserD(1) = $lb("","61206,64593")

^test2.AppD(1) = $lb("","1","61206,64593")
^test2.AppI("LinkIndex",1,1) = ""
^test2.User2AppD(1) = $lb("")
^test2.UserD(1) = $lb("","1","61206,64593")
^test2.UserI("LinkIndex",1,1) = ""

С виду, оба варианта одинаковы? Или все же нет?

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

В общем, непоня-я-ятно ;(
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35457506
Фотография krvsa
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Не думаю что такие задачки нужно решать абстрактно (через X, Y и Z)... Типа потом подставьте вместо букв нужные смысловые значения...
Наверняка построение БД будет идти от смысловой нагрузки. Поскольку ввод данных должен быть удобен пользователям... Да и рапросы к БД будут не абстрактными, а "смысловыми" же...
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35458211
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
To kolesov

Рассмотрим второй вариант.

Допустим, в обоих классах у Вас не одно свойство P1, а много, например, 10. На каждую связь эти 10 свойств должны повторяться - отсюда избыточность данных. А если класс имеет сложную структуру и отображается на несколько таблиц?

Далее Вам, допустим, надо изменить одно из этих 10 полей. Придется менять не одну запись (объект), а много (сколько связей).

Далее, для того чтобы исключить дублирование связей, Вам придется создать уникальный индекс на 10+1 полей. Если сделаете эти 11 полей первичным ключом, потеряете возможность использовать bitmap-индексы.

Класс "test2.User2App" во втором варианте всегда будет пустым, не считая ID, так как отношения с кардинальностью many в БД не хранятся.

Опять же остаются проблемы с каскадностью (удаление/изменение) при доступе через SQL, а также с параллелизмом.

К тому же второй вариант не неверен, он - бессмысленен. Смысл появится, если отношения Apps и Users перенести в соответствующие классы (недостатки этого подхода см. выше).

PS: чтобы лучше понять отличия реализаций:
1) посмотрите табличные представления классов в обоих вариантах, не забыв заполнить их данными;
2) попробуйте поудалять данные и посмотрите не нарушится ли ссылочная целостность?
Еще погуглите по "много-ко-многим", например: Поддержка отношений вида много-ко-многим
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35459082
Бред
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
krvsaЧто-то вот эдакое...

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
/// Граждане
Class tmp.Mans Extends %Persistent
{

/// ФИО
Property FIO As %String;

/// Является работником
Relationship Workers As tmp.Workers [ Cardinality = many, Inverse = Man ];

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
/// Предприятия
Class tmp.Enterprises Extends %Persistent
{

/// Название
Property Name As %String;

/// Работники
Relationship Worker As tmp.Workers [ Cardinality = many, Inverse = Enterprise ];

}
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
/// Работники
Class tmp.Workers Extends %Persistent
{

/// Гражданин
Relationship Man As tmp.Mans [ Cardinality = one, Inverse = Workers ];

Index ManIndex On Man;

/// Предприятие
Relationship Enterprise As tmp.Enterprises [ Cardinality = one, Inverse = Worker ];

Index EnterpriseIndex On Enterprise;

}
----------
Cache for Windows (x86-32) 2007.1.3 (Build 607) Wed Oct 17 2007 02:12:09 EDT
Cache не поддерживает связи между объектами в принципе, а не только М:М (которых, впрочем, в действительности не существует). Можно принять и прозвучавшую причину: "чтобы был SQL".
В Cache объект (ради организации сявзи) рассматривается как свойство другого объекта, что не совсем то же самое, что ограничения целостности FK/PK в "реляционных системах", но почти то же самое):
В приведенном примере, в случае действительной поддержки связей, было бы не семь фрагментов описания метаданных, а пять, и, конечно, не было бы конструкций Index ... On ...:

Object {Man,Человек}
Object {Ent,Предприятие}
Object {Wor,Работник}
Relationship {Man,Wor,[номер связи],[тип связи],Является,Это}
Relationship {Ent,Wor,[номер связи],[тип связи],Состоит из,Работает на}

Здесь [номер связи] - так как может быть несколько связей между двумя объектами, и указывается семантика связи в обоих направлениях. В результате "приложение" уже можно использовать в рамках объектного навигатора, так как определены и имена объектов и имена связей, а не только, как и в "реляционных" СУБД, идентификаторы объектов (Man,Ent,Wor) и связей (в конструкции As ... в примере Cache), которые почему то часто называют именами.

Разумеется пользователь в своих схемах (которых для данного примера может быть довольно много, а ему разработчик в Cache навяжет одну):) должен иметь возможность изменять имена объектов, характеристик (часто говорят "свойств") объектов и связей между объектами.
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35470089
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Ну, в общем согласен - действуем по старому принципу: Если есть нечто, что мы хотим назвать "класс, реализующий отношение многие-ко-многим", вначале пытаемся для этого класса найти реальную предметную сущность, на которую можно повесить связь, а дальше действуем как обычно (1 вариант).

За редким исключением, так и выходит (пассажир-билет-автобус, человек-должность-работа, товар-строка-документ и т.д.).

В редком исключении остается двунаправленный список - но пока на ум не приходят примеры для него, да и на практике вроде бы если по факту у нас получается такой список, то лучше поискать, что мы упустили в начальных посылках ;)
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35491002
Бред
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesovНу, в общем согласен - действуем по старому принципу: Если есть нечто, что мы хотим назвать "класс, реализующий отношение многие-ко-многим", вначале пытаемся для этого класса найти реальную предметную сущность, на которую можно повесить связь, а дальше действуем как обычно (1 вариант).

За редким исключением, так и выходит (пассажир-билет-автобус, человек-должность-работа, товар-строка-документ и т.д.).

В редком исключении остается двунаправленный список - но пока на ум не приходят примеры для него, да и на практике вроде бы если по факту у нас получается такой список, то лучше поискать, что мы упустили в начальных посылках ;)
Уточню:)
1. Объект и Связь между объектами - это не одно и то же, и они не должны представляться в МД одинаково. Связь, в частности, отличается от объекта тем, что у нее нет и не может быть никаких характеристик (кроме характеристик метаданных: типа, семантики, ограничений). И это отличие, конечно же, не зависит от типа связи. Характеристик нет ни у связи 1:1, ни у связи 1:M, ни у связи М:М (если такие связи существуют).
2. Связи не являются характеристиками объектов. Никакие. Ни 1:1, ни 1:M, ни М:М.
3. Связи должны представляться одинаково, независимо от их типа.
4. Связи должны представляться симметрично для однородной двунаправленной навигации.
5. При объявлении на уровне метаданных (то есть на уровне концептуальной схемы, которая в случае ОМД выполняет и роль логической) связи между объектами A и B, на уровне данных каждый экземпляр объекта A связывается с экземплярами объекта B, а каждый экземпляр объекта B - с экземплярами объекта A (количество связанных экземпляров зависит от типа связи). Связываются, естественно, идентификаторы экземпляров. То есть "двунаправленные списки", о которых Вы говорите, существуют всегда, независимо от типа связи.
6. В универсальном объектном навигаторе пользователь сам может строить любые схемы, основанные на концептуальной модели. Например, пользователь может разместить запись накладной (операцию отгрузки) "выше", а накладную "ниже", тогда как "разработчик" обычно делает наоборот): И примеров такого рода (причем вполне объяснимых и обоснованных) на практике я видел очень много.

Одним из перспективных девизов, которые способны вывести БД из состояния многодесятилетнего застоя, может быть: свободная работа пользователя с концептуальной схемой вместо навязывания ему одной точки зрения путем программирования "приложений". К счастью, системы такого типа существуют, и я думаю, что будущее за ними. А не за системами, требующими неизбежного и постоянного программирования даже самых простых функций получения данных, и неизбежно требующими применения дополнительных систем восстановления навигации и смысла данных (все это происходит при использовании распространенных, к несчастью, "реляционных" систем).
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35521584
Фотография kolesov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
servitTo kolesov

Рассмотрим второй вариант.

...

К тому же второй вариант не неверен, он - бессмысленен. Смысл появится, если отношения Apps и Users перенести в соответствующие классы (недостатки этого подхода см. выше).



Странно, нашел в своей системе такую штуку:
- груз приходит на судне (3-мя коносаментными партиями), например 3500 тонн, 1500 тонн и 900 тонн.
- выгружается в вагоны (приблизительно по 60 тонн в вагон)

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

Реализовано:
груз(один) - (много) порция выгрузки груза(много) - (один)вагон
Понятно, что объектов больше и объект "груз" - сложная конструкция, но в общем именно так:
1-М-М-1

И нормально работает... и вполне со смыслом... Не спорю, это не "отношение" в математическом смысле... Но мы с вами вроде программисты, а не математики ;)
...
Рейтинг: 0 / 0
Отношение многие ко многим
    #35524095
servit
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
kolesovРеализовано:
груз(один) - (много) порция выгрузки груза(много) - (один)вагон
Понятно, что объектов больше и объект "груз" - сложная конструкция, но в общем именно так:
1-М-М-1

И нормально работает... и вполне со смыслом...
1) вариант 1:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Class test1.a Extends %Persistent
{
  Property Name As %String;
  Relationship ab As test1.ab [ Cardinality = many, Inverse = a ];
}
Class test1.b Extends %Persistent
{
  Property Name As %String;
  Relationship ab As test1.ab [ Cardinality = many, Inverse = b ];
}
Class test1.ab Extends %Persistent
{
  Property Name As %String;
  Relationship a As test1.a [ Cardinality = one, Inverse = ab ];
  Relationship b As test1.b [ Cardinality = one, Inverse = ab ];
}
Данные:

Таблица test1.a
ID Name1 груз12 груз2
Таблица test1.b
ID Name1 вагон12 вагон2
Таблица test1.ab
ID Name a b1 порция1 1 12 порция2 1 23 порция3 2 14 порция4 2 2
2) вариант 2:
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
Class test2.a Extends %Persistent
{
  Property Name As %String;
  Relationship ab As test2.ab [ Cardinality = one, Inverse = a ];
}
Class test2.b Extends %Persistent
{
  Property Name As %String;
  Relationship ab As test2.ab [ Cardinality = one, Inverse = b ];
}
Class test2.ab Extends %Persistent
{
  Property Name As %String;
  Relationship a As test2.a [ Cardinality = many, Inverse = ab ];
  Relationship b As test2.b [ Cardinality = many, Inverse = ab ];
}
Данные:

Таблица test1.a
ID Name ab1 груз1 12 груз1 23 груз2 34 груз2 4
Таблица test1.b
ID Name ab1 вагон1 12 вагон1 33 вагон2 24 вагон2 4
Таблица test1.ab
ID Name1 порция12 порция23 порция34 порция4
...
Рейтинг: 0 / 0
17 сообщений из 17, страница 1 из 1
Форумы / Caché, Ensemble, DeepSee, MiniM, IRIS, GT.M [игнор отключен] [закрыт для гостей] / Отношение многие ко многим
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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