UPDATE = DELETE (помечено как) + INSERT? - PullRequest
11 голосов

Это вопрос SQL Server, но я был бы признателен, если бы ответы были правильно определены в других контекстах СУБД.

Ответ Сета Линча на мой вопрос на форуме MSDN:

говорит:

"Когда данные обновляются, они не перезаписываются - исходная строка помечается как удаленная, а новая строка вставляется"

Это правильное утверждение? Можете ли вы дать ссылки, подтверждающие это в документах?
Как это можно проверить?

Похожие обсуждения:

Обновление: не так давно я считал, что грязное чтение разрешено на уровне изоляции транзакции READ UNCOMMITTED (или, что то же самое в SQL Server, через подсказку WITH (NOLOCK)), разрешено чтение (из других транзакций), незафиксированное (или зафиксированное) , если еще не изменены) значения, но не частично изменены (частично обновлены, частично удалены или частично вставлены.

RESUME ': короче говоря, эта фраза, как правило, и в большинстве случаев неверна (хотя в SQL Server категорически говорится о довольно редких случаях)

Ответы [ 3 ]

9 голосов
/ 27 ноября 2010

По словам Кален Делани, в своей книге Внутри Microsoft SQL Server 2005: механизм хранения , SQL Server 2005 (а теперь и 2008) может обновлять строку с помощью вставки / удаления или по месту просто изменив значение одного столбца. Вот краткое изложение того, что она говорит на с. 306-311 из книги.

Обычное поведение в SQL Server 2005/2008 - обновление строки на месте. Строка остается в том же месте на странице, и изменяются только затронутые байты. Примером этого может быть обновление значения в целочисленном столбце, который не является частью очищенного индекса.

Строка может обновляться с помощью вставки / удаления, когда ее размер изменяется, и она больше не помещается на исходной странице. Это может произойти, если вы измените значение в столбце varchar и увеличите его. Это также происходит, когда столбец кластеризованного индекса изменяется, и строка должна перемещаться из-за своей позиции в индексе (поскольку строки упорядочены по кластерному ключу). Примером этого может быть изменение чьей-либо фамилии с «Смит» на «Джонс» в таблице с кластеризованным индексом по фамилии.

2 голосов
/ 27 ноября 2010

Это зависит от реализации.

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

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

Подробности зависят от реализации. Некоторые системы будут использовать дельту до фиксации, а некоторые изменят строку, но сохранят копию оригинала для использования в случае отката.

1 голос
/ 28 ноября 2010

В Oracle UPDATE всегда меняет исходную строку. Старые значения строки записываются в журнал UNDO и остаются там в течение некоторого времени в рамках реализации многоконверсионного управления параллелизмом (MVCC).

Пока новые значения не зафиксированы, все другие транзакции будут получать старые значения из журнала UNDO. То же самое происходит, если ваш запрос был запущен до COMMIT новых значений или в определенных режимах изоляции транзакции.

Если новые значения больше и строка больше не помещается на той же странице, строка переносится на новую страницу, и место на старой странице освобождается.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...