|
|
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
Здравствуйте. Подскажите, как правильно спроектировать БД. Есть таблица STONES, упрощенно, - ( id int PK, name varchar, status int). В таблице хранятся данные по камнях. Поле status определяет является ли камень отдельным видом или разновидностью другого камня. Один камень (вид) может иметь несколько разновидностей. Если камень - разновидность, природа распорядилась так, что он может относиться к нескольким видам. Вопрос такой - как технически организовать (или реорганизовать) эту таблицу, чтоб обеспечить целостность. Добавить еще одно поле и сделать его FK на id нельзя, не позволяют условия. Я склоняюсь к варианту: - Сделать еще одну таблицу вроде - MTF ( stone_id int, form_id int), видимо придется полюбому, но как быть в таком случае с уникальностью записей в ней? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2012, 19:17 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
Таблица Камней (Камень) Таблица КаменьЯвляетсяРазновидностью (Камень, РазновидностьюКакогоКамняЯвляется) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2012, 20:22 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщ Подскажите, как правильно спроектировать БД.Сразу скажу что правильно проектируется БД только для определенного задания. То есть КАМАЗ совершенно правильно спроектирован для перевозки грузов, но совершенно неправильно для поездок на работу и с работы. сфьщ В таблице хранятся данные по камнях.Наверное все-таки не по камням (реальным объектам с массой и размерами) а по классификатору камней. авторОдин камень (вид) может иметь несколько разновидностей. Если камень - разновидность, природа распорядилась так, что он может относиться к нескольким видам.То бишь в одной таблице вы храните общего предка вместе с потомками. например Каменюка Каменюка обыкновенная Каменюка необыкновенная Каменюка красивая сфьщ Вопрос такой - как технически организовать (или реорганизовать) эту таблицу, чтоб обеспечить целостность.Целостность чего вы обеспечиваете? Поясню - в какой момент база должна выдать ошибку чтобы не дать вставить/поменять/удалить данные. То бишь в случае с примером выше мы не можем удалить запись Каменюка если от нее есть потомки. авторДобавить еще одно поле и сделать его FK на id нельзя, не позволяют условия.Почему? Это как раз классическое решение - хотя и не единственное. Убрать поле status, заменить его на parent_id и если оно null - значит это разновидность, а не отдельный вид. сфьщ Я склоняюсь к варианту: - Сделать еще одну таблицу вроде - MTF (stone_id int,form_id int)Опять же чего вы хотите добится. Сколько уровней в вашей иерархии? Каменюка Каменюка обыкновенная Каменюка обыкновенная с дырочкой Есть ли предел (офицально утвержденный) для максимума иерархий? Можете почитать про Деревья в SQL ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2012, 20:29 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
SERG1257То бишь в одной таблице вы храните общего предка вместе с потомками. например Каменюка Каменюка обыкновенная Каменюка необыкновенная Каменюка красивая Да, пока так и есть. SERG1257Почему? Это как раз классическое решение - хотя и не единственное. Убрать поле status, заменить его на parent_id и если оно null - значит это разновидность, а не отдельный вид. Потому, что несколько , как вы пишете, "предков" может быть для одного "потомка". например Каменюка обыкновенная Булыжник могут быть предками для Каменюка рудная Явно нужно еще таблицу одну, как я писал. SERG1257 То бишь в случае с примером выше мы не можем удалить запись Каменюка если от нее есть потомки. Если б существовал какой-нибудь идиоматический вариант, когда при удалении записи "Каменюка", все связанные с ней записи в таблице MTF удалялись, или при удалении записи "Каменюка рудная" все связанные с ней записи в MTF тоже удалялись, и при всем при этом записи в MTF были уникальны (как если бы был составной PK из stone_id,form_id) - я б был рад. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2012, 23:00 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщ Потому, что несколько , как вы пишете, "предков" может быть для одного "потомка".То бишь у вас нифига не дерево, а совсем даже граф. Тогда ваше решение stones - узлы графа MTF - дуги графа Код: sql 1. имеет место быть. сфьщ Если б существовал какой-нибудь идиоматический вариант, когда при удалении записи "Каменюка", все связанные с ней записи в таблице MTF удалялись, или при удалении записи "Каменюка рудная" все связанные с ней записи в MTF тоже удалялись Если вы пропишите on delete cascade на ограничение, то при удалении узла все ссылки на него и/или от него автоматически удалятся. Если логика не столь однозначна - пишите триггеры. сфьщ и при всем при этом записи в MTF были уникальны (как если бы был составной PK из stone_id,form_id) - я б был рад. И что вам мешает объявить такой первичный ключ? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 01.02.2012, 23:37 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
SERG1257То бишь у вас нифига не дерево, а совсем даже граф. Тогда ваше решение stones - узлы графа MTF - дуги графа Код: sql 1. имеет место быть. Проблема в том,что тогда нельзя прописать каскадное удаление для двух FK, только на один какой-нибудь, так как они привязаны будут оба к [STONES].[id]. Вот, собственно, я и не знаю, как спроектировать все так, чтоб можно было обеспечить каскадное удаление/обновление по двум FK? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 00:36 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщВот, собственно, я и не знаю, как спроектировать все так, чтоб можно было обеспечить каскадное удаление/обновление по двум FK? Вручную на клиенте или в удаляющей хранимке. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 00:51 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
SERG1257Вручную на клиенте или в удаляющей хранимке. На клиенте хардкодить - не интересно. Хранимая процедура конечно вариант, но мне интуитивно кажется, что есть какой-то стандартный подход проектирования для решения такой проблемы. Я же, в конце концов, не первый человек с подобной проблемой... просто с гугл тупит че-то :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 01:26 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщSERG1257То бишь у вас нифига не дерево, а совсем даже граф. Тогда ваше решение stones - узлы графа MTF - дуги графа Код: sql 1. имеет место быть. Проблема в том,что тогда нельзя прописать каскадное удаление для двух FK, только на один какой-нибудь, так как они привязаны будут оба к [STONES].[id]. Вот, собственно, я и не знаю, как спроектировать все так, чтоб можно было обеспечить каскадное удаление/обновление по двум FK? Что ж вы сразу про проблему-то не сказали? Вас же небось, ещё и интересуют решения для конкретной СУБД? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 01:41 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
АнатоЛойЧто ж вы сразу про проблему-то не сказали? Вас же небось, ещё и интересуют решения для конкретной СУБД? Каюсь, не сформулировал правильно проблему в первом посте, но тут, как вы видите, конкретно дошло дело до еще одной таблицы в процессе обсуждения, и соотв. проблема с FK, тоже возникла в процессе. Конкретная СУБД - MS SQL 2008 R2, но я тему создал в этой ветке, ибо тут, как мне показалось, просто нужно правильно спроектировать. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 01:57 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщ, проверь вариант: MTF (stone_id int, depended_stone_id int, type_dependencies bool)... оба id по FK на stone. по stone_id - каскадный... первичный ключ на оба id... если stone "1" является предком для "2" , делать две записи в MTF 1, 2, true 2, 1, false в одной транзакции с клиента удалять все записи из MTF - иначе error... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 02:10 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
АнатоЛойсфьщ, проверь вариант: MTF (stone_id int, depended_stone_id int, type_dependencies bool)... оба id по FK на stone. по stone_id - каскадный... первичный ключ на оба id... если stone "1" является предком для "2" , делать две записи в MTF 1, 2, true 2, 1, false в одной транзакции с клиента удалять все записи из MTF - иначе error... Нет, MS SQL, как оказалось, не разрешает использование каскадного обновления/удаления даже для одного FK для "самосвязи" много-ко-многиим (как написано - чтоб предотвратить возможность цикличного удаления/обновления). Видимо, вариант с самоуправлением таблицей зависимостей - единственно возможный :( ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 17:37 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщ, Хм, в Access все работает. Интересно, что будет если МигрейшнАссистентом на MS SQL попытаться перевести... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.02.2012, 18:20 |
|
||
|
проблема ссылочной целостности
|
|||
|---|---|---|---|
|
#18+
сфьщХм, в Access все работает. Интересно, что будет если МигрейшнАссистентом на MS SQL попытаться перевести... Ничего не получится, выдаст такое же сообщение об ошибке, как при попытке создать каскадный FK в MS SQL. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.02.2012, 15:12 |
|
||
|
|

start [/forum/topic.php?fid=32&fpage=53&tid=1541842]: |
0ms |
get settings: |
6ms |
get forum list: |
10ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
61ms |
get topic data: |
9ms |
get forum data: |
3ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 276ms |
| total: | 423ms |

| 0 / 0 |
