powered by simpleCommunicator - 2.0.60     © 2026 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Внешний ключ на две таблицы (+)
44 сообщений из 44, показаны все 2 страниц
Внешний ключ на две таблицы (+)
    #33338588
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Всем здравствуйте.
Точно знаю, что подобная тема здесь уже была, встречал, но вот найти никак не могу :(
Есть таблица, в ней необходимо сделать внешний ключ, который может ссылаться на одну из двух таблиц, как это лучше реализовать:
1. Сделать PK в каждой из двух таблиц сквозной, т.е. поле IDENTITY с непересекающимися значениями. Соответственно, берем значение внешнего ключа в связанной таблице и ищем поочередно в каждой из двух родительских таблиц.
2. Сделать в связанной таблице два поля - внешние ключи на каждую из таблиц. Одно из полей всегда NULL. Проверяем, какое из полей не NULL и обращаемся к соответствующей родительской таблице.
Расширения не будет, т.е. родительских таблиц всего две.
Подскажите, пожалуйста, как лучше сделать? Можно ссылкой на подобную тему.
Спасибо!
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338606
YBW
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
YBW
Гость
KezyaВсем здравствуйте.
Точно знаю, что подобная тема здесь уже была, встречал, но вот найти никак не могу :(

эта тема обычно поднимается, когда речь заходит о физиках-юриках

можно искать по топикам Физические лица, Юридические лица
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338608
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Спасибо !
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338700
VladSh
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Есть таблица, в ней необходимо сделать внешний ключ, который может ссылаться на одну из двух таблиц, как это лучше реализовать:

Применительно к физическим-юридическим лицам и т.д.
лучший вариант - хранить данные не в двух разных таблицах, а в одной.
Например CUSTOMER.
При желании к этой таблице можно создать подчиненную, где хранить дополнительные атрибуты юридических лиц.

Все другие варианты - хуже.

--
Шумов В.
http://www.acdplus.ru/
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338808
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня не физ. и юр. лица :)
Сущности разные, схожих атрибутов у них нет. Сделал одно поле - внешний ключ и поле-признак, значение в котором и будет означать из какой сущности взят экземпляр.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338885
KezyaУ меня не физ. и юр. лица :)
Сущности разные, схожих атрибутов у них нет. Сделал одно поле - внешний ключ и поле-признак, значение в котором и будет означать из какой сущности взят экземпляр.


можно сделать одну общую "сквозную" "опорную" "единую" таблицу ключей (EntryID EntryDate etc.) для разных сущностей - по ним и определять откуда данные о сущности (таблиц таким образом может быть и не две... и не пять...)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338953
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Kezya
На мой взгляд, неправильно сделали. Если это абсолютно разные сущности, то лучше в главной таблице сделать два поля. Зачем экономить-то?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33338954
Фотография Cat2
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Модератор форума
Вот еще. С таким подходом Вы не напишите нм одного нормального запроса ни на одном диалекте SQL.
По всей видимости Вы еще не совсем освоились в реляционных БД и мыслите навигационным способом доступа к данным :)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339024
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В главной таблице у этих разных сущностей есть общее поле - количество.
Cat2
По всей видимости Вы еще не совсем освоились в реляционных БД

это верно :(
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339059
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
VladShПрименительно к физическим-юридическим лицам и т.д.
лучший вариант - хранить данные не в двух разных таблицах, а в одной.
Меня всегда умиляли слова "лучше так" при абсолютно неизвестной постановке задачи (то есть - как именно будет использоваться это "так").

VladShНапример CUSTOMER.
Если CUSTOMER - то действительно например. Но подброшу другой например, из моей практики: хранятся данные о самой фирме и ее филиалах (сотрудники и оргструктура), контрагентах (те самые customer), банках (которые само собой юрики и которые могут быть контрагентами) ключевых сотрудниках контрагентов-юриков и банков (грубо говоря, контакты), расчетных счетах, которые физик или юрик может иметь в банке.

Признаться, с огромным интересом изучил бы хорошую реализацию, в которой все это свалено в одну таблицу. Например, хранение данных о физике, который является контрагентом, одновременно является сотрудником банка-контагента и имеет счет в своем банке :)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339060
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KezyaСделал одно поле - внешний ключ и поле-признак, значение в котором и будет означать из какой сущности взят экземпляр.
Присоединюсь к предыдущим ораторам. Это решение во-первых наиболее неудобно в использовании, а во-вторых, наиболее ненадежно, чревато проблемами в сопровождении (разрешите не расшифровывать почему, если угодно - просто точка зрения).

