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

Вниз

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

 
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;
Скачать: CL | DM;

Наверх




Память: 0.61 MB
Время: 0.018 c
15-1448011257
Сергей Суровцев
2015-11-20 12:20
2017.01.15
Вот и про нас вспомнили


3-1310747259
Дмитрий
2011-07-15 20:27
2017.01.15
Вылет при изменении данных в гриде (Eh)


2-1432123390
Цукор5
2015-05-20 15:03
2017.01.15
Утечка?


15-1447436787
data
2015-11-13 20:46
2017.01.15
подскажите по my sql


15-1451394616
Kerk
2015-12-29 16:10
2017.01.15
Сувениры