В большинстве случаев. , .
- «Персонал» всегда описывает людей.
- Некоторые клиенты - люди.
- Некоторые клиенты являются предприятиями
(организации).
- «Поставщики» обычно (всегда?)
организаций.
- Персонал также может быть клиентом.
- Поставщиками также могут быть клиенты.
Существуют серьезные проблемы с наличием отдельных таблиц телефонных номеров сотрудников, телефонных номеров поставщиков и телефонных номеров клиентов.
- Персонал может быть клиентом. Если персонал
номер телефона меняется, делает ли клиент
номер телефона тоже нужно обновлять? Как узнать, какой из них обновить?
- Поставщиками могут быть клиенты. Если
меняется номер телефона поставщика, делает ли клиент
номер телефона тоже нужно обновлять? Как узнать, какой из них обновить?
- Вы должны дублировать и поддерживать без ошибок ограничения
для телефонных номеров в каждой таблице, которая
хранит номера телефонов.
- Те же проблемы возникают, когда
номер телефона клиента меняется. Сейчас
Вы должны проверить, чтобы увидеть,
телефонные номера сотрудников и
также необходимо обновить.
- Ответить на вопрос "Чей телефон
номер 123-456-7890? ", вы должны
посмотрите в 'n' разных таблицах, где
'n' - это число разных
"виды" партий, с которыми вы имеете дело. В
дополнение к персоналу, клиентам и
поставщики, думаю "подрядчика
телефоны "," телефоны проспекта "и др.
Вам необходимо реализовать схему супертипа / подтипа. (Код PostgreSQL, строго не проверенный.)
create table parties (
party_id integer not null unique,
party_type char(1) check (party_type in ('I', 'O')),
party_name varchar(10) not null unique,
primary key (party_id, party_type)
);
insert into parties values (1,'I', 'Mike');
insert into parties values (2,'I', 'Sherry');
insert into parties values (3,'O', 'Vandelay');
-- For "persons", a subtype of "parties"
create table person_st (
party_id integer not null unique,
party_type char(1) not null default 'I' check (party_type = 'I'),
height_inches integer not null check (height_inches between 24 and 108),
primary key (party_id),
foreign key (party_id, party_type) references parties (party_id, party_type) on delete cascade
);
insert into person_st values (1, 'I', 72);
insert into person_st values (2, 'I', 60);
-- For "organizations", a subtype of "parties"
create table organization_st (
party_id integer not null unique,
party_type CHAR(1) not null default 'O' check (party_type = 'O'),
ein CHAR(10), -- In US, federal Employer Identification Number
primary key (party_id),
foreign key (party_id, party_type) references parties (party_id, party_type) on delete cascade
);
insert into organization_st values (3, 'O', '00-0000000');
create table phones (
party_id integer references parties (party_id) on delete cascade,
-- Whatever you prefer to distinguish one kind of phone usage from another.
-- I'll just use a simple 'phone_type' here, for work, home, emergency,
-- business, and mobile.
phone_type char(1) not null default 'w' check
(phone_type in ('w', 'h', 'e', 'b', 'm')),
-- Phone numbers in the USA are 10 chars. YMMV.
phone_number char(10) not null check (phone_number ~ '[0-9]{10}'),
primary key (party_id, phone_type)
);
insert into phones values (1, 'h', '0000000000');
insert into phones values (1, 'm', '0000000001');
insert into phones values (3, 'h', '0000000002');
-- Do what you need to do on your platform--triggers, rules, whatever--to make
-- these views updatable. Client code uses the views, not the base tables.
-- In current versions of PostgreSQL, I think you'd create some "instead
-- of" rules.
--
create view people as
select t1.party_id, t1.party_name, t2.height_inches
from parties t1
inner join person_st t2 on (t1.party_id = t2.party_id);
create view organizations as
select t1.party_id, t1.party_name, t2.ein
from parties t1
inner join organization_st t2 on (t1.party_id = t2.party_id);
create view phone_book as
select t1.party_id, t1.party_name, t2.phone_type, t2.phone_number
from parties t1
inner join phones t2 on (t1.party_id = t2.party_id);
Чтобы растянуть это немного дальше, таблица для реализации "персонала" должна ссылаться на подтип человека, а не на супертип партии. Организации не могут быть в штате.
create table staff (
party_id integer primary key references person_st (party_id) on delete cascade,
employee_number char(10) not null unique,
first_hire_date date not null default CURRENT_DATE
);
Если поставщиками могут быть только организации, а не отдельные лица, то в таблице поставщиков-поставщиков аналогичным образом будет указываться подтип организаций.
Для большинства компаний заказчиком может быть либо физическое лицо, либо организация, поэтому таблица, в которой клиенты реализованы, должна ссылаться на супертип.
create table customers (
party_id integer primary key references parties (party_id) on delete cascade
-- Other attributes of customers
);