Главная страница
Top.Mail.Ru    Яндекс.Метрика
Текущий архив: 2011.11.13;
Скачать: CL | DM;

Вниз

Design DB tables "exclusive OR"   Найти похожие ветки 

 
Empleado ©   (2011-07-14 13:02) [0]

Поделитесь опытом.
Как вы реализуете данную ситуацию в вашей практике?
Какие таблицы и какие отношения между ними используете?

Например:
Имеется автомобиль. Автомобиль должен проходить тех осмотр: либо через 10.000 км либо через 1 год.

ПС. Цель: однозначно представить эту операцию в дизайне таблиц

Спасибо


 
stas ©   (2011-07-14 13:08) [1]

А в чем собственно проблема?


 
Омлет ©   (2011-07-14 13:31) [2]

Справочником.


 
icelex ©   (2011-07-14 13:41) [3]


> Автомобиль должен проходить тех осмотр: либо через 10.000
> км либо через 1 год.

> stas ©   (14.07.11 13:08) [1]
> А в чем собственно проблема?

во взятке


 
Медвежонок Пятачок ©   (2011-07-14 13:51) [4]

например после очередного то добавляем в табличку две записи.
в одной пробег + 10000 в другой дата через год.
в обоих флаги да/нет.

далее по екзисту проверяем наличие записей с выставленным флагом.
условие - либо текущий пробег >= выставленному пробегу либо сегодня >= выставленная дата.

если экзист вернул пусто, значит либо просрочено очередное ТО, либо на прошлом ТО не записали те две записи.

как-то так.


 
И. Павел ©   (2011-07-14 13:52) [5]

> [0] Empleado ©   (14.07.11 13:02)

Создайте целочисленное поле и по его значению определяйте состояние:
null - автомобиль не прошел техосмотр
1 - прошел через год
2 - прошел через 10000км
любое другое значение - сумма взятки

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

PS: Рекомендую взять БД какого-нибудь приложения (таблиц на 50-200) и посмотреть, как она организована.


 
И. Павел ©   (2011-07-14 13:57) [6]

> [0] Empleado ©   (14.07.11 13:02)

А если нужно хранить не только последний техосмотр, то можно добавить таблицу с историей техосмотра, например, с помями: id, idМашины, тип (1 - через 10000, 2 - через 1 год), дата.


 
Empleado ©   (2011-07-14 16:20) [7]


> Медвежонок Пятачок ©   (14.07.11 13:51) [4]

Подобное представление не помогает "увидеть" бизнес-логику XOR через организацию отношений различных таблиц (когда по отношениям можно было бы понять о сути операции).

В настоящий момент мы тоже пользуемся "суррогатами".


 
Медвежонок Пятачок ©   (2011-07-14 16:26) [8]

как так не видно?

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

просто и понятно, если не зацикливаться на "правильной" реализации ксора который тут вроде бы напрашивается (а на самом деле нет)


 
Dimka Maslov ©   (2011-07-14 16:28) [9]

У меня в машине прямо указывается срок или остаток пробега до следующего ТО c выводом предупреждения, что пора бы и на сервисе показаться. Отсюда мораль: надо хранить дату и показания одометра при последнем ТО. Признак необходимости ТО определять как (Today - RecentServiceDate > 365) or (Mileage - RecentServiceMileage > 10000)


 
DiamondShark ©   (2011-07-14 19:01) [10]


> однозначно представить эту операцию в дизайне таблиц

Операции в дизайне таблиц не представляются. В дизайне таблиц представляются множества допустимых значений данных, а операции переводят данные из одного допустимого состояния в другое. Операции представляются последовательностями команд DML.
/всегда ваш К.О./


 
Empleado ©   (2011-07-15 11:35) [11]


> DiamondShark ©   (14.07.11 19:01) [10]

Хорошо, /всегда наш К.О./ :), называй операцию ситуацией.
ПС. По части операций ты прав. Операции мы также представляем в качестве данных таблиц.

Суть:
представить бизнес-логику процесса выбора "либо одного, либо другого, но не двух одновременно" через взаимоотношения таблиц БД.
Цель:
Так, чтобы когда разработчик увидел графическое представление таблиц на бумаге, он однозначно понял, что это за сутация и какие операции использовать, чтобы ее реализовать.

Возможно ли?

ПС. Другой пример: Таблица регистрации каких-нибудь клиентов, например ClientReg. Клиентом может быть как IDStaff из внутренних ресурсов (из таблицы HR), так и IDCustomer из внешних ресурсов (из таблицы Customers), но только один может быть зарегистрирован и участвовать в данной регистрации.


 
Компромисс   (2011-07-15 11:44) [12]

Клиентом может быть как IDStaff из внутренних ресурсов (из таблицы HR), так и IDCustomer из внешних ресурсов (из таблицы Customers), но только один может быть зарегистрирован и участвовать в данной регистрации.


create table client(id int not null, hr_id int, customer_id int);

alter table client ADD CONSTRAINT fk_hr_id FOREIGN KEY (hr_id) REFERENCES HR(id);

alter table client ADD CONSTRAINT fk_customer_id FOREIGN KEY (customer_id) REFERENCES Customers(id);

ALTER TABLE client
     ADD CONSTRAINT one_client_id_is_not_null CHECK (hr_id is null AND customer_id is not null OR  hr_id is not null AND customer_id is null)

