В Советской Белоруссии SQL разжигает айседа
http://theiced.livejournal.com/238346.html
Собственно, про кобол я не знаю, на дельфи пишу уже 15 лет и никак избавится от него не могу (слишком много легаси кода), а вот про SQL я с ним не согласен.
Сам по себе SQL очень хорошо подходит для генерации отчетов. Если отчет сводится к фильтрации-сортировке-группировке множеств - идеально. С рекурсивными CTE - еще и деревья можно обрабатывать, не особо включая мозг. Всунув поверх этого минимальных размеров постобработку на какой-нибудь функциональщине, можно сделать почти любой отчет, пришедший в голову свихнувшимся на Excel выпускникам нархоза, работающим в минстате, минфине и МНС.
Но когда доходит до процедурных расширений, API между СУБД и клиентскими приложениями или каких-нибудь вещей, которые забыли вовремя добавить в стандарт - начинается полная, немыслимая жопа.
Например, проклятая тема - генерация автоинкрементных ключей и возвращение значений автоматически заполненных полей. Кто во что горазд - identity, генераторы, sequence, функции (в каждой СУБД названные по разному), returning, заебы на тему "вызывать в той же транзакции и сессии" и прочая и прочая. Про вариации на тему "вернуть поле, которое заполняется автоматически, но не является ключом/identity" лучше даже не думать.
Неудивительно, что люди при первой же возможности сбегают в ORM (которые являются уже второй производной от всего этого маразма и несут на себе его неизгладимый след).
Собственно, про кобол я не знаю, на дельфи пишу уже 15 лет и никак избавится от него не могу (слишком много легаси кода), а вот про SQL я с ним не согласен.
Сам по себе SQL очень хорошо подходит для генерации отчетов. Если отчет сводится к фильтрации-сортировке-группировке множеств - идеально. С рекурсивными CTE - еще и деревья можно обрабатывать, не особо включая мозг. Всунув поверх этого минимальных размеров постобработку на какой-нибудь функциональщине, можно сделать почти любой отчет, пришедший в голову свихнувшимся на Excel выпускникам нархоза, работающим в минстате, минфине и МНС.
Но когда доходит до процедурных расширений, API между СУБД и клиентскими приложениями или каких-нибудь вещей, которые забыли вовремя добавить в стандарт - начинается полная, немыслимая жопа.
Например, проклятая тема - генерация автоинкрементных ключей и возвращение значений автоматически заполненных полей. Кто во что горазд - identity, генераторы, sequence, функции (в каждой СУБД названные по разному), returning, заебы на тему "вызывать в той же транзакции и сессии" и прочая и прочая. Про вариации на тему "вернуть поле, которое заполняется автоматически, но не является ключом/identity" лучше даже не думать.
Неудивительно, что люди при первой же возможности сбегают в ORM (которые являются уже второй производной от всего этого маразма и несут на себе его неизгладимый след).
no subject
Честно говоря не пойму про что вы говорите, где и как можно забыть индекс.
Да очень просто. На момент проектирования предполагалось что тут данных будет мало. А потом внезапно план выполнения запроса посмотрели опаньки, а их тут много.
Запрос пишется и отлаживается в IBExpert, там же контролирую статистику чтений индексных, неиндексных, смотрю план. Если что не нравится - корректирую/переписываю запрос. Можно играться хинтами но я этого не умею и в принципе не хочу использовать т.к. это дело иногда меняется, в новых версиях сервера. Зарулить запрос на использование нужных мне индексов можно используя outer join и хаки типа "+0".
После отладки текст запроса копируется в компонент в Delphi.
Учтивая характер того как вы разрабатываете, не удивительно. Но такая скорость разработки для любого другого софта просто не приемлема. Как правило фича нужна не через месяц как разработчик насладится игранием в explain и его адаптацией к конкретной ситуации, а завтра. В этом случае есть время выработать внятные подходы со слабой связностью. Чтобы в случае чего было просто это переделать. Но это же хотя и позволяет делать ошибки, но позволяет так же исправлять их просто и быстро.
no subject
Количество данных очевидно на этапе постановки требований, а кривые планы видны на первом же запуске на забитой тестовыми данными базе, если оптимизатору крышу сорвало.
Конкретно к планам и количеству данных ORM никакого отношения не имеет, если не делать херни вида "забрали все 100500 объектов на клиента, там обработали и положили обратно".
no subject
Какой месяц на explain, каких данных мало?
Количество данных очевидно на этапе постановки требований, а кривые планы видны на первом же запуске на забитой тестовыми данными базе, если оптимизатору крышу сорвало.
Далеко не всегда :) Иногда есть проблема вида надо вчера. Плюс изначально при постановке предполагался меньший поток данных, а фактически получили больший. Плюс можно поймать баг explain использует не тот индекс. Я такое на PostgreSQL ловил. Лечилось отстрелом индекса как это не парадоксально.
Конкретно к планам и количеству данных ORM никакого отношения не имеет, если не делать херни вида "забрали все 100500 объектов на клиента, там обработали и положили обратно".
Конкретно надо по месту смотреть что там будет. И старательно бить канделябром за забрали 100500 объектов.
no subject
А если нужен но мешает вот в этом конкретном запросе - то его можно отключить конструкциями типа "+0", правда я не в курсе работает ли этот хак на постгресе.
Базы у меня гигабайтные, поэтому уже никаких "внезапно отросших данных" давно не наблюдаю, и тестировать есть на чем.
no subject
А если нужен но мешает вот в этом конкретном запросе - то его можно отключить конструкциями типа "+0", правда я не в курсе работает ли этот хак на постгресе.
Нет хинтов в PostgreSQL. А индекс был добавлен еще давно и как раз было внезапно много данных.
Базы у меня гигабайтные, поэтому уже никаких "внезапно отросших данных" давно не наблюдаю, и тестировать есть на чем.
То что у вас все хорошо тут уже все поняли и я сильно сочувствую тем кто будет переделывать систему после вас.
no subject
>> правда я не в курсе работает ли этот хак на постгресе.
>>>> Нет хинтов в PostgreSQL. А индекс был добавлен еще давно и как раз было внезапно много данных.
Ну вот я говорю что был добавлен давно - ведь с какой-то целью? А удалив его ту цель поломали.
Я не советовал пользоваться хинтами.
Если упрощенно то
select id, name from table where id = 10
заюзает индекс по ID.
Но если запрос написать в виде
select id + 0 as id, name from table where id = 10
то индекс по ID уже использоваться не будет.
Далее надеюсь понятно как можно отключать индексы.
Повторю - это в Firebird есть такая особенность оптимизатора. Сработает ли это в PG - не в курсе.
Почитал про EXPLAIN - оказалось что это план запроса так называется в PG.
В Firebird оптимизатор поплоше чем в PG будет, но даже и в PG засады случаются, поэтому при написании запроса, если хоть сколько-то интересуют перспективы работы - просмотр получаемого плана обязателен.
В IBExpert вместе с планом еще показывается статистика - из каких таблиц сколько записей было прочитано/изменено/удалено, с применением индексов и без них. И если данные похожи на реальные - сразу видно где засада может вырасти.
no subject
Ну вот я говорю что был добавлен давно - ведь с какой-то целью? А удалив его ту цель поломали.
Была другая выборка.
В IBExpert вместе с планом еще показывается статистика - из каких таблиц сколько записей было прочитано/изменено/удалено, с применением индексов и без них. И если данные похожи на реальные - сразу видно где засада может вырасти.
Фишка в том что иногда вы не можете предсказать какие там данные будут. Только предположить и эти предположения могут быть ошибочны.
no subject
no subject
no subject
Запросов не так много, а те что требуют внимания к плану - так и вообще мало.
Впрочем может быть с ОРМ другая ситуация с запросами, они генерятся ОРМ на каждый чих - тогда действительно охренеешь смотреть.
no subject
А не надо смотреть всех выполняемых. Надо смотреть при написании.
Вот заняться мне больше нечем, как сидеть и смотреть как же я туда положу данные. В 90% случаев это будет одинаково, что чтение, что запись. Особенно при CRUD.
Впрочем может быть с ОРМ другая ситуация с запросами, они генерятся ОРМ на каждый чих - тогда действительно охренеешь смотреть.
Еще раз. Их количество ровно такое же какое будет у вас при ваших формах. Фишка в том что если операция типовая мне не надо туда вообще смотреть и писать запрос. А вам приходится смотреть на каждую форму.
no subject
У меня нет такого вопроса, формы уже все сделаны и в большом количестве не добавляются.
Мой проект имеет меньше прокладок, он проще, поэтому проще в поддержке и в ознакомлении с ним другим программистом.
Вы меня пытаетесь убедить что без ОРМ я действую неправильно и поэтому мой проект плох.
no subject
Ваш ОРМ решает вопрос как нагенерить 100 форм за 1 день.
У меня нет такого вопроса, формы уже все сделаны и в большом количестве не добавляются.
Используемые мной и остальными в обсуждении этой записи технологии нужны не только для нагенерить 100 форм в день. А еще и для улучшения поддержки кода.
Мой проект имеет меньше прокладок, он проще, поэтому проще в поддержке и в ознакомлении с ним другим программистом.
Ваш проект имеет свои велосипедные прокладки. И это не проще это сложнее. и это хуже. Так-как программисту вместо ага тут используется это надо изучать чего вы там наделали.
Вы меня пытаетесь убедить что без ОРМ я действую неправильно и поэтому мой проект плох.
Я пытаюсь вас убедить что создание своего велосипеда, при наличии готового инструмента это плохо. И ваш проект плох, потому что он написан на устаревших технологиях и сопровождать после вас это никто не будет. Даже не мечтайте.
(no subject)
(no subject)
(no subject)
(no subject)
no subject
Запрос определяет сущность формы.
Кроме этого запроса на форме есть еще один, для режима поиска конкретного документа по параметрам.
Поля те же самые но условия задаются по другому. Можно было вструмить те условия и в этот запрос но тогда пострадала бы читаемость запроса.
-- FrmDocs.QSel
-- Журнал складских документов
--
select
bdok.id as id,
iif (bdok.lck = 1, 'Б', '') as lck,
bdok.sf_d as sf_d,
bdok.sf_n as sf_n,
bdok.io as io,
bdok.ndok as ndok,
bdok.data as data,
bdok.type_ as type_,
bdok.idpost as idpost,
iif(oper < 10 , '', 'возврат' ) as ret,
iif(idpost >= 0 , '', 'перемещение') as mov,
post.name || iif((post.gorod = ''), '', ' (' || post.gorod || ')' )
as post_full_name,
bdok.summ_w_nds as summ_w_nds,
bdok.msg as msg,
--
(select count(*) from logprd where (logprd.id_bdok = bdok.id)) as prn_count, -- сколько раз распечатывался документ
--
iif (bdok.io in ('t', 'f'), 'S', '') as ROW_FONTSTYLE, -- перечеркнем удаленные доки
iif(idpost >= 0 , '', 'BLUE' ) as ROW_COLOR -- выделим перемещения синим шрифтом
from bdok
left join spost post on (post.id = bdok.idpost)
where ((bdok.data >= :data1 ) or (bdok.type_ = 1) or (bdok.reserve = 1))
-- по дате будем фильтровать только закрытые документы. А открытые и резервы - целиком,
-- иначе там набирается куча по жизни незакрытых документов
and (bdok.nsklad = :nsklad)
and (bdok.io = :io )
and (bdok.type_ = :type_ )
and ((post.idagent = :idagent) or (:idagent = -1))
and ((bdok.reserve = :reserve) or (:reserve = -1))
order by
data, idpost
no subject
no subject
no subject
(no subject)
(no subject)
(no subject)
no subject
no subject
Если вас размерчик не устраивает - ничем не могу помочь.
no subject
Написать запросы - 15% времени.
Закодировать - 25%
Постановка и уточнение задачи - 60%
ОРМ тут поможет в тех 25%, допустим ускорит в 2 раза, общее время практически не изменится.
Что такое "разработчик насладится игранием в explain и его адаптацией к конкретной ситуации" - я не понял.
В большинстве форм ее смысл заключен в запросе/запросах. Да, это надо тестить. Но 15% времени - это немного,
кроме того этот смысл в виде запроса легко достать из программы и проверить/отладить в IBEXpert. Там есть подсветка, и переход на объекты, каменты, всякая статистика, просмотр описаний, отслеживание зависимостей и т.п.
Кстати, стуктура БД - это практически основное, и любая форма отталкивается от данных, потом пишутся запросы и только потом это суем в программу.
Планы запроса от количества записей у меня вроде не менялись ни разу, ну или может пару раз за 15 лет. А вот при смене версии сервера головняков было побольше - и смена планов из-за изменения в оптимизаторе и необходимость переименовки некоторых полей которые стали совпадать с ключевыми словами сервера.
no subject
Вы как-то странно делаете вывод о моей скорости из описания процесса.
Написать запросы - 15% времени.
Закодировать - 25%
Постановка и уточнение задачи - 60%
ОРМ тут поможет в тех 25%, допустим ускорит в 2 раза, общее время практически не изменится.
Он поможет в 40 процентах. Так-как написание запросов может и не потребоваться.
В большинстве форм ее смысл заключен в запросе/запросах. Да, это надо тестить. Но 15% времени - это немного,
Вы бы про MVC почитали уже. Вы видимо даже как-то не в курсе что в случае ORM форма это и есть объект с данными.
кроме того этот смысл в виде запроса легко достать из программы и проверить/отладить в IBEXpert. Там есть подсветка, и переход на объекты, каменты, всякая статистика, просмотр описаний, отслеживание зависимостей и т.п.
Для crud операций? А смысл?
Кстати, стуктура БД - это практически основное, и любая форма отталкивается от данных, потом пишутся запросы и только потом это суем в программу.
Вы видимо меня плохо понимаете. У меня проектирование начинается с БД, а потом по ней генерится слой для работы с ней. В результате я сразу могу переходить к разработке приложения, в том числе минуя стадию отладить запрос вот для этой штуки. Когда таких запросов надо отладить больше 10 это мягко говоря утомительно и однообразно.
Планы запроса от количества записей у меня вроде не менялись ни разу, ну или может пару раз за 15 лет. А вот при смене версии сервера головняков было побольше - и смена планов из-за изменения в оптимизаторе и необходимость переименовки некоторых полей которые стали совпадать с ключевыми словами сервера.
У меня складывается ощущение, что в вашу программу изменения вносятся раз в пятилетку. При таком подходе работает какой угодно метод программирования.
no subject
Запрос select * from table в отладке не нуждается, а иных у вас после генерации и не будет.
no subject
no subject