Oracle
Comments 27
+4
никогда не делайте update всех колонок в таблице при изменении одного поля объекта
Угу, расскажите это разработчикам веб-интерфейсов.

А так, получилось отличное краткое содержание одной из книг T.Кайта.
+2
Угу, расскажите это разработчикам веб-интерфейсов.

А вы не пускайте их в разработку бизнес логики =)
+1
А причём тут бизнес логика? В любом случае надо проверять, какие поля изменились, а какие нет — хотите, сами мучайтесь, хотите — программиста. Только весь выигрыш эта проверка сведёт на нет.
0
Решается примитивно заменой стандартного браузерного алгоритма отправки формы на свой собственный, который собирает и отправляет только те данные, у которых defaultValue или defaultChecked отличается от текущего значения value или checked.

Алгоритм простой:
* при срабатывании события submit вызываем собственный обработчик и возвращаем false, дабы остановить процесс отправки данной формы
* в обработчике создаем клон данной формы и удаляем из нее все элементы, у которых значение не изменялось
* вставляем клон в дерево в какой-то невидимый контейнер
* вызываем метод submit у клонированной формы
* радуемся полученному результату

Никаких суперсложных проверок, алгоритм дубовый что двери.
0
«Алгоритм простой:


радуемся полученному результату»

Ага, но совсем недолго, ибо влетаем в проблему валидации в ситуациях с «Under-Posting» и «Over-Posting». Ну это так, к слову. Да и вообще как хак какой-то выглядит.

Как бы там ни было, до базы должны реально доходить изменения, которые действительно нужны. Тут веб или не веб — не суть важно. Важен уровень разработчика и его уверенность в том, что он делает.
0
Конечно.

Допустим, у меня есть форма, у которой есть обязательные поля:
— Имя
— Фамилия
— Возраст
— Email

Все поля обязательны. Плюс, существует какая-нибудь проверка, что, допустим, имя должно быть не менее 2 символов в длину.

Входящая View-Model (Input-Model, если быть точным) проверяется в данном с использованием так называемого «Model Validation» (когда проверяются данные всей модели, а не только полей, которые мы запостили).

И я делаю пост только значений фамилии и email. Не найдя полей «имя» и «возраст», валидатор посылает модель к монахам, говоря, что они не соответствуют правилам валидации (отмечены как обязательные, но их нет во входящей модели).

Ремарка: я использую строгие Input-Model'и как раз для избежания ситуаций с over-posting и under-posting (то есть, чтобы нельзя было создать потенциально невалидную модель с «недостаточными» данными и нельзя было «хакнуть» систему, запостив данные, которые нельзя обновить в текущем контексте).
+1
Суть понятна. Вы проверяете данные на валидность несколько раз в разных местах.

Если разделять логику INSERT и UPDATE, то порционное обновление все же можно построить. Когда данных в базе нет, использовать логику полной валидации модели. На UPDATE можно использовать проверку только тех данных, что пришли, потому что в базе хранится уже проверенная модель.

Хотя согласен, с точки зрения простоты решения вариант порционных данных не сильно выгоден, придется изменять логику построения кода.
0
Ну Partial Editing это тоже один из сценариев. И да, для простоты он тоже обычно оформляется в виде отдельной, «кастрированной» Input-Model'и. В данном случае обновляется все равно строго определенный набор полей, просто меньший. Разумеется, от этого никуда не деться в основных сценариях. Но зато модель целостная и постинг полностью контролируем.

Поддерживать подход для всех сочетаний всех полей с ручной проверкой наличия-отсутствия получается очень «дорого». На практике чаще всего куда проще пожертвовать «ненужным апдейтом» пары лишних полей в пользу серьезного упрощения системы в целом, а поддерживать постинг одного-двух-трех наборов данных для одной сложной сущности.
0
Полностью поддерживаю. В любом случае мы имеем проблему «stale data». То есть, мы не можем сравнивать значения с исходными в уже загруженной форме, мы обязаны после POST-инга формы выбрать все из базы и сравнить в таком случае.

И да, когда мы точно знаем что обновить нужно ровно одно поле — мы так и делаем, а не обновляем всю запись.
0
Дайте им интерфейс в виде процедур, так проще поддерживать логику, а проверки можно делать уже в процедурах
+2
Спасибо, очень полезная статья, иногда приходится работать с Oracle, теперь буду знать про пустые поля =)
+2
Отличная статья, спасибо! Вы меня заинтересовали, особеннно про «невозможность грязного чтения» благодаря версионности. Такой возможности мне очень не хватает в tsql, и приходится обращаться к «необходимости грязного чтения», чтобы не терять производительность из-за блокировки записей при чтении.
UFO landed and left these words here
-1
Статья интересная, спасибо!
Пара замечаний от штурмбанфюрера:
«при потери» -> «при потере»
«впросак» -> «в просак»
0
Странно, по правилам, если есть слово «просак», то писать «впросак» — не правильно. Ну буду знать :-)
+4
Настолько попсовая статья у вас получилась, что даже грустно стало. Много неточностей, как терминологических так и смысловых, есть и просто ляпы. На половину сделанных категоричных утверждений можно возразить «it depends». Из всей этой поверхностной статьи реальной пользы для разработчика — чуть. Разве что про связываемые переменные, и то, для многих это скрыто фреймворками.
Поэтому минус.
Oracle, к сожалению, настолько монструозно сложная штука, что туда нужно нырять очень глубоко, чтобы доставать какие-то жемчужины.

