|
|
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Sgt.PepperВы несколько снисходительно заявили, что есть методы попроще, без IS_MAIN-ов А вот здесь сами его фактически стали использовать в update По сути npp - это аналог приоритета, а не тупенького is_main, то есть, это обобщение is_main-а. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.08.2008, 16:58 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Сергей ВаскецовДа. В перечне подразделений оно будет первым. Или последним. Как захотите. Если сделать функцию, возвращающую по работе ее главное подразделение, можно и отдельно его отображать. Отлично. Вам ТАК нравится спроектировать GUI. Но у пользователя есть возможность их двигать вверх-вниз?... Одним словом, как бы ни строился пользовательский интерфейс, есть возможность сказать "главное было с id_cust = 2, а теперь пусть будет главным с id_cust = 1" что произойдет с таблицей?... (npp=0 у обеих записей). Я Вас так понял, что всем "неглавным" надо присвоить npp больший, чем у главного?.. одинаковый?.. разный?... В многабукав я не нашел объяснения КАК это должно делаться. Если npp=0 у главного и npp=1 у неглавного, то чем отличается npp от IS_MAIN?... Сергей ВаскецовПо сути npp - это аналог приоритета, а не тупенького is_main, то есть, это обобщение is_main-а. напишите, плиз, корректный update при смене главного подразделения, все сразу встанет на свои места... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2008, 07:51 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Если мы решаем задачу существования главного подразделения, а не ранжирования подразделений в общем виде, то правильнее, IMHO, сделать отдельную таблицу - "Работа-Главное ПЗ" с PRIMARY KEY(ID_JOB) и FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). В таблице "Работа-ПЗ" для этого нужен либо PRIMARY KEY(ID_JOB, ID_Customer), либо UNIQUE(ID_JOB, ID_Customer) и CHECK (ID_JOB IS NOT NULL AND ID_Customer IS NOT NULL). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2008, 11:33 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChAЕсли мы решаем задачу существования главного подразделения, а не ранжирования подразделений в общем виде, то правильнее, IMHO, сделать отдельную таблицу - "Работа-Главное ПЗ" с PRIMARY KEY(ID_JOB) и FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). В таблице "Работа-ПЗ" для этого нужен либо PRIMARY KEY(ID_JOB, ID_Customer), либо UNIQUE(ID_JOB, ID_Customer) и CHECK (ID_JOB IS NOT NULL AND ID_Customer IS NOT NULL). Правда, тогда для списка ВСЕХ подразделений нужен UNION?... Но интересовали "методы попроще", может быть там есть какое-то рациональное зерно... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2008, 15:52 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Sgt.Pepper ChAЕсли мы решаем задачу существования главного подразделения, а не ранжирования подразделений в общем виде, то правильнее, IMHO, сделать отдельную таблицу - "Работа-Главное ПЗ" с PRIMARY KEY(ID_JOB) и FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). В таблице "Работа-ПЗ" для этого нужен либо PRIMARY KEY(ID_JOB, ID_Customer), либо UNIQUE(ID_JOB, ID_Customer) и CHECK (ID_JOB IS NOT NULL AND ID_Customer IS NOT NULL). Правда, тогда для списка ВСЕХ подразделений нужен UNION?Или я не понял Ваших сомнений, или Вы несколько невнимательно отнеслись к предложенной схеме. Все подразделения и так находятся в таблице "Работа-ПЗ", включая и "главное". В таблице "Работа-Главное ПЗ" есть только факт, которое из них считать главным. Так что необходимость в UNION "для списка ВСЕХ подразделений" отсутствует. Sgt.PepperНо интересовали "методы попроще", может быть там есть какое-то рациональное зерно...На мой взгляд, более-менее вменяемый способ был упомянут ранее , но у него есть сильный недостаток. Для того чтобы обойтись только ограничениями, для таблицы "Работа" надо будет сделать обратный FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). К сожалению, формально для таблицы "Работа-ПЗ" уже должен быть FOREIGN KEY ON "Работа" (ID_JOB). Т.е., у нас образуется так называемая циклическая связь, что позволяют не все СУБД, да и просто может вызвать сложности с определением, типа, "что раньше - яйцо или курица". Лично я стараюсь избегать таких неоднозначностей в схеме. Если же обратной связи ("Работа-ПЗ"->"Работа") не делать, то возникает риск ввести в качестве главного подразделения то, которое вовсе не участвует в списке допустимых. Если же считать его допустимым, но дополнительным к списку в "Работа-ПЗ", то оно, во-первых, может оказаться дублирующим, во-вторых, для получения списка всех подразделений придется использовать упомянутый Вами UNION. Кроме того, процедура замены главного подразделения может оказаться не очень тривиальной, хотя при наличии транзакций это и не проблема, но по моему глубочайшему убеждению, нужно стремиться, чтобы изменение одного факта выполнялось за минимальной число модифицирующих операций(в идеале за одну). Так что при всей, казалось бы, простоте решения, на мой взгляд, этот вариант не очень привлекателен в реализации. В предложенным мною вариант корректность данных определяется стандартным механизмом ограничений. Надеюсь очевидно, что изменение главного подразделения тоже не вызывает каких-либо сложностей, простейший UPDATE. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2008, 18:01 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChAИли я не понял Ваших сомнений, или Вы несколько невнимательно отнеслись к предложенной схеме. Все подразделения и так находятся в таблице "Работа-ПЗ", включая и "главное". В таблице "Работа-Главное ПЗ" есть только факт, которое из них считать главным. Так что необходимость в UNION "для списка ВСЕХ подразделений" отсутствует. Согласен, разобрался... Все дальнейшее тоже вполне приемлимо на первый взгляд, хотя и в IS_MAIN или id_cust_main каких-либо непоправимых бед не усматривается. Просто весь спор был попыткой разобраться в экзотическом решении коллеги. А в принципе проблема, как мне кажется, совершенно пустяковая, не стОит четырех страниц :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.08.2008, 20:36 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Sgt.Pepperв IS_MAIN или id_cust_main каких-либо непоправимых бед не усматривается.Смотря что считать бедой, да еще и непоправимой. На мой взгляд, корректность данных должна максимально определяться схемой БД, а не какой-либо последовательностью кода. Оба упомянутых решения как раз требуют написания такого кода. Более того, если правильно помню определения, то решение с IS_MAIN вообще нарушает 4НФ, которая запрещает зависимость кортежей друг от друга. Sgt.PepperА в принципе проблема, как мне кажется, совершенно пустяковая, не стОит четырех страницЛирика и злостный офтоп: проблемы всегда в людях, а для этого и четырех страниц может оказаться маловато :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.08.2008, 01:16 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChAЛирика и злостный офтоп: проблемы всегда в людях, а для этого и четырех страниц может оказаться маловато :) Злостный? :) Больше не буду, воля Ваша. А по поводу "проблемы всегда в людях" не то что четыре страницы, цельные библиотеки написаны, вряд ли мы тут с Вами что-то существенное к Гоголю и Достоевскому добавим, простите еще раз за лирику... :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.08.2008, 17:55 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Sgt.PepperВам ТАК нравится спроектировать GUI Я начинаю сомневаться в Вашей адекватности. Где-то я давал определенные рекомендации по провектировню GUI, которые бы следовали из предлагаемой мной схемы? Sgt.PepperНо у пользователя есть возможность их двигать вверх-вниз? Безусловно есть. Sgt.Pepperесть возможность сказать "главное было с id_cust = 2, а теперь пусть будет главным с id_cust = 1" что произойдет с таблицей?... (npp=0 у обеих записей) Если предположить главенство подразделения с максимальным npp, то схематично примерно что-то типа update job_cust set npp=(select max(npp)+1) where id_job=N and id_cust = 1, если уж Вы так привязались к этому "id_cust = 1". Если главное подразделение с минимальным npp - аналогично. Также никто не мешает выполнять update job_cust set npp=(case when id_cust=1 then A else B end) where id_cust in (1,2), что тривиально при необходимости строится прямо из приложения, если хочется сделать кнопки для движения подразделений вверх и вниз. Sgt.PepperЯ Вас так понял, что всем "неглавным" надо присвоить npp больший, чем у главного?.. одинаковый?.. разный?... Подумайте еще раз, что Вы написали, и какая цель приследуется при подобном update-е, и какая будет разница, будут ли новые значения npp разными или равными, какие будут последствия. По-моему, я достаточно описал, где и как используется npp, чтобы понять это. Sgt.PepperВ многабукав я не нашел объяснения КАК это должно делаться Вроде как топик не ставит задачей объяснить всем, как пишутся update-ы? Sgt.PepperЕсли npp=0 у главного и npp=1 у неглавного, то чем отличается npp от IS_MAIN?... Именно поэтому это и является расширением IS_MAIN, к которому сводится наложением дополнительных ограничений. Именно поэтому при допущении, что решение с IS_MAIN работает, будет работать и решение с npp. Какие у него плюсы и минусы, использовать ли его, и в каком случае - пусть решает автор. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 09:39 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChA На мой взгляд, более-менее вменяемый способ был упомянут ранее , но у него есть сильный недостаток. Для того чтобы обойтись только ограничениями, для таблицы "Работа" надо будет сделать обратный FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). К сожалению, формально для таблицы "Работа-ПЗ" уже должен быть FOREIGN KEY ON "Работа" (ID_JOB). Т.е., у нас образуется так называемая циклическая связь, что позволяют не все СУБД, да и просто может вызвать сложности с определением, типа, "что раньше - яйцо или курица". Лично я стараюсь избегать таких неоднозначностей в схеме. Если же обратной связи ("Работа-ПЗ"->"Работа") не делать, то возникает риск ввести в качестве главного подразделения то, которое вовсе не участвует в списке допустимых. Если же считать его допустимым, но дополнительным к списку в "Работа-ПЗ", то оно, во-первых, может оказаться дублирующим, во-вторых, для получения списка всех подразделений придется использовать упомянутый Вами UNION. Кроме того, процедура замены главного подразделения может оказаться не очень тривиальной, хотя при наличии транзакций это и не проблема, но по моему глубочайшему убеждению, нужно стремиться, чтобы изменение одного факта выполнялось за минимальной число модифицирующих операций(в идеале за одну). Так что при всей, казалось бы, простоте решения, на мой взгляд, этот вариант не очень привлекателен в реализации. В предложенным мною вариант корректность данных определяется стандартным механизмом ограничений. Надеюсь очевидно, что изменение главного подразделения тоже не вызывает каких-либо сложностей, простейший UPDATE. О каких циклических связях вы говорите? Считайте что это абсолютно разные связи: 1 - "Работа-ПЗ" 2 - "Работа-ПЗ"->"Работа" И нет ничего страшного что две таблицы ссылаются друг на друга. А какие СУБД не поодерживают этого? В Ыслучайно не путаете с иерархическими связями(когда сущность ссылается сама на себя) и соотвественно иерахическими запросами? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 10:55 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChAЕсли мы решаем задачу существования главного подразделения, а не ранжирования подразделений в общем виде, то правильнее, IMHO, сделать отдельную таблицу - "Работа-Главное ПЗ" с PRIMARY KEY(ID_JOB) и FOREIGN KEY ON "Работа-ПЗ" (ID_JOB, ID_Customer). В таблице "Работа-ПЗ" для этого нужен либо PRIMARY KEY(ID_JOB, ID_Customer), либо UNIQUE(ID_JOB, ID_Customer) и CHECK (ID_JOB IS NOT NULL AND ID_Customer IS NOT NULL). А как в этом случае реализовать обязательность связи Главное ПЗ? Зачем делать сложнее если можно сделать проще? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 10:56 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Все очень простоО каких циклических связях вы говорите?О тех, которые в англоязычных источниках обычно упоминаются как circular. Когда одна сущность ссылается на другую, а та, в свою очередь, ссылается обратно. Формально, это не запрещено, до тех пор пока для этих связей не определены каскадные операции, которые могут породить замкнутый бесконечный цикл в некоторых ситуациях, или наоборот, невозможность модификации, так как изменения в одной таблице будут блокироваться данными в другой таблице, что потребует от СУБД существования не самого простого механизма отложенной(deferrable) проверки ограничений ссылочной целостности. В некоторых источниках подобные связи считаются логическими ошибками проектирования, так как подобные циклы практически всегда могут быть исключены введением(или существованием) вполне корректных дополнительных сущностей. Такие связи не имеют никакого отношения к иерархическим связям, которые конечны по сути своей, так как "глубина" такой связи не может превысить количества элементов участвующих в иерархии. Все очень простоИ нет ничего страшного что две таблицы ссылаются друг на друга.Зависит от ситуации. Вполне может проявится неоднозначность вида "кто на ком стоял ?". IMHO, лучше избегать подобных ситаций, насколько это возможно, хотя готов допустить, что в некоторых случаях такой подход и может оказаться допустимым решением. Все очень простоА какие СУБД не поодерживают этого?Сейчас уже не вспомню, но как-то давно сталкивался, то ли в древних версиях MS SQL, то ли Informix. В MS SQL 2000, например, есть запрещение на включение каскадности одного типа в прямой и обратной связях одновременно. Хотя в рассматриваемом нами примере это вроде и не требуется, посему теоретически им вполне можно пренебречь. Все очень простоА как в этом случае реализовать обязательность связи Главное ПЗ? Зачем делать сложнее если можно сделать проще?Не заметил условия обязательности в постановке топикстартера. Насколько я понял задачу, есть список ПЗ, одно из которых может быть главным. Поэтому вполне логично отделить выбор ПЗ для новой работы от выбора главного из них. Впрочем, это мой поверхностный взгляд на поднятую задачу. Предложенный Вами вариант подразумевает при добавлении работы сразу указать для него подразделение заказчика. 1. Если выбирать его прямо из справочника "ПЗ", то Сергей Васкецов уже упомянул некоторые следствия. 2. Если выбирать его прямо из справочника "Работа-ПЗ", то: а). если поле в таблице "Работа" должно быть не NULL(обязательное значение), то ситуация еще хуже. Надо добавить запись в справочник "Работа-ПЗ", на которую будет ссылка из таблицы "Работа", но мы не можем этого сделать, так как у нас еще не добавлена соотвествующая запись в справочник "Работа". В наличии имеем пат, который придется хитромудро разрешать. Это как раз и есть яркая иллюстрация чреватости циклических связей. б). если поле в таблице "Работа" может быть NULL(необязательное значение), то мы уже не имеем решения задачи "обязательность связи Главное ПЗ". Так как все равно придется делать 3 действия: - добавление записи в справочник "Работа" - потом в справочник "Работа-ПЗ" - и только уж потом установку правильного значения в поле "ГлавПЗ" в соответствующую запись таблицы "Работа". Как уже говорилось, при наличии транзакций это вполне допустимо. Все модифицирующие операции практически те же самые, что и в предлагаемом мною варианте с отдельной таблицей. Различие в наших подходах заключается в том, что Вы пытаетесь замаскировать многоходовку, хотя на уровне пользователя в интерфейсе это все равно будут отдельные логические операции - выбор или добавление нового подразделения заказчика в список "Работа-ПЗ", и только потом уже выбор его в качестве главного. Тогда как мой же вариант соотвествует этим операциям можно сказать явно, один в один. Как мне кажется, можно было бы сказать, что наши варианты различаются смысловой нагрузкой: - ваш - "Для данной работы имеется главное ПЗ" - мой - "одно из ПЗ считается главным для данной работы". Топикстартер волен выбрать любой из этих вариантов, который он посчитает предпочтительным в контексте решения собственной задачи. Но он должен отдавать себе отчет, что в вашем решении по варианту 2б обязательность точно также не будет контролироваться ограничениями, как и в моем варианте. Не буду скрывать, что мой вариант мне нравится больше, хотя бы потому, что лично я настороженно отношусь к NULLABLE-полям в таблице, тем более, что на самом деле они такими по сути не являются, а их значения контролируются неким кодом произвольной сложности. Впрочем, я не призываю следовать тем же курсом и не настаиваю на том, что мой вариант является безусловно и единственно правильным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 15:15 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChAНе буду скрывать, что мой вариант мне нравится больше, хотя бы потому, что лично я настороженно отношусь к NULLABLE-полям в таблице, тем более, что на самом деле они такими по сути не являются, а их значения контролируются неким кодом произвольной сложности Еще немаловажен факт, что при отсутствии циклических связей FK могут быть созданы одновременно с созданием таблиц, а не отдельным ALTER-ом потом, даже если СУБД их поддерживает с ограничениями. То есть, нет необходимости дополнительно задумываться над порядком генерации сущностей в скрипте создания БД в случае использования, например, PowerDesigner-а. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 15:23 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChA Топикстартер волен выбрать любой из этих вариантов, который он посчитает предпочтительным в контексте решения собственной задачи. Но он должен отдавать себе отчет, что в вашем решении по варианту 2б обязательность точно также не будет контролироваться ограничениями, как и в моем варианте. А обязательность в моем случае легко реализуется путем создание ограничения CHECK и указанеим того что это ограниение отложеное (deferable). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:12 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Сергей Васкецов ChAНе буду скрывать, что мой вариант мне нравится больше, хотя бы потому, что лично я настороженно отношусь к NULLABLE-полям в таблице, тем более, что на самом деле они такими по сути не являются, а их значения контролируются неким кодом произвольной сложности Еще немаловажен факт, что при отсутствии циклических связей FK могут быть созданы одновременно с созданием таблиц, а не отдельным ALTER-ом потом, даже если СУБД их поддерживает с ограничениями. То есть, нет необходимости дополнительно задумываться над порядком генерации сущностей в скрипте создания БД в случае использования, например, PowerDesigner-а. Erwin с этим легко справляется. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:12 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Все очень простоErwin с этим легко справляется. Я как бы и не утверждал, что это нереальная проблема вынести создание FK из CREATE TABLE. Все очень простообязательность в моем случае легко реализуется путем создание ограничения CHECK и указанеим того что это ограниение отложеное ( deferable ) Если говорить о реализации CONSTRAINT-ов, лучше всегда приводить конкретный SQL с указанием, на каких СУБД он будет работать и как. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:43 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Сергей Васкецов Если говорить о реализации CONSTRAINT-ов, лучше всегда приводить конкретный SQL с указанием, на каких СУБД он будет работать и как. СУБД ORACLE ALTER TABLE table1 ADD CONSTRAINT CHK_table1_PZ_NN CHECK (PZ_ID IS NOT NULL) DEFERRABLE INITIALLY DEFERRED ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:55 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Все очень простоСУБД ORACLE Относительно прочих что-нибудь знаете столько же определенное? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:56 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
Все очень простоА обязательность в моем случае легко реализуется путем создание ограничения CHECK и указанеим того что это ограниение отложеное (deferable).Т.е., отложенная проверка ограничения типа NOT NULL ? К моему искреннему сожалению, в MS SQL 2000(топикстартер), 2005, и даже пререлизе 2008 такая возможность отсутствует. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 17:58 |
|
||
|
Несколько связей между двумя таблицами
|
|||
|---|---|---|---|
|
#18+
ChA Т.е., отложенная проверка ограничения типа NOT NULL ? К моему искреннему сожалению, в MS SQL 2000(топикстартер), 2005, и даже пререлизе 2008 такая возможность отсутствует. Мои соболезнования :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.08.2008, 18:05 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=35467116&tid=1543731]: |
0ms |
get settings: |
10ms |
get forum list: |
16ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
184ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
59ms |
get tp. blocked users: |
1ms |
| others: | 235ms |
| total: | 523ms |

| 0 / 0 |
