这是SQL Server的问题,但我希望其他DBMS上下文能够正确识别这些答案。

赛斯·林奇在msdn论坛上回答我的问题:

讲述:

“更新数据时,不会过度写入-原始行标记为已删除,并插入新行。”

这是正确的说法吗?你能在文档中提供支持这一点的参考资料吗?
如何验证?

相关讨论:

更新:不久前,我认为在read uncommitted事务隔离级别(或者,在SQL Server中是相同的,通过with(nolock)提示)允许读取(来自其他事务)未提交(或者提交,如果尚未更改)的值,但没有部分更改。(部分更新、部分删除或部分插入。

简历:简而言之,这个短语通常是不正确的,而且在大多数情况下都是不正确的(尽管它对SQL Server中非常不常见的情况进行了分类说明)。

3 回复  |  直到 14 年前
    1
  •  9
  •   DataWriter Leon Bambrick    14 年前

    根据卡伦·德莱尼的说法,在她的书中 在Microsoft SQL Server 2005内部:存储引擎 ,SQL Server 2005(现在是2008)可以通过使用插入/删除或就地更新行,只需更改一列的值。这是她在本书第306-311页上所说的一个简短的总结。

    SQL Server 2005/2008中的正常行为是就地更新一行。该行在页面上保持相同的位置,并且只更改受影响的字节。这方面的一个例子是更新一个整数列中的值,该列不是Cultered索引的一部分。

    当行的大小发生变化且不再适合原始页时,可以使用插入/删除来更新行。当您更改varchar列中的值并使其变长时,可能会发生这种情况。当聚集索引列正在更改,并且由于行在索引中的位置(因为行是由聚集键排序的)需要移动时,也会发生这种情况。例如,在姓氏上有聚集索引的表中,将某人的姓氏从“smith”更改为“jones”。

        2
  •  2
  •   fredt    14 年前

    这取决于实现。

    通常,当使用多版本同构控制(MVCC)时,会保留原始行。它要么被删除它的事务标记为已删除,并创建替换行,要么在事务上下文的其他位置存储增量,直到事务提交并将增量应用到现有行。

    在基于锁的并发控制中,可以就地更改行,因为只有单个事务可以读写该行。

    细节取决于实现。有些系统在提交之前将使用增量,有些系统将更改行,但保留原始的副本以备回滚时使用。

        3
  •  1
  •   Codo    14 年前

    在Oracle中,更新总是更改原始行。该行的旧值将写入撤消日志,并作为多版本并发控制(MVCC)实现的一部分保留一段时间。

    只要未提交新值,所有其他事务都将从撤消日志中获取旧值。如果查询是在提交新值之前或在某些事务隔离模式下启动的,则会发生同样的情况。

    如果新值较大,并且该行不再适合同一页,则该行将迁移到新页,并释放旧页上的空间。