|
|
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Добрый день! Есть, допустим, сущность "Человек". "Человек" может быть либо "Врачом", либо "Пациентом" ( одновременно и тем, и тем, быть не может ). В голову приходит две реализации: 1) Из таблиц "Врач" и "Пациент" ссылаться на "Человека". 2) В таблице "Человек" добавить ссылки и на "Врача", и на "Пациента". Первый вариант выглядит вроде бы предпочтительнее, хотя бы потому что второй нарушает 2 нормальную форму. НО! В первом варианте гораздо сложнее отследить что бы на "Человека" не было две ссылки из обеих связанных таблиц (и можно ли вообще сделать это стандартными sql средствами, не используя триггеры?). Вообще, проблемма совершенно стандартная и регулярно появляеться, поэтому должно же быть какое то "правильное" стандартно решение? Или, хотябы, на ваш взгляд, какой из двух вариантов лучше? Для лучшего понимания прикладываю картинку, иллюстрирующую оба варианта. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 17:55 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Jelis одновременно и тем, и тем, быть не можетСурово однако. Заболел, значит не достоин звания врача. Другое дело что в документе типа рецепт можно запретить чтобы врач = пациент ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 18:21 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257Jelis одновременно и тем, и тем, быть не можетСурово однако. Заболел, значит не достоин звания врача. Другое дело что в документе типа рецепт можно запретить чтобы врач = пациент Врачи в своих больницах не лечаться :-) Ну, это пример о сферическом коне, но суть проблеммы передаёт полностью. На самом деле область у меня соовсем другая. Можно в примере заменить "человека" на "транспорт", а "врача" и "пациента" на "грузовой" и "легковой". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 19:20 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Выцарапать общие признаки из сущностей легковая и грузовая машины в отдельный предок - транспорт идея конечно красивая, объектная, но я предпочитаю строить базы ориентируясь на непротиворечивость и удобство хранения/обработки данных ибо программы приходят и уходят а данные остаются. Иными словами а задлянафига вам это надо? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 20:02 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257Выцарапать общие признаки из сущностей легковая и грузовая машины в отдельный предок - транспорт идея конечно красивая, объектная, но я предпочитаю строить базы ориентируясь на непротиворечивость и удобство хранения/обработки данных ибо программы приходят и уходят а данные остаются. Иными словами а задлянафига вам это надо? Ну, если в другой таблице нам надо ссылаться просто на "транспорт", и совершенно всёравно, "легковой" он или "грузовой". Например, есть "рейс", к которому привязан "транспорт" (любой) и "водитель". А вот сервисы есть раздельные, "сервис_для_грузового_транспорта" и "сервис_для_легкового_транспорта". И "страховки" совершенно разные, для разных транспортов. А даты смены колёс надо отслеживать только для "грузового" транспорта. А "техосмотры" проходят просто для всего "траспорта". Ну и ко всему этому "транспортов" может быть не два вида, а побольше. И, имхо, объектного тут нет ни капли! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 20:33 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Судя по всему Легковые и грузовые это отдельные сущности с некоторыми одинаковыми полями. То есть таблица Транспорт плавно превращается во вьюху с объединением (union all) общих полей из таблиц Легковые и Грузовые. Теперь про таблицу Рейс. Туда я бы засунул два поля (с разрешенными пустыми значениями) со ссылками на таблицы Легковые и Грузовые и ограничением типа только одно из них должно быть заполнено. Если добавляется еще одна таблица например Автобусы то добавляем еще одно поле и модифицируем ограничение. Jelis И, имхо, объектного тут нет ни капли! Скажем так - подобные подходы к проектированию я видел у поклонников OOП. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 21:09 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Ага... Per aspera ad astra... Слегка удлиннёным путём, но вы высказались за второй вариант на картинке. Спасиба :-) В таком варианте ("две ссылки на разные таблицы, только одна заполнена") весьма легко повесить check на таблицу для контроля условия. Но вот что меня смущает: это сходу нарушение 3 нормальной формы, так как получаеться что два этих поля зависят друг от друга, а не только от первичного ключа :-( А это есть грех, который хочеться по возможности всё таки не совершать :-) А на счёт вьюшки "Транспорт"... Если у вас "легковые" и "грузовые" две полностью разделённые сущности с дублирующимися полями, как вы будете отслеживать, например, уникальность гос номеров? Они же должны быть полностью уникальными - не может у нас быть "легкового" и "грузового" с одинаковым номером! SERG1257 Скажем так - подобные подходы к проектированию я видел у поклонников OOП. Не переживайте - я до мозга костей поклонник РСУБД... Хотя на яве пишу много - может и начало уже её виляние сказываться :-) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 21:44 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Jelis Они же должны быть полностью уникальными - не может у нас быть "легкового" и "грузового" с одинаковым номером!В таком случае действительно имеет смысл ввести сущность Транспорт с общими полями плюс два nullable поля Свойства легкового автомобиля и Свойства грузового автомобиля плюс ограничение. То бишь перенести эту связь из таблицы Рейс в таблицу транспорт. Jelis Ага... Per aspera ad astra... Слегка удлиннёным путём, но вы высказались за второй вариант на картинке. Спасиба :-)А вы поболее про задачу расскажите (типа популярные/критичные запросы) и я выскажусь и за первый или вообще за третий ненарисованный вариант. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 02.12.2009, 22:10 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257В таком случае действительно имеет смысл ввести сущность Транспорт с общими полями плюс два nullable поля Свойства легкового автомобиля и Свойства грузового автомобиля плюс ограничение. То бишь перенести эту связь из таблицы Рейс в таблицу транспорт.А завтра появится речной вид транспорта, а потом воздушный. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 09:44 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Senya_LSERG1257В таком случае действительно имеет смысл ввести сущность Транспорт с общими полями плюс два nullable поля Свойства легкового автомобиля и Свойства грузового автомобиля плюс ограничение. То бишь перенести эту связь из таблицы Рейс в таблицу транспорт.А завтра появится речной вид транспорта, а потом воздушный. Т.е. вы выступает за схему по первому варианту (на картинке)? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 11:25 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257А вы поболее про задачу расскажите (типа популярные/критичные запросы) и я выскажусь и за первый или вообще за третий ненарисованный вариант. В том-то и дело, что меня интересует не конктретный случай, а абстрагированое теоретическое "правильное" решенеий подобной ситуации, этакий best practice. При проектировании подобная схема у меня появляеться регулярно, наверно раза 3 на каждые 100 таблиц. И каждый раз приходиться в муках решать, как же лучше сделать :-) Если вы скажете что я много хочу, и что надо смотреть на каждый конкретный случай, могу привести пример с отношением многие-ко-многим: тут без вопросов решаеться путём введения допонительной таблицы, и особо раздумывать не надо! ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 11:35 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
JelisВ первом варианте гораздо сложнее отследить что бы на "Человека" не было две ссылки из обеих связанных таблиц (и можно ли вообще сделать это стандартными sql средствами, не используя триггеры?).Бизнес логика не обязательно должна выполняться только средствами "чистого" sql. Закройте модификацию этих таблиц хранимыми процедурами и в них контролируйте целостность. И вторая отправная точка для размышлений - как вы будете определять что конкретный транспорт "грузовой" или "легковой"? Если if exists(select * from "грузовой") then "грузовой" else "легковой"... А если по другому? Например, в таблицу "траспорт" добавить поле "тип транспорта". ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 13:55 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Я за первый вариант, как раз НЕЧТО такое реализую, но у меня в дочерней таблице ParentID=ID, то есть первичный ключ дочерней таблицы является одновременно внешним к родительской. Кроме того для каждой дочерней таблицы постороена VIEW по типу: Код: plaintext 1. 2. С уважением, Naf ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 17:00 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Использую чаще всего первый вариант. Из соображений гибкости и "похожести" на ООП. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 17:51 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Jelis И каждый раз приходиться в муках решать, как же лучше сделать :-) Такова твоя планида. Плюс добавь что схема редко пишется/переписывается с нуля, всегда есть какая-то реализованная часть, плюс решение должно быть максимально простым и понятным, плюс решение должно быть "удобным" для СУБД (чтобы обеспечить приемлимую производительность), плюс просчитать что будет (что придется поменять) если условия игры изменятся. Так что однозначное идеальное решение в общем случае не найти. Senya_LА завтра появится речной вид транспорта, а потом воздушный.Неизбежно добавится новая таблица, то бишь будет патч на СУБД в котором можно добавить колонки, изменить ограничения и т.д. Серж Например, в таблицу "траспорт" добавить поле "тип транспорта". А это уже денормализация. И надо будет учитывать недостатки данного решения. Jelis могу привести пример с отношением многие-ко-многим: тут без вопросов решаеться путём введения допонительной таблицы, и особо раздумывать не надо!Задавшись целью, можно будет скроить начальные условия при которых "многие-ко-многим" оптимально будет решать без дополнительной таблицы. IMHO цель форума - для каждого решения найти достоинства и недостатки, которые дизайнер должен взвесить и принять вольюнтаристкое решение (мы посовещались и я решил) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 17:58 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257Задавшись целью, можно будет скроить начальные условия при которых "многие-ко-многим" оптимально будет решать без дополнительной таблицы.это как? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 18:21 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
egorych это как? Через ж..у ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 18:37 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Серж И вторая отправная точка для размышлений - как вы будете определять что конкретный транспорт "грузовой" или "легковой"? Если if exists(select * from "грузовой") then "грузовой" else "легковой"... А если по другому? Например, в таблицу "траспорт" добавить поле "тип транспорта". Ну да, с определением типа в такой схеме есть сложность. Я обычно с начала в запросах где надо занть тип делаю что то такое : Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. А потом, когда либо выяснение типа расплываеться по многим местам или приходиться уже обращать внимание на производительность, делаю таки поле тип_транспорта в таблице Транспорт и заполняю его из триггеров. Вообщем, определение типа можно смело записывать в недостатки первого варианта, во втором чуть по проще. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 18:58 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
NafЯ за первый вариант, как раз НЕЧТО такое реализую, но у меня в дочерней таблице ParentID=ID, то есть первичный ключ дочерней таблицы является одновременно внешним к родительской. Да, иногда получаеться сделать сквозные идишники, иногда нет. Кстати, может кто-нибудь расскажет о подводных камнях со сквозными идишниками в первой схеме? Что-то я даже впомнить не могу ни каких грабель на эту тему. Naf Кроме того для каждой дочерней таблицы постороена VIEW по типу: Код: plaintext 1. 2. С уважением, Naf Триггеры вешаються прямо на вьюху? А что за СУБД, можно узнать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 19:08 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 03.12.2009, 20:20 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
SERG1257А это уже денормализация. И надо будет учитывать недостатки данного решения.Денормализировать, как правило, все равно приходится. Если применять ее осмысленно, то ничего страшного в этом нет. JelisВообщем, определение типа можно смело записывать в недостатки первого варианта, во втором чуть по проще.Да тот же самый case when легковой_Id is not null then 'легковой'... Jelis Код: plaintext 1. 2. А где на практике такой запрос применяется? Т.е. какой смысл одновременно вязать две таблицы с совершенно разными данными, одна из которых гарантированна будет пустой. Jelis Кстати, может кто-нибудь расскажет о подводных камнях со сквозными идишниками в первой схеме? ...Что-то упустил сразу этот момент... Я считаю что ИД транспорта это ФК в таблицах легковой, грузовой и одновременно ПК. Т.е. значение ИД одно. Это понимается под сквозными ИД? Я делал именно так и никаких подводных камней не нашел. А в случае с гуидами, вообще все ИД по базе сквозные. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2009, 05:27 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
JelisТриггеры вешаються прямо на вьюху? А что за СУБД, можно узнать? Firebird, MS SQL Server ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2009, 09:19 |
|
||
|
Поддержка уникальности в таблицах, расширяющих родительскую.
|
|||
|---|---|---|---|
|
#18+
Забыл уточнить, у родительской таблицы еще есть поле - идентификатор вида конечной дочерней таблицы - число мнемоническое, у меня. Чтобы по записи в родительской можно было понять кокретный "тип" записи не устраивая соединений с дочерними С уважением, Naf ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 04.12.2009, 09:21 |
|
||
|
|

start [/forum/topic.php?fid=32&fpage=80&tid=1542950]: |
0ms |
get settings: |
10ms |
get forum list: |
17ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
65ms |
get topic data: |
12ms |
get forum data: |
3ms |
get page messages: |
75ms |
get tp. blocked users: |
2ms |
| others: | 245ms |
| total: | 437ms |

| 0 / 0 |