Нормальные решения уже были названы - это либо "сквозная" таблица, объединяющая две сущности, либо то, что в Oracle Designer-е называется "дугой" - два поля, два foreign key и check constraint вида (a is null and b is not null or a is not null and b is null).
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339159
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Да, прошелся поиском по форуму, нашел кучу поднобных тем. Знал ведь, что они есть :)
Решение с битовым полем-"переключателем" действительно не очень удачное, сделал
Softwarer
...то, что в Oracle Designer-е называется "дугой" - два поля, два foreign key и check constraint вида (a is null and b is not null or a is not null and b is null).
Еще раз большое всем спасибо за советы!
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339175
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Хм, возникла интересная ситуация: сначала в таблице внешний ключ ссылался всего лишь на одну таблицу и этот внешний ключ являлся составной частью первичного ключа. Я не стал делать суррогатный ключ, а сделал составной. Первичный ключ для таблицы состоял из трех внешних ключей, теперь же добавляется четвертый, но так, что два внешних ключа являются "взаимоисключающими", т.е. один из них всегда(!) NULL. Возможно ли создание такого PK, состоящего из 4-х полей таблицы, причем одно из них всегда будет NULL?
Я конечно попробую все же создать, но насколько хорошо будет такое решение (если получится)?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339177
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Поле с возможностью NULL значения не может быть частью PK. Очень удобно ссылочная целостность реализовывалась, как в таком случае ее поддерживать - триггерами?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339231
Фотография ASCRUS
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KezyaПоле с возможностью NULL значения не может быть частью PK. Очень удобно ссылочная целостность реализовывалась, как в таком случае ее поддерживать - триггерами?
Лучше сделать PK все таки суррогатным ключом, а на поля сделать UNIQUE CONSTRAINT/INDEX (если конечно Оракл позволяет нормально делать UNIQUE на NULL-поля).
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339246
Фотография MasterZiv
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Надо в сущности , на которую нужно ссылаться, выделить общего предка, применив отношение подкатегории. И на него (общего предка) тогда и ссылаться.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339314
MasterZivНадо в сущности , на которую нужно ссылаться, выделить общего предка.

БОЯН
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339332
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
KezyaПервичный ключ для таблицы состоял из трех внешних ключей, теперь же добавляется четвертый,
"А зачем нам кузнец?" (c)

Почти всегда лучше обойтись без подобных первичных ключей. Для адресации нужной записи в таблице составной ключ из четырех полей, мягко говоря, неудобен. А если адресовать записи не требуется - зачем первичный ключ? Делайте просто уникальный по требуемому набору полей.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339334
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ASCRUS(если конечно Оракл позволяет нормально делать UNIQUE на NULL-поля).
Позволяет. Даже позволяет создать foreign key, ссылающийся на такой unique constraint.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33339370
Kezya
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
У меня не Oracle, а MS SQL Server. Сделаю, наверное, суррогатный ключ. "Опорную" таблицу делать имеет смысл если таблиц более 2-х, мне же хватит и одной :)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33340282
hardsign
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Если CUSTOMER - то действительно например. Но подброшу другой например, из моей практики: хранятся данные о самой фирме и ее филиалах (сотрудники и оргструктура), контрагентах (те самые customer), банках (которые само собой юрики и которые могут быть контрагентами) ключевых сотрудниках контрагентов-юриков и банков (грубо говоря, контакты), расчетных счетах, которые физик или юрик может иметь в банке.


Правильно, давайте всё в кучу. Делить клиентов на "контрагентов" и "неконтрагентов" -- дальновидное и технически грамотное решение :)

Если серьёзно -- "контрагенты", "расчётные счета" и т.п. это всё преходяще и должно описываться отдельными сущностями. Деление на "физиков" и "юриков" вечно и неизменно, и два поля, одно из которых не null, и битовый флаг -- решения равнозначные. Единственное неудобство -- во втором случае нельзя сделать FK, но я считаю FK злом :)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33340336
sgdsfgsfgsfgsfgsfg
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
hardsignДеление на "физиков" и "юриков" вечно и неизменно :)

а физиков на физиков с ИНН и без?
а физиков на резидентов и не резидентов


"вечных и неизменных" делений несть числа - это показывает практика

у кого-то она шире... у кого-то уже...
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33340445
hardsign
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
sgdsfgsfgsfgsfgsfgа физиков на физиков с ИНН и без?
а физиков на резидентов и не резидентов

"вечных и неизменных" делений несть числа - это показывает практика


