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

Вниз

Исторические справочники   Найти похожие ветки 

 
Bjdob ©   (2016-02-16 10:24) [40]

>обычно в таких системах отношение кол-ва
>записей с IS_ACT_IND = 1 к кол-ву с
>IS_ACT_IND = 0 стремится к нулю

ну у меня как раз корректировка записи редкое явление


 
Кщд ©   (2016-02-16 11:25) [41]

>Bjdob ©   (16.02.16 10:24) [40]
SLOWLY CHANGING dimension же)
если записи не изменяются, то и смысла городить огород нет
если всё же меняются, то рано или поздно "отношение стремится к нулю"
в общем, Ваша задача давно формализована, равно как и методы её решения - это чистый SCD
какой тип больше подходит Вам - решать только Вам


 
Сергей Суровцев ©   (2016-02-16 11:42) [42]

>Кщд ©   (16.02.16 09:45) [38]

Данный запрос написан под конкретные условия конкретной задачи. Будут другие условия, будет другое решение.

>1. вот только физически запись с меньшим ID может быть закоммичена позже записи с большим ID
Теоретически, если генерировать дату на клиенте, то да. Практически, если генерировать дату-время вместе с ID, то нет. Единственная возможность - изменить дату в уже внесенной записи, но тогда это уже не "справочник с историей".

>2. ID может быть цикличен
Тогда это уже не ID

>3. ID может не быть числом
А еще его может вообще не быть. Или быть, но не он. Или еще что-нибудь. Решать нужно конкретную задачу, а не выдумывать из нее теоретическую абстракцию на все случаи жизни.

>поэтому Ваш SQL-запрос логически неверен
Так предложите свой вариант.


 
Кщд ©   (2016-02-16 12:12) [43]

>Сергей Суровцев ©   (16.02.16 11:42) [42]
>Данный запрос написан под конкретные условия конкретной задачи
зачем выдумывать велосипед, который будет работать при некоторых допущениях, когда можно написать то, что будет работать при любых?)

>Теоретически, если генерировать дату на клиенте, то да.
это не так
1. сессия №1 получает ID = 1;
2. сессия №2 получает ID = 2;
3. сессия №2 вставляет данные в таблицу и делает commit;
4. сессия №1 вставляет данные и делает commit.

>Тогда это уже не ID
если Вы ни разу не сталкивались с циклическими генераторами ID, значит, их не существует
я понял)

>Решать нужно конкретную задачу
решать нужно так, чтобы не выстрелить себе в ногу
если разница между устойчивым и неустойчивым решениями - одна строка кода, то выбор как бы очевиден

>Так предложите свой вариант.
уже предложил: необходимо выбирать ID, соответствующий максимальной дате
это приведет к тому, что в Ваш запрос добавится ещё один подзапрос


 
Bjdob ©   (2016-02-16 12:54) [44]

>если всё же меняются, то рано или
>поздно "отношение стремится к нулю"

записи меняются, но редко.
гораздо чаще вставляются новые записи. поэтому не понимаю почему будет стремится отношение к нулю.


 
Bjdob ©   (2016-02-16 12:59) [45]

более того, на бесконечном времени отношение будет стремится к бесконечноси, а не к нулю


 
Сергей Суровцев ©   (2016-02-16 14:48) [46]

>Кщд ©   (16.02.16 12:12) [43]
>это приведет к тому, что в Ваш запрос добавится ещё один подзапрос

SELECT t1.id_gr, t2.id, t2.name FROM
(SELECT s1.id_gr,
(
SELECT kkzz.id FROM street as kkzz
WHERE kkzz.dt_begin =
 (
 SELECT Max(kz.dt_begin) FROM street as kz
 WHERE kz.dt_begin <= "11.06.2015" AND kz.id_gr = s1.id_gr
 )
AND kkzz.id_gr = s1.id_gr
ROWS 1
)
as mid FROM street AS s1
WHERE s1.dt_begin <= "11.06.2015"
GROUP BY s1.id_gr) as t1
LEFT JOIN street as t2 ON t1.mid=t2.id

Хорошо, так академичнее?
Про commit. Неважно, кто будет первый, кто второй. Важно - когда они получат дату - вместе с ID или потом.
Суть вопроса была в том, чтобы показать, что DT_END для решения обозначенных задач не нужно. И таки да, ни в первом, ни во втором варианте их нет.


 
Кщд ©   (2016-02-17 06:49) [47]

>Bjdob ©   (16.02.16 12:59) [45]
>более того, на бесконечном времени отношение будет стремится к >бесконечноси, а не к нулю
речь шла только о том, что для получения АКТУАЛЬНЫХ данных, сканирование по индексу на IS_ACT_IND будет эффективнее, чем по DT_BEGIN, DT_END


 
Кщд ©   (2016-02-18 10:19) [48]

