|
|
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
В базе данных есть таблица "pages", в которой хранится информация о некоторых страницах (можно называть их документами, но это не важно). У каждой страницы есть id, название, ещё много всякой ерунды и поле "тип страницы". Типы страниц хранятся в таблице "page_types": id, название типа и прочее. Теперь появилась необходимость прикреплять к страницам файлы, причем файлы могут группироваться. Все возможные группы определяются исключительно типом страницы. Напр., для страницы типа "Описание материала" можно добавлять файлы в группы "Техническая документация" и "Сертификаты". Получается следующая ситуация. Добавляем таблицу, где будут хранится файлы (имя, размер и прочее). Теперь добавляем еще одну таблицу, где будут хранится группы файлов: (id группы, id типа страницы, название группы). Теперь при добавлении страницы какого-то типа можно сразу вывести названия групп, в которые можно добавить файлы. Но что делать с таблицей самих файлов? Получается, что там нужны как id страницы, так и id группы, в которой этот файл на этой странице находится. Тогда никто не запрещает добавить запись с такими значениями этих полей, при которых эти id соответствуют разным типам страниц (группа 1->тип страницы 1 + страница 8->тип страницы 2). В чём тут фокус? Вроде пытался рассуждать логически, а получилась какая-то, простите, хрень :D ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 19:44 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
andy.sПолучается, что там нужны как id страницы, так и id группы, в которой этот файл на этой странице находится. Зачем там id страницы? Может существовать файл, привязанный к странице, но без группы? Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 19:52 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovЗачем там id страницы? Может существовать файл, привязанный к странице, но без группы? А как иначе? Если оставить только id группы, то как узнать, к какой странице привязан файл? Группы не содержат никакой информации о конкретных страницах, там лишь указывается тип страницы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 20:23 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
andy.sГруппы не содержат никакой информации о конкретных страницах, там лишь указывается тип страницы. Ну тогда либо контролируй, что файл привязан к правильной странице/группе триггерами, либо заведи отдельный список групп, привязанных к странице. Или ещё что-нибудь. Это зависит от того, какие выборки потребуется делать. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 20:27 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
andy.s, продолжайте использовать корректное сокращения - значительно упрощает общение :) С вашей подачи уже имеем pages, page_types andy.sДобавляем таблицу, где будут хранится файлы (имя, размер и прочее). files andy.s Теперь добавляем еще одну таблицу, где будут хранится группы файлов: (id группы, id типа страницы, название группы). Не "группы файлов", а "виды групп файлов на конкретных типах страниц": file_group_types (_for_page_types - но это уж слишком длинно). Ещё раз, file_group_types - потому что это не группы конкретных файлов, а именно названия (типы, виды) для групп файлов в зависимости от типа страницы. andy.sНо что делать с таблицей самих файлов? Получается, что там нужны как id страницы, так и id группы, в которой этот файл на этой странице находится. Тогда никто не запрещает добавить запись с такими значениями этих полей, при которых эти id соответствуют разным типам страниц (группа 1->тип страницы 1 + страница 8->тип страницы 2). В чём тут фокус? Вроде пытался рассуждать логически, а получилась какая-то, простите, хрень :D а хрень тут в том, что у вас в таблицах "file_groups" и "pages" по привычке суррогатные первичные ключи из одного идентификатора. А атрибут "ид типа страницы - page_types.id..." мог бы являться частью первичного ключа для этих таблиц "file_groups" и "pages". И тогда при проектировании таблички files вы бы завели просто два внешних ключа на: pages (id_page, id_page_type) file_group_types(id_fgtype, id_page_type) и у вас бы образовалось в files три атрибута: id_page, id_fgtype, id_page_type. То что id_page_type - это одно и то же поле, и гарантировало бы вам отсутствие херни в виде возможности "добавить запись с такими значениями этих полей, при которых эти id соответствуют разным типам страниц"... Т.е. чтобы у вас в таблице files не возникло ошибки, напрямую связанной с типом страницы, нужно: внести этот атрибут "тип страницы" в таблицу и внешними ключами обеспечить контроль заполнения этого поля. Ещё варианты: 1. НЕ обязательно заводить сложные первичные ключи, можно завести дополнительные альтернаивные ключи, оставив суррогатные. 2. Не заводить атрибут и обеспечить целостность триггерами, которые лазят в pages и file_group_types и сверяют совпадение в них id_page_type. 3. andy.sТеперь при добавлении страницы какого-то типа можно сразу вывести названия групп, в которые можно добавить файлы. Можно "вывести", а можно завести таблицу "file_group_types_on_page" (ид страницы, ид типа группы файлов) - группы файлов на конкретной странице. Поскольку формируете автоматически - сами решайте, хотите ли контролировать со стороны БД корректность этого добавления. Если хотите, то история та же, что и вашего первого варианта... теперь при добавлении файлов вы их связываете с конкретной записью file_group_types_on_page. П.С.: Рисуйте схему при проектировании - помогает разобраться даже в трёх соснах... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 20:46 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
АнатоЛой, Спасибо за развернутый ответ. Вариант со сложным первичным ключом в таблице групп мне нравится. Он может быть таким: (name, page_type_id). name - это строка только из английских букв, максимум 50 символов. Это поле не выдумано, оно действительно потребуется в дальнейшем. Смущает только то, что для каждой записи в таблице files придется таскать за собой это поле name. Места не жалко, но и целостность в принципе не критична, так что можно оставить и начальный вариант, а проверки делать вручную. Пойду брошу монетку :)) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 21:22 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
andy.s, вы не всё поняли. пусть остаётся суррогатное поле (id_gt_type). Оно кстати может и не быть суррогатным, а трансформироватья в поле "number_for_sort" Варианты: 1) или сделайте первичным ключом (id_gt_type, id_page_type) - при этом будет ли id_gt_type уникальным в пределах id_page_type, или уникальным по всей таблице - ваше дело... 2) или оставьте первичным ключом (id_gt_type) и сделайте альтренативный ключ (id_gt_type, id_page_type). Ключ (первичный или альтернативный) нужен только для того, чтоб на него можно было сослаться внешним ключом из files.... ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 21:30 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
АнатоЛой, Я понял, просто заметил, что в качестве id_gt_type можно использовать и поле name, которое обязательно должно быть уникальным в пределах id_page_type, т.е. таблица групп может содержать примерно такие строки: ("certificates", 1, "Сертификаты") ("documents", 1, "Документы") и большего вроде как не надо. В противном случае еще придется делать уникальный индекс на id_page_type+name, если я уж захотел контролировать всё средствами субд :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.12.2011, 22:02 |
|
||
|
Два внешних ключа, противоречащих друг другу
|
|||
|---|---|---|---|
|
#18+
andy.sТогда никто не запрещает добавить запись с такими значениями этих полей, при которых эти id соответствуют разным типам страниц Отчего же, мешает. Если я правильно понял, то: Код: plsql 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.12.2011, 03:47 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=37578575&tid=1541889]: |
0ms |
get settings: |
11ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
494ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
48ms |
get tp. blocked users: |
1ms |
| others: | 247ms |
| total: | 833ms |

| 0 / 0 |