Да ну? Физик без ИНН может получить ИНН. Физик-резидент может эмигрировать (или наоборот -- нерезидент может получить гражданство). Юрик физиком не станет никогда.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33340544
hardsign sgdsfgsfgsfgsfgsfgа физиков на физиков с ИНН и без?
а физиков на резидентов и не резидентов

"вечных и неизменных" делений несть числа - это показывает практика


Да ну? Физик без ИНН может получить ИНН. Физик-резидент может эмигрировать (или наоборот -- нерезидент может получить гражданство). Юрик физиком не станет никогда.

меньше боевого задора - я в вам про Кузьму вы мне про Ярему...

а вдруг станет? что будете делать - харакири?

по категории физики юрики субъектов хозяйственной деятельности различает законодатель ИМХО - а ну как он перестанет различать?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33340705
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
rtwertwertwertwertwertwertwet
а вдруг станет? что будете делать - харакири?
Да бог с ним. Возражение гораздо проще - у меня упомянута, например, таблица банков, которая ссылается на юриков (банк физиком быть не может). Еще там упомянуты сотрудники, которые вряд ли могут быть кем-то кроме физиков. Итого, если валить физиков с юриками в одну таблицу - начинаются пляски с целостностью. Правда, уже было задекларировано "зло", на что трудно возразить :)
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33341077
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
пообсуждаем?... )
Код: 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.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
create table customer (
	customer_id	int not null,
	customer_type char( 1 ) not null, check (customer_type in ('P','O')),
	-- Общие атрибуты клиентов
	-- ...
	constraint PK primary key (customer_id,customer_type)
)@


create table people (
	customer_id	int not null,
	customer_type char( 1 ) not null check (customer_type in ('P')),
	-- Дополнительные атрибуты физ лиц
	-- ...
	constraint FK foreign key (customer_id,customer_type)
		references customer (customer_id,customer_type)
			on delete restrict on update restrict,
	constraint PK primary key (customer_id,customer_type)
)@


create table organization (
	customer_id	int not null,
	customer_type char( 1 ) not null check (customer_type in ('O')),
	-- Дополнительные атрибуты юр лиц
	-- ...
	constraint FK foreign key (customer_id,customer_type)
		references customer (customer_id,customer_type)
			on delete restrict on update restrict,
	constraint PK primary key (customer_id,customer_type)
)@

-- Как пример:
create table Doc (
	-- Производитель
	org_id int,
	org_type char( 1 ),
	-- Потребитель
	fl_id int,
	fl_type char( 1 ),
	-- Прочие атрибуты
	-- ...
	constraint FK_PEOPLE foreign key (org_id,org_type) references people (customer_id, customer_type),
	constraint FK_ORG foreign key (fl_id,fl_type) references organization (customer_id, customer_type)
)@
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33341203
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanпообсуждаем?...
Как-то бессмысленно обсуждать, не имея постановки задачи. Флейм получится.

Из общих соображений - меня несколько смущает то, что people и organization обязаны быть customer-ами, ну и то, что я назвал "пляска с целостностью" - по понятным причинам аж в таблицу документов залезло техническое поле org_type. Наконец, в данной схеме чрезвычайно неудобен путь от "документа" к "общим атрибутам клиентов".

Итого - во-первых, я бы скорее протянул foreign key в обратную сторону (от customer к people/organization). Во-вторых, в doc ссылался бы на customer_id. В-третьих, убрал бы поле типа.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33341224
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор, в данной схеме чрезвычайно неудобен путь от "документа" к "общим атрибутам клиентов".
Как раз наоборот. Все очень-очень просто. За общими отрибутами не надо ходить в People или Org - можно напрямую приджойнить customer.
автор
Итого - во-первых, я бы скорее протянул foreign key в обратную сторону (от customer к people/organization). Во-вторых, в doc ссылался бы на customer_id. В-третьих, убрал бы поле типа.
Приведите пример пожалуйста. Для наглядности.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342116
hardsign
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
softwarer
Из общих соображений - меня несколько смущает то, что people и organization обязаны быть customer-ами,

Можно несколько переформулировать определение кастомера: это любой субъект, с которым приходится иметь дело. Тогда не жалко валить туда и физиков, и юриков. Контрагентом субъект становится в тот момент, когда с ним заключается соответствующий договор. Тогда, чтобы определить контрагента, надо идти от договора, а не от справочника клиентов. Вполне жизнеспособный подход.

softwarer ну и то, что я назвал "пляска с целостностью" - по понятным причинам аж в таблицу документов залезло техническое поле org_type.

