Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Прочее";
Текущий архив: 2011.11.13;
Скачать: [xml.tar.bz2];

Вниз

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;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.003 c
2-1310392304
jetus
2011-07-11 17:51
2011.11.13
MDI-приложение и перерисовка родительской формы


2-1311459358
Aleks1995
2011-07-24 02:15
2011.11.13
Отправка почты в Дельфи


15-1310569650
R_R
2011-07-13 19:07
2011.11.13
PHP, Как составить список подключенных сокетов?


15-1310730513
Rendy_Stager
2011-07-15 15:48
2011.11.13
Помощь по Клиент-серверному приложению


15-1310539493
SQLEXPRESS
2011-07-13 10:44
2011.11.13
Ctrl+shift+с во время описания класса. Некорректно





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский