|
|
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
MasterZivЭто вы что-то перепутали. как раз нормальные люди используют для этого специально придуманный для этого NULL. Философски тут можно поспорить. NULL - некий эквивалент бытового понятия "значение неизвестно", но для даты начала действия оно-то уж точно известно - скажем это может быть дата начала деятельности фирмы. История любой учетной величины имеет свое начало, другое дело, что разбираться с этим нет желания. Дата конца истории тоже понятная величина - это текущее время (в будущем - это уже не история :) ). Так что никаких неизвестных величин тут нет. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2008, 17:57:34 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov Andrey пишет: > Философски тут можно поспорить. NULL - некий эквивалент бытового понятия > "значение неизвестно", Тут и спорить нечего. NULL - это и есть значение, которое заведомо несовпадает ни с одним значением домена. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 19.11.2008, 22:26:45 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
MasterZivТут и спорить нечего. NULL - это и есть значение, которое заведомо несовпадает ни с одним значением домена. Строго говоря, нельзя сказать "несовпадает" ). К тому-же в данном случае мы имеем некие характеристики значения т.к. известно что первое значение даты меньше, а последнее больше. Т.е. уже вроде как не null. Ну да ладно, все равно голосую за вариант с одной датой, тем более, судя по всему, у автора MSSQL, а не oracle. А значит можно использовать такой запрос: Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 00:16:12 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
MasterZivТут и спорить нечего. NULL - это и есть значение, которое заведомо несовпадает ни с одним значением домена. Ну во-первых, я предупредил, что вопрос философский, поэтому рассматривать его нужно не с практической точки зрения. Во-вторых, у вас странное представление о NULL. NULL, это не "нечто ни с чем не совпадающее", у него вполне конкретный смысл - "значение неизвестно". В-третьих, для случая с историей значений в качестве даты начала нужно некоторое значение "минус бесконечность" :) Так как ни один производитель СУБД еще не расширил домены данных таким значением, так каждый сам выбирает что-то из имеющегося для его замены. И в данном случае использование NULL вместо минус бесконечности будет ровно таким же частным соглашением, как и 24 августа 1572 года (оба варианта в подавляющем большинстве систем заведомо не совпадают ни с одним из допустимых значений). Более того, с практической точки зрения использование конкретной даты удобнее, так как позволяет писать более простые запросы. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 09:08:40 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Вообще-то Bogdanov Andrey немного неправильно построил примеры. Более близкой аналогией будет структура таблиц: Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. Можно протестировать это? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 14:48:20 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov Andrey В-третьих, для случая с историей значений в качестве даты начала нужно некоторое значение "минус бесконечность" :) Так как ни один производитель СУБД еще не расширил домены данных таким значением, PostgreSQL имеет '-infinity'::timestamp и 'infinity'::timestamp ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 14:50:12 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Funny_FalconВообще-то Bogdanov Andrey немного неправильно построил примеры. Более близкой аналогией будет структура таблиц: Хм. Я не знаю какие именно запросы интересуют автора. Я приводил пример на тот случай, если мы пытается понять состояние одного объекта на заданную дату. Вы приводите случай, когда пытаемся получить полный срез по всем объектам. По моему опыту первая задача возникает гораздо чаще. Ну а то, что во втором случае таблица с двумя датами может выиграть я писал еще на второй странице этого топика. Если конкретно по вашим запросам, то во втором варианте все равно имеем full scan, а в первом - hash join. Количество обращений к диску (и время выполнения операций) очень сильно зависит от соотношения длины истории и количества объектов. При относительно малом числе объектов (разлиных значений поля kod) с длинной историей выигрывает первый вариант, при большом количестве объектов с короткой историей - второй. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 17:04:09 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Funny_FalconPostgreSQL имеет '-infinity'::timestamp и 'infinity'::timestampСпасибо, буду знать. А где можно посмотреть на описание? Интересно как реализована арифметика и логические операцити с этим. А для числовых типов что-то подобное есть? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 17:09:32 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov AndreyFunny_FalconВообще-то Bogdanov Andrey немного неправильно построил примеры. Более близкой аналогией будет структура таблиц: Хм. Я не знаю какие именно запросы интересуют автора. Я приводил пример на тот случай, если мы пытается понять состояние одного объекта на заданную дату. Вы приводите случай, когда пытаемся получить полный срез по всем объектам. По моему опыту первая задача возникает гораздо чаще. Ну а то, что во втором случае таблица с двумя датами может выиграть я писал еще на второй странице этого топика.Есть подозрение, что это будет примерно одинаковов по эффективности. Стоит посмотреть на такой запрос для одной даты и на составной индекс "kod, dt" Код: plaintext 1. 2. 3. 4. 5. Запрос, составленный Funny_Falcon , не очень верный - дает неверный результат. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 18:38:05 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bely, на философский вопрос не может быть практического ответа. В зависимости от СУБД ваш запрос (даже если его оптимизировать) может быть как быстрее так и медленнее простого Код: plaintext Если ваша СУБД хорошо переваривает такой запрос, то и нечего извращаться с одной датой. А представьте, если нужно сопоставить состояния нескольких объектов, да не в определённый момент времени, а в исторической перспективе. Что тогда деать с одной датой? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 18:58:34 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
explaBely, на философский вопрос не может быть практического ответа. В зависимости от СУБД ваш запрос (даже если его оптимизировать) может быть как быстрее так и медленнее простого Код: plaintext 2. Свои филосовские измышления я строю на пониамнии того как примерно будет выбирать сервер данные. explaЕсли ваша СУБД хорошо переваривает такой запрос, то и нечего извращаться с одной датой.Здесь вопрос стоит не столько в том сколько дат использовать, а втом - сколько дат включать в индекс и какие индексы строить в разных вариантах. explaА представьте, если нужно сопоставить состояния нескольких объектов, да не в определённый момент времени, а в исторической перспективе. Что тогда деать с одной датой?Собственно, базовый запрос нарисован - надо будет только запустить его на выполнение и анализировать :). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 19:09:10 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
BelyЯ склоняюсь к мнению, что если использовать две даты, то строить надо только один индекс - по первой дате :) Практика показывает, что для Оракла лучше индексировать обе даты. Тогда ещё на этапе сканирования индекса SQL машина отбросит нерелевантные данные и выполнит единственное чтение блока БД. Когда одна из дат не входит в индекс, а предикат на индексированную дату возврашает много строк SQL машина будет вынуждена дёрнуть каждую строку из блоков БД, чтобы проверить ограничение на непроиндексированную дату. Опять же, практика показывает, что извращения с min(dt) ни чуть не быстрее сканирования индекса с двумя датами, но при этом такие запросы решают лишь малый класс задач. Дополнительная память мало сказывается на скорости, потому как индекс обычно содержит много других данных, как минимум одну из дат и ROWID, ID объекта и т.п.. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 19:13:20 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov AndreyFunny_FalconPostgreSQL имеет '-infinity'::timestamp и 'infinity'::timestampСпасибо, буду знать. А где можно посмотреть на описание? Интересно как реализована арифметика и логические операцити с этим. А для числовых типов что-то подобное есть? Нужно не путать понятие математической бесконечности, как предела некоторой бесконечной последовательности и специального значения переменной в дискретной ЭВМ. Для типа date всегда определена самая ранняя и самая поздняя дата, которые этот тип может принять. Собственно эти даты и можно использовать в качестве самой большой и самой маленькой даты. Бесконечно большая и бесконечно малая даты несут в себе семантику недостижимой величины которую нельзя ни с чем сравнить (природа этой величины - некая неопределённось, которую можно раскрыть только аналитическими методами, но не численными). Такие даты вряд ли имеют практический смысл в нашем бренном мире, тем более для дискретных вычислительных машин. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 19:27:15 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov AndreyFunny_FalconPostgreSQL имеет '-infinity'::timestamp и 'infinity'::timestampСпасибо, буду знать. А где можно посмотреть на описание? Интересно как реализована арифметика и логические операцити с этим. А для числовых типов что-то подобное есть? 8.5.1.5. Special Values 8.1.3. Floating-Point Types Тесты в версии PostgreSQL 8.3 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 20:03:21 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Добавлю 5 копеек по теме. История сущности может характеризоваться её состояниями и переходами этих состояний (как граф, можно описывать и рёбрами и узлами). В этом смысле второй вариант (с диапазоном дат) реализует модель с истории состояний. Что касается переходов, то переход характеризуется исходным и конечным состоянием и датой. В этом смысле первому варианту не хватает полей для хранения предыдущего состояния. Принцип один факт, одна запись для второго случая нужно рассмотреть с другой стороны. Факт перехода состояния мы не регистрируем в БД, мы регистрируем два факта - завершение старого сотояние и создание нового состояния, отсюда и вовлечение в транзакцию двух записей. Обеспечение целостности в обеих случаях для современных реляционных СУБД, которые ориентированы на хранение состояния системы на один момент времени, задача нетривиальная. Ну нету в них адекватных декларативных ограничений целостности! То что говорили о зависимости записей, то Primary Key пример такой зависимости, т.е. возможность изменять значения ключевого поля одной записи зависит от значений этого поля в других записях таблицы и это нормально! Во втором случае эту задачу не сложно решить используя триггеры, но на практике обычно на это можно вообще забить. Если все изменения истории выполнять проверенными надёжными процедурами, то такие процедура могут гарантировать целостность данных самим фактом своего использования. В первом случае мы наблюдаем лишь иллюзию надёжности по той причине, что в записи о переходе состояния нет данных о прежнем состоянии. Таким образом можно в историческую последовательность воткнуть произвольную запись, которая логически не могла быть результатом перехода из предыдущего состояния, и не может быть исходным состоянием для следующего перехода. Проверка корректности таких переходов опять же лежит на совести программного обеспечения БД. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 20.11.2008, 21:08:04 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
expla пишет: > времени, задача нетривиальная. Ну нету в них адекватных декларативных > ограничений целостности! То что говорили о зависимости записей, то Да есть, только недекларативные - триггерами. Кстати, тут вот R:Base вспоминали. Так там, если не изменяет память, как раз были check constraint-ы, позволяющие внутри писать запрос ЛЮБОЙ СЛОЖНОСТИ, и даже из других таблиц. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 00:54:46 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Funny_FalconТесты в версии PostgreSQL 8.3Спасибо. Исчерпывающе. Тут кстати и объяснение для expla почему специальный литерал лучше, чем некоторая "самая ранняя дата" из поддерживаемых системой. Вряд ли для самой ранней даты будут выполняться приведенные арифметические правила. Ну а то, что этот литерал не является эквивалентом "математической бесконечности" меня не смущает. Мне математическая бесконечность и не нужна. :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 08:59:21 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
MasterZiv expla пишет: > времени, задача нетривиальная. Ну нету в них адекватных декларативных > ограничений целостности! То что говорили о зависимости записей, то Да есть, только недекларативные - триггерами. Кстати, тут вот R:Base вспоминали. Так там, если не изменяет память, как раз были check constraint-ы, позволяющие внутри писать запрос ЛЮБОЙ СЛОЖНОСТИ, и даже из других таблиц. А в других СУБД разве нельзя в constraint`ах использовать функции? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 09:54:39 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
expla Практика показывает, что для Оракла лучше индексировать обе даты. Что за практика? Чем лучше? expla Тогда ещё на этапе сканирования индекса SQL машина отбросит нерелевантные данные и выполнит единственное чтение блока БД. Когда одна из дат не входит в индекс, а предикат на индексированную дату возврашает много строк SQL машина будет вынуждена дёрнуть каждую строку из блоков БД, чтобы проверить ограничение на непроиндексированную дату. Я тоже так считал, но показанные Bogdanov Andrey результаты говорят об обратном (почти). Данных-то читать - один блок. А сколько блоков индекса читать? expla Опять же, практика показывает, что извращения с min(dt) ни чуть не быстрее сканирования индекса с двумя датами, но при этом такие запросы решают лишь малый класс задач. Дак познакомьте с практикой! Очень интересно! Надо бы по конкретнее Вообще, лично я был не прав, доказывая, что две лучше одной, т.к. предполагал для одной даты следующий примерный алгоритм: 1) для каждой записи истории найти дату ее окончания (второй просмотр таблицы) 2) для каждой записи истории с датой окончания - выбрать только те, в диапазон дат которых попадает искомый момент. Соответственно, я предполагал, что т.к. в случае с двумя датами искать дату окончания не нужно, значит работать должно быстрее, т.е. вместо двух - один проход по таблице. Короче, мозк нада было включить!!! Очень понравилось то, что SELECT MAX(x) from t where x<:1 и для условия и для агрегирующей функции используется один индекс и один проход!!! Собственно это и победило при выборе алгоритма! Можно использовать две даты (если бизнес-логика хочет), запрос будет - как в варианте с одной датой, дополненный в конце условием на вторую дату (если есть "дыры"). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 10:23:43 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
KOT MATPOCKuH, +1 - после показанных тестов вопрос что лучше перестает быть однозначным. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 10:27:38 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
explaОпять же, практика показывает, что извращения с min(dt) ни чуть не быстрее сканирования индекса с двумя датамиПриведенные выше примеры как раз иллюстируют то, что "извращения" намного быстрее. Не буду спорить с тем, что у меня руки кривые, но других цифр пока никто не привел. Только теоретизируют. Ссылаясь на "практика показывает" постарайтесь приводить хоть какие-то доказательства. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 10:33:45 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
призрак коммунизма пишет: > А в других СУБД разве нельзя в constraint`ах использовать функции? Функции можно как правило. Запросы нельзя. Posted via ActualForum NNTP Server 1.4 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 10:37:05 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
MasterZiv> А в других СУБД разве нельзя в constraint`ах использовать функции? Функции можно как правило. Запросы нельзя. Тут есть тонкость - запрос сегодня может возвращать одно, завтра другое. В зависимости от данных, которые лежат в БД. В таком случае может получиться, что те данные, которые были введены вчера - сегодня уже неверные. Как серверу поступать с ними? Типичный пример недетерминированного правила: Код: plaintext ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 10:49:56 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov AndreyПриведенные выше примеры как раз иллюстируют то, что "извращения" намного быстрее . Не буду спорить с тем, что у меня руки кривые, но других цифр пока никто не привел. Только теоретизируют. Ссылаясь на "практика показывает" постарайтесь приводить хоть какие-то доказательства. Передергиваете. Я приводил пример оптимизированного запроса с двумя датами для вашей модели. Индекс только по start_dt. Чтений там будет меньше, чем у вас раза в полтора-два (думаю, вы и сами это проверили) - за счет однократного прохода индекса. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 13:43:13 |
|
||
|
История одна дата vs две. Что лучше?
|
|||
|---|---|---|---|
|
#18+
Bogdanov AndreyexplaОпять же, практика показывает, что извращения с min(dt) ни чуть не быстрее сканирования индекса с двумя датамиПриведенные выше примеры как раз иллюстируют то, что "извращения" намного быстрее. Не буду спорить с тем, что у меня руки кривые, но других цифр пока никто не привел. Только теоретизируют. Ссылаясь на "практика показывает" постарайтесь приводить хоть какие-то доказательства. У каждого саоя практика. Речь лишь о том, что на разных СУБД, на разных экземплярах СУБД и на разных экземплярах БД результат может быть разным, в пользу любого из решений. с min(dt) требуется двойной поиск по индексу, сначала чтобы вычислить min, потом, чтобы найти ROWID искомой записи. Для between требуется лишь одно сканирование индекса, но в зависимости от того, что мы чаще ищем - записи в далёком прошлом или самые последние записи следует строить индекс либо по ключу (ID, DT_FROM, DT_TO) или (ID, DT_TO, DT_FROM) соответственно. В принципе, если данные таковы, что в большинстве случаев проверка второй даты не уменьшает количество возвращаемых строк (мне обычно нужно искать текущее состояние объекта и это состояние является крайним в последовательности состояний), то можно ограничиться индексом (ID, DT_FROM) или (ID, DT_TO) соответственно для поиска древних и молодых записей. Если нужна взвешенная оценка, составте таблицу вида "аспект" X "вариант решения". Аспект\РешениеПереходыСостоянияКод транзакцииПростой 3Сложный 1Код запросов Сложный 0 Простой 5Эффективность Средняя 3 Средняя 3Итого: 6 9 Это таблица для моих задач, и я свой вывод уже сделал. 3 - средняя оценка. Наибольший вес имеет аспект "Код запросов", поскольку в первую очередь нужно разработать приложения БД. Если из-за сложности модели данных это сделать не удасться, то всё остальное будет не важно. Запросов к БД обычно значительно больше, чем процедур, которые её изменяют, поэтому аспект "Код транзакции" имеет средний вес. Эффективность может быть разная. На моей БД она получается примерно одинаковой, кроме того скорость запросов для меня не является очень критично, поэтому я поставил среднюю оценку. Аспекты, оценки и их вес в общем итоге вы определяете сами исходя из своих задач. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.11.2008, 13:43:23 |
|
||
|
|

start [/forum/topic.php?fid=32&msg=35664625&tid=1543554]: |
0ms |
get settings: |
6ms |
get forum list: |
16ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
2136ms |
get topic data: |
9ms |
get forum data: |
2ms |
get page messages: |
68ms |
get tp. blocked users: |
2ms |
| others: | 221ms |
| total: | 2466ms |

| 0 / 0 |