Тоже жизнеспособный подход -- составной первичный ключ, часть которого является внешним ключом. Он тоже может кому-то не нравиться (как мне, например, не нравятся физические FK :)), но, тем не менее, это работает и в OLTP иногда очень удобно.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342390
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 gardenman

Структурно ключом все-таки должен быть customer_id
Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
create table customer (
	customer_id	int not null,
	customer_type char( 1 ) not null, check (customer_type in ('P','O')),
	-- Общие атрибуты клиентов
	-- ...
              
               constraint PK primary key (customer_id)
               constraint PK unique (customer_id,customer_type)
)@

create table people (
	customer_id	int not null,
	customer_type char( 1 ) not null check (customer_type in ('P')),
	-- Дополнительные атрибуты физ лиц
	-- ...
	constraint FK foreign key (customer_id,customer_type)
		references customer (customer_id,customer_type)
			on delete restrict on update restrict,
	constraint PK primary key (customer_id)
)@

А далее кому важно, чтобы тип не менялся, ссылаются на unique, а кому не важно - на primary key.

Во-вторых в косметических целях поменял бы название customer на party (действующее лицо). Клиент - это скорее роль. У одного действующего лица ролей может быть много.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342469
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
авторСтруктурно ключом все-таки должен быть customer_id

Сможете обосновать?
автор
customer на party

Я подумаю над этим. Однако привычка - знаете ли большое дело.

По мне так абсолютно никакой разницы первичный ключ составной или из одного поля. Для меня существенно другое - Если клиент существует, то для него обязательно должна быть запись в таблице Customer. И опять же Customer должен быть упомянут только один раз и должен иметь совершенно определенный тип.
Единственная проблема которую я тут вижу - можно удалить строку из People а в Customer она останется. Поэтому без триггеров такая схема до конца не работает.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342477
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hardsignМожно несколько переформулировать определение кастомера: это любой субъект, с которым приходится иметь дело.
"Субъект" - согласен, будет нормальная сущность. А вот кастомер - не нравится; захочется внести туда собственных сотрудников и выяснится, что приходится обозвать их кастомерами :)

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

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
  c.*
from 
  Document d,
  People p,
  Organization o,
  Customer c
where
  d.people_id = p.people_id (+) and
  d.organization_id = o.organization_id (+) and
  c.customer_id = coalesce ( p.customer_id, o.customer_id )

Получается так, что наиболее нужная информация засунута максимально далеко.

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

Как неформальный признак - imho такой подход оправдан, когда не нужно вносить дополнительных технических полей, то есть когда поля составного ключа по своему смыслу должны присутствовать в каждой из таблиц.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342498
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
автор"Субъект" - согласен, будет нормальная сущность. А вот кастомер - не нравится; захочется внести туда собственных сотрудников и выяснится, что приходится обозвать их кастомерами :)


А что, собственный сотрудник разве не может быть кастомером?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342511
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 softwarer
Таблицу Doc я привел в пример лишь для того, чтобы показать как можно накрутить ссылочную целостность на такую схему.
Например, если потебуется хранить организацию и ее сотрудников и обеспечить связь между ними.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342542
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenmanА что, собственный сотрудник разве не может быть кастомером?
Может. Но совершенно не обязан им быть. Поэтому внешние ключи, например, кастомер -> физик и сотрудник -> физик вполне удобны, а вот notnull-овский физик -> кастомер - искусственен, не отражает реальности.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342563
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
gardenman авторСтруктурно ключом все-таки должен быть customer_id

Сможете обосновать?

Общеэстетические соображения:
Party_idParty_type1'O'1'P'
вызывает вопрос так '1' у нас человек или организация? Ответ ясен O1 это одно а P1- другое, но все же....
во-вторых включение смыслового атрибута в суррогатный ключ в общем случае не лучшая практика.

Производительность, кодирование: короткие ключи безусловно лучше.
А главное, цель (контроль целостности Party - Organization xor Person) достигается и при коротком ключе, зачем усложнять.

Наконец, если имеется существующая база, то одно дело добавить UNIQUE, другое реорганизовать PK.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342586
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelRНаконец, если имеется существующая база, то одно дело добавить UNIQUE, другое реорганизовать PK.
Хм. Возможно тупой вопрос, но - а в чем разница?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33342633
gardenman
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
2 ModelR
взвесил, что вы написали. действительно:

Код: 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.
32.
33.
create table customer (
	customer_id	int not null,
	customer_type char( 1 ) not null, check (customer_type in ('P','O')),
	-- Общие атрибуты клиентов
	-- ...
              
               constraint PK primary key (customer_id),
               constraint PK2 unique (customer_id,customer_type)
)@

