Форум: "Прочее";
Текущий архив: 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.049 c