>Сергей Суровцев ©   (16.02.16 14:48) [46]
>Хорошо, так академичнее?
нет
одно лишнее и, к тому же, внешнее объединение

select s.*
from street s
where s.id in (
             select max(s2.id)
             from street s2
             where s2.dt_begin = (select max(s3.dt_begin)
                                 from street s3
                                 where s3.id_gr = s2.id_gr
                                       and s3.dt_begin <= date "2015-06-11"
                                 )
             group by s2.id_gr
             )


>Суть вопроса была в том, чтобы показать, что DT_END для решения >обозначенных задач не нужно
нужно по двум причинам:
1. запись может быть отключена на период, удалена
2. поиск актуальной записи на дату эффективнее по индексу, построенному на dt_begin, dt_end


 
DayGaykin ©   (2016-02-18 13:00) [49]

Только что получил ситуацию, когда ADD_TIME(ID) перестала быть монотонно возрастающей:
У постгреса есть кеш при получении ID. ( http://www.postgresql.org/docs/8.2/static/sql-createsequence.html )
Этот кеш свой на каждое соединение. Поэтому ситуация, когда ID не коррелирует с ADD_TIME очень вероятная в случае более одного соединения с базой данных. Намного более вероятная, чем обратная.


 
Кщд ©   (2016-02-18 13:25) [50]

>DayGaykin ©   (18.02.16 13:00) [49]
есть два простых правила:
1. никогда-никогда-никогда не использовать ID в реализации бизнес-логики
2. всегда-всегда-привсегда использовать ID по прямому назначению: ТОЛЬКО для уникальной идентификации записи

следуя этим правилам, избавляете себя и своих последователей от трудноуловимых ошибок и несете в мир радость и добро


 
Сергей Суровцев ©   (2016-02-18 17:33) [51]

>Кщд ©   (18.02.16 10:19) [48]
Так даже изящнее.

>нужно по двум причинам:
>1. запись может быть отключена на период, удалена

1) 01/01/2015  --- 05/01/2015
2) 05/01/2015  --- 10/01/2015
3) 10/01/2015  --- 15/01/2015

Удаляем (отключаем) (2), какую строку найдет поиск на 07/01/2015?
1) уже неактуальна.
3) еще не актуальна.

>2. поиск актуальной записи на дату эффективнее по индексу, построенному на dt_begin, dt_end

А индекс только на dt_begin будет менее эффективен?


 
TohaNik ©   (2016-02-18 21:21) [52]


> Кщд ©   (18.02.16 13:25) [50]

Это да! И никогда не соглашайтесь на "Этого ни когда не будет" если для выбора одной записи в ключе не хватает хотя бы одногоо поля:0


 
Кщд ©   (2016-02-19 07:56) [53]

>Сергей Суровцев ©   (18.02.16 17:33) [51]
>Удаляем (отключаем) (2), какую строку найдет поиск на 07/01/2015?
по состоянию на 07.01.2015 не найдет ничего
и это правильно, т.к. на указанную дату запись не существовала
это именно та особенность, которую предоставляет dt_end

>А индекс только на dt_begin будет менее эффективен?
конечно
он менее селективен
в вашем примере при предикате dt_begin <= 16.01.2015 по индексу будет выбрано 3 записи,
а при предикате dt_begin <= 16.01.2015 and dt_end > 16.01.2015 - всего одна


 
Сергей Суровцев ©   (2016-02-19 08:58) [54]

>Кщд ©   (19.02.16 07:56) [53]
>по состоянию на 07.01.2015 не найдет ничего
>и это правильно, т.к. на указанную дату запись не существовала
>это именно та особенность, которую предоставляет dt_end

Объясните что это правильно тому пользователю, которому нужно здесь и сейчас занести данные, а ему из справочника вываливается "неизвестно". Я думаю он по достоинству оценит эту замечательную особенность.
Мало того. Есть логика процесса и логика реализации. Так вот по логике процесса если вы убираете промежуточную строку, действие предыдущей должно автоматически распространяться до следующей нормальной. А логика реализации должна, по идее воплощать логику процесса, а не ломать ее.

>он менее селективен
Конечно менее. Но насколько это критично по времени? При разнице на 6-7 порядков, может быть разница и будет заметна. При 1-3 порядках даже зафиксировать не удастся.


 
Сергей Суровцев ©   (2016-02-19 09:17) [55]

>Кщд ©   (19.02.16 07:56) [53]

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


 
Кщд ©   (2016-02-19 10:36) [56]