create table people (
	customer_id	int not null,
	customer_type char( 1 ) not null check (customer_type in ('P')),
	-- Дополнительные атрибуты физ. лиц
	-- ...
	constraint FK foreign key (customer_id,customer_type)
		references customer (customer_id,customer_type)
			on delete restrict on update restrict,
	constraint PK primary key (customer_id)
)@



create table organization (
	customer_id	int not null,
	customer_type char( 1 ) not null check (customer_type in ('O')),
	-- Дополнительные атрибуты юр. лиц
	-- ...
	constraint FK foreign key (customer_id,customer_type)
		references customer (customer_id,customer_type)
			on delete restrict on update restrict,
	constraint PK primary key (customer_id)
)@
выглядит приятнее. Единственная проблема - на Customer появляется два ключа. Коррекция двух ключей - опять же - не самое лучшее. Для производительности (предположим таблица People будет содержать миллионы записей) следует создавать по два ключа и на Org и на People. Однако если удаления будут не часты в целом - устроит наверное многих. Можно сказать даже почти всех.
Я б на такую схему вообще поставил - "рекомендовано к использованию"
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33343009
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarer ModelRНаконец, если имеется существующая база, то одно дело добавить UNIQUE, другое реорганизовать PK.
Хм. Возможно тупой вопрос, но - а в чем разница?Нет тупых вопросов, есть тупые ответы. Надеюсь не этот. Имеется ввиду, что в действующей системе многие запросы, функции и другой код как правило составлены с учетом ПК. Переделываем ПК - переделывает джойны по ПК и еще массу кода.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33343264
hardsign
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
[quot softwarer]В данном случае мне не нравится другое: для того, чтобы получить "общие атрибуты клиента", например категорию, нужно писать запрос типа

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
select
  c.*
from 
  Document d,
  People p,
  Organization o,
  Customer c
where
  d.people_id = p.people_id (+) and
  d.organization_id = o.organization_id (+) and
  c.customer_id = coalesce ( p.customer_id, o.customer_id )

М-да, видать я недостаточно внимательно читал исходное сообщение. Конечно, маразм. Мне казалось, что тот факт, что ключ "субъекта" является уникальным (т.е. грубо говоря, и для физиков и для юриков берётся из одной последовательности), очевиден для всех и обсуждению не подлежит. А если взять из договора subject_id, то он будет ключом в subject, а также в одной из таблиц "физик" и "юрик"...
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33345618
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelRИмеется ввиду, что в действующей системе многие запросы, функции и другой код как правило составлены с учетом ПК. Переделываем ПК - переделывает джойны по ПК и еще массу кода.
Cовершенно не обязательно. Если "старый ПК перестает быть уникальным" - тогда да, геморрой. Если же идет именно реорганизация, типа "старый ПК сделали просто уникальным, а ПК объявили что-то еще" - проблемы будут только у изрядно кривых приложений.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33345639
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
hardsignМне казалось, что тот факт, что ключ "субъекта" является уникальным (т.е. грубо говоря, и для физиков и для юриков берётся из одной последовательности), очевиден для всех и обсуждению не подлежит. А если взять из договора subject_id, то он будет ключом в subject, а также в одной из таблиц "физик" и "юрик"...
Виноват, не подумал об этом. Похоже, просто сказалась привычка к другому типу структур.
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33345802
ModelR
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
softwarerЕсли "старый ПК перестает быть уникальным" - тогда да, геморрой. Если же идет именно реорганизация, типа "старый ПК сделали просто уникальным, а ПК объявили что-то еще" - проблемы будут только у изрядно кривых приложений.Согласен, смысл моего поста как раз в этом и был - сохранить уникальность как она есть. Но я под "реорганизацией" понимал именно то, что будет разрешено
Party_id; Party_type 1; 'O' 1; 'P'
"старый ПК (K1) сделали просто уникальным, а ПК объявили что-то еще (K2)" - мне не пришло в голову, я бы просто создал новый UNIQUE K2. Для чего может потребоваться перестановка ПК = K2 , UNIQUE = K1 ?
...
Рейтинг: 0 / 0
Внешний ключ на две таблицы (+)
    #33346096
Фотография softwarer
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
ModelR Для чего может потребоваться перестановка ПК = K2 , UNIQUE = K1 ?
В оракле - для переупорядочивания index-organized table. Может и еще что-то можно придумать, но этого имхо достаточно.
...
Рейтинг: 0 / 0
44 сообщений из 44, показаны все 2 страниц
Форумы / Проектирование БД [игнор отключен] [закрыт для гостей] / Внешний ключ на две таблицы (+)
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


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