Если вы читали Кайта, почему бы не взять с него пример. он пишет понятно, лаконично, интересно, но при этом максимально корректно. Хотя, судя по оборотам «бинарные индексы» и «бинарные мапы» вы читали его не в подлиннике, в а одном из г… переводов, если так, то вы себя очень обделили. Нормально переводил Кайта только один переводчик, и сейчас я к сожалению не вспомню, кто именно.

P. S. «Пауза ожидания» — это состояние, которое проявляется на морде лица после употребления пищи еды.
0
Спасибо за критику, поставил вам плюсик за коммент.

Во многом согласен с Вашими комментариями, правда, не понятно, зачем Вы полезли под кат, если уже читали книгу Кайта. В хабре не хватает возможности указать уровень аудитории на которую рассчитана статья: begginer, intermediate, expert… Хотя, конечно, в большинстве случаев можно указывать это явно в начале текста.

Да, что и говорить до Тома мне далеко, не поспоришь.
Все обороты — это в большинстве случаев отсебятина, а не подхваченные словечки из кривых переводов. Уж простите, но я на великого литератора я не претендую.
У Кайта по всему этому написана целая книга, а у меня только короткий топик, поэтому написать обо всем конкретно в таком формате попросту невозможно, о чем я и упомянул в заключении, если Вы дочитали до него.
По поводу категоричных утверждений тоже с Вами согласен, где-то я пытался вставлять слова «в большинстве случаев» и «скорее всего», но в большинстве случаев, неверное, опустил. Связано это с тем, что я описывал основной случай, а на исключения места уже не хватало, и так обо всем очень кратко писал.

Буду очень признателен, если укажете конкретно на смысловые ляпы.
+2
Статья, да, не совсем точная, но все же полезная.
По неточностям — чтение далеко не всегда идет через кэш. В 10g при параллелизации запроса параллельные сервера читают напрямую из датафайлов миную кэш. В 11g все еще как-то кручу в плане выбора, грузить в кэш или нет.
Про логирование индексов — это все играет роль только в момент построения индекса либо direct insert (insert с хинтом append либо параллельный insert). Для одиночных вставок всегда все логируется.
Про потерю данных и nologging — при обычном крэше данные потерять невозможно, только если придется по какой-то причине восстанавливать файл из бэкапа на момент до начала nologging операции и накатываться…
0
Спасибо Женя.

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

Про NO_LOGGING я конечно дал маху, по правде говоря никогда не использовал на практике, но всегда хотел. Вообще удалил абзац про него.

Про потерю данных и nologging — не нашел, честно говоря, где я писал про это. Да с Вами абсолютно согласен, что при обычно крэше ничего не потерять. Разве что во время крэша сломался еще и диск на который журнальный файл писался (если только он не писался параллельно на несколько дисков), в этом случае можно потерять немного последних изменений, но совсем немного, разумеется.
+1
>В Oracle, в отличие от многих других БД, даже если в середине вашего запроса другая транзакция переведет некоторую суммы с первого счета на последний, вы в итоге все равно получите данные актуальные на начало вашего запроса, так как дойдя до последний строчки ваш SELECT увидит, что строчка была изменена, пойдет в сегмент отката и прочитает данные, которые были в этой ячейке на момент начала выполнения запроса. Во многих других базах данных, вы получите ответ в виде суммы, никогда не существующей в вашей таблице.

Это называется стабильныv курсор и есть они почти во всех субд, из тех, где его нет (но можно добиться хитрым селектом с сортировкой) я знаю только firebird

Ну и как вы себе представляете работу в таких субд, если по вашему примеру при нескольких пользователях всегда будут кривые суммы…
0
>Это называется стабильныv курсор

С точки зрения программиста это называется согласованным чтением, которое достигается путем уровня изоляции REPEATABLE_READ. Но Вы правы я забыл упомянуть одну очень важную деталь, что другие БД (в которых нет внутренней поддержки версионности на уровне операторов по умолчанию) получат кривые суммы только в случае уровня изоляции READ_COMMITTED, который и выбирается в большинстве случаев.

В других БД, чтобы получать всегда согласованный результат придется выставлять уровень REPEATABLE_READ, который они обычно достигают путем выставления строчных разделяемых блокировок чтения, которые, могут легко приводить к дедлокам. Например, если в описанном случае во время чтения большой таблицы одной транзакцией, другая транзакция попытается перевести деньги с последней строчки в первую и выставлен уровень REPEATABLE_READ, то и получиться дедлок.

Мнения о других БД я взял из книжки Тома Кайта 2005 года, так что возможно «многие другие БД» к сегодняшнему моменту уже перешли на поддержку версионности данных и построчными блокировками на чтение больше не балуются. Если кто знает, напишите в комментарии плиз.
0
аккуратнее с использованием pl/sql функций в запросах, они имеют противную особенность работать в своем уровне изоляции и сумма таки может разойтись
Only those users with full accounts are able to leave comments., please.