?


 
Медвежонок Пятачок ©   (2011-07-15 12:08) [13]

Клиентом может быть как IDStaff из внутренних ресурсов (из таблицы HR), так и IDCustomer из внешних ресурсов (из таблицы Customers), но только один может быть зарегистрирован и участвовать в данной регистрации.


Зачем две таблицы для одной сущности ?
Сначала создали проблему, затем боретесь с ней.


 
DiamondShark ©   (2011-07-15 12:53) [14]


> Empleado ©   (15.07.11 11:35) [11]
> представить бизнес-логику процесса выбора "либо одного,
> либо другого, но не двух одновременно" через взаимоотношения
> таблиц БД.

А с чего это вдруг не одновременно?
Вот есть у нас автомобиль. Дата последнего техосмотра -- 15.07.2010, последнее показание спидометра -- 99990.
Сегодня мы берём машинку из гаража, катаемся и ставим на место.
На спидометре 100017 а на часах 00:15 16.07.2011.
Но сейчас ночь, а утром -- выходной. И завтра выходной. А в понедельник в ГАИ неприёмный день. А со вторника водила в отпуске, а начгар напился и в прогуле. В среду просто всем пофиг, в четверг шмон из налоговой, а в пятницу юбилей фирмы и корпоратиффчик.
В общем, к следующему понедельнику машинка так и стоит с накрученной десяткой и уже неделей, как второй год.
Наконец, опухший начгар выполз на работу, и в порыве служебного рвения отправил на техосмотр десяток машин. Включая те, которым по срокам ещё меяц-другой можно было бы и поездить.

Где здесь исключающие ситуации, и какие такие "ОПЕРАЦИИ" должны быть зашифрованы в "дизайне таблиц" -- в упор не вижу.

Машина может стоять в гараже и с десяткой пробега и без, и меньше года, и больше года, и с техосмотром и без. И всё в любых сочетаниях.

Юзеру нужно видеть машины, которые необходимо отправить на осмотр. Но это никак не выражается в "дизайне таблиц". Это выражается в пользовательском запросе к данным:

select *
from [Машины]
where
DATEDIFF(year, [ДатаПоследнегоОсмотра], GETDATE()) >= 1
or
[ПробегСПоследнегоОсмотра] >= 10000;

Весь "дизайн таблиц" сводится к наличию полей [ДатаПоследнегоОсмотра] и [ПробегСПоследнегоОсмотра], или какой-нибудь аналогичной ботвы, позволяющей фиксировать подобную информацию.

Как глядя на этот "дизайн" определить, что пробег должен быть 10000, а срок 1 год? Да никак.
Потому что это, вообще говоря, тоже бизнес-данные. Завтра выйдет закон, что осмотр нужен раз в 3 года при пробеге в 25000. Но, кроме Москвы. А в Москве -- раз в полгода и через 5000.


 
DiamondShark ©   (2011-07-15 13:03) [15]


> Другой пример: Таблица регистрации каких-нибудь клиентов,
>  например ClientReg. Клиентом может быть как IDStaff из
> внутренних ресурсов (из таблицы HR), так и IDCustomer из
> внешних ресурсов (из таблицы Customers), но только один
> может быть зарегистрирован и участвовать в данной регистрации.

Вариант первый
CREATE TABLE ClientReg(
ID bigint not null primary key,
IDStaff  bigint null,
IDCustomer bigint null,
CONSTRAINT FK_CLIENT_STAFF FOREIGN KEY(IDStaff)
REFERENCES Staff(ID),
CONSTRAINT FK_CLIENT_CUSTOMER FOREIGN KEY(IDCustomer)
REFERENCES Customers(ID),
CONSTRAINT CK_CLIENTID CHECK((IDStaff  is not null and IDCustomer is null) or (IDStaff  is null and IDCustomer is not null))
)

Вариант второй
CREATE TABLE ClientReg(
ID bigint not null primary key,
IDClient  bigint not null,
CONSTRAINT FK_CLIENT FOREIGN KEY(IDClient)
REFERENCES Entities(ID)
)

CREATE TABLE Entities(
ID bigint not null primary key,
...
)

CREATE TABLE Stuff(
ID bigint not null primary key,
...
CONSTRAINT FK_ENTITY FOREIGN KEY(ID)
REFERENCES Entities(ID)
)
CREATE TABLE Customers(
ID bigint not null primary key,
...
CONSTRAINT FK_ENTITY FOREIGN KEY(ID)
REFERENCES Entities(ID)
)



Страницы: 1 вся ветка

Текущий архив: 2011.11.13;
Скачать: CL | DM;

Наверх




Память: 0.52 MB
Время: 0.009 c
2-1311579988
arturich
2011-07-25 11:46
2011.11.13
Цвет поля в DevExpress cxGrid


4-1251951251
imp
2009-09-03 08:14
2011.11.13
Обработка сообщений от дочерних контролов


1-1272500252
SPeller
2010-04-29 04:17
2011.11.13
Можно ли проверить указатель на корректность?


3-1266236064
Раиса
2010-02-15 15:14
2011.11.13
MySQL и несколько insert-ов


15-1309890322
Petr V. Abramov
2011-07-05 22:25
2011.11.13
вышел сегодня на новую работу