2010-11-27 4 views
11

Это вопрос SQL Server, но я был бы признателен за правильность определения ответов на другие контексты СУБД.UPDATE = DELETE (помечено как) + INSERT?

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

говорит:

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

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

Связанные дискуссиях:

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

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

+0

Это обновит поля AUTO_INCREMENT? – 2010-11-27 12:57:38

ответ

9

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

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

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

2

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

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

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

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

+0

Какая у вас ссылка? В своем обсуждении обновлений на месте (стр. 309) Делани пишет: «Кроме того, журнал будет содержать одну запись для каждой такой обновленной строки, если в таблице нет триггера обновления или не помечены для репликации. В этих случаях, обновление все еще происходит, но журнал будет содержать запись удаления, за которой следует запись вставки ». – DataWriter 2010-11-27 14:34:10

+0

Обсуждаете ли вы Oracle, Фредт? – DataWriter 2010-11-27 14:40:39

1

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

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

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

Смежные вопросы