>Сергей Суровцев ©   (19.02.16 09:17) [55]
>То есть мы говорим о двух принципиально разных подходах.
ваш подход - частный случай SCD type 2
1. он менее гибок в смысле бизнес-логики
2. неэффективен с точки зрения БД
лично я не вижу смысла решать частную задачу, когда за то же время легко и свободно пишется универсальное решение
свою точку зрения никому не навязываю
дискуссию со своей стороны заканчиваю)


 
Юрий Зотов ©   (2016-02-19 15:29) [57]

Для начала еще надо решить - а допустимо ли вообще удалять записи об истории? Ведь при этом история в БД искажается и перестает соответствовать реальной истории.

Если недопустимо, то я бы выбрал более селективный вариант (с DATE_END). А если допустимо, то все равно выбрал бы его, потому что при нем пропуски в истории хотя бы можно обнаружить.

Но это вообще, для случая сферического коня в  вакууме. А конкретно - все зависит от реальной задачи.


 
Сергей Суровцев ©   (2016-02-19 19:28) [58]

Вариант А

1) 01/01/2015  --- 05/01/2015 Гнилушин переулок
2) 05/01/2015  --- 05/01/2015 Юбилейная улица
3) 05/01/2015  --- 25/01/2015 Юбилейная Улица
4) 25/01/2015  --- 05/01/2999 Неширокая улица между магазином №2 и столовой №11

Дубль строки 2 и 3. Удаляя строку 3 (законно, как повторную) имеем разрыв с 5 по 25е.

Вариант Б

1) 01/01/2015  --- 05/01/2015 Гнилушин переулок
2) 05/01/2015  --- 25/01/2115 Юбилейная улица

3) 25/01/2115  --- 30/01/2015 Неширокая улица между магазином №2 и столовой №11 (до исправления)
3) 25/01/2015  --- 30/01/2015 Неширокая улица между магазином №2 и столовой №11 (после исправления)

4) 30/01/2015  --- 25/01/2999 Лукоморье улица

После исправления опечатки строка 2 своей датой окончания перекрывает ближайшие 100 лет.

И таких вариантов будет масса. Перед КАЖДЫМ использованием справочника придется проверять его на адекватность. Или после каждого редактирования. И обвешивать каждое изменение кучей проверок.

Хотя, возможно это действительно универсальное решение с точки зрения "программист без работы не останется".


 
Юрий Зотов ©   (2016-02-19 21:08) [59]

> Сергей Суровцев ©   (19.02.16 19:28) [58]

Грязная база - это не аргумент. Грязи просто не должно быть. И для этого существуют внешние ключи, индексы, триггеры и т.п.


 
Inovet ©   (2016-02-19 21:28) [60]

> [58] Сергей Суровцев ©   (19.02.16 19:28)
> 1) 01/01/2015  --- 05/01/2015 Гнилушин переулок
> 2) 05/01/2015  --- 25/01/2115 Юбилейная улица

В один день два названия. Почему не:
1) 01/01/2015  --- 05/01/2015 Гнилушин переулок
2) 06/01/2015  --- 25/01/2115 Юбилейная улица
?


 
Сергей Суровцев ©   (2016-02-19 22:53) [61]

>Юрий Зотов ©   (19.02.16 21:08) [59]
>Грязная база - это не аргумент. Грязи просто не должно быть. И для этого существуют внешние ключи, индексы, триггеры и т.п.

Согласен, грязи не должно быть. Что и обеспечится кучей обвески. Не забываем еще править DT_END предыдущей по хронологии записи после каждого добавления-редактирования-удаления.
А за появление грязи, когда она все же возникнет, ибо фантазия юзера безгранична, расстрел этого юзера перед всем коллективом и экзекуция остальным в виде недельного чтения вслух SCD type 2, без сохранения оплаты за этот период.


 
Сергей Суровцев ©   (2016-02-19 22:57) [62]

>Inovet ©   (19.02.16 21:28) [60]
>В один день два названия. Почему не:

Можно и так. Это не принципиально, т.к. в общем случае подразумевается DateTime. Главное - гарантировано исключить интервалы неопределенности запрашиваемого значения.


 
Сергей Суровцев ©   (2016-02-19 23:01) [63]

Кстати, равно как и исключить перекрытие интервалов, при которых актуальными могут считаться несколько значений.



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

Форум: "Прочее";
Текущий архив: 2017.01.15;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.59 MB
Время: 0.043 c
15-1457514823
istok20
2016-03-09 12:13
2017.01.15
где искать фрилансеров по Delphi ?


15-1451943001
Юрий
2016-01-05 00:30
2017.01.15
С днем рождения ! 5 января 2016 вторник


6-1256640553
Encore
2009-10-27 13:49
2017.01.15
Post/get неверная кодировка


2-1420537491
Enzain
2015-01-06 12:44
2017.01.15
От какого пользователя запущено приложение.


2-1425902713
KBO78
2015-03-09 15:05
2017.01.15
Как правильно быстрее найти элемент с ошибкой List index out of b





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский