表上的DELETE操作
在今天的文章里,我想给你快速展示下当我们从表里删除记录时,在SQL Server里发生了什么。首先我们来创建一个简单的表,在8KB的页上刚好能插入4条记录。
-- Create a simple table where 4 records fit onto 1 page
CREATE TABLE TestTable
(
Col1 INT IDENTITY(1, 1),
Col2 CHAR(2000)
)
GO
接下来我们插入4条记录,这样的话一个页刚好全部填满。
-- Insert 4 records
INSERT INTO TestTable VALUES
(
REPLICATE('', 2000)
),
(
REPLICATE('', 2000)
),
(
REPLICATE('', 2000)
),
(
REPLICATE('', 2000)
)
GO
为了研究我们堆表的细节,我们使用DBCC PAGE命令来倾倒出分配的页面。因此我们还要启用3604跟踪标志,这样的话SQL Server从DBCC PAGE命令直接把结果输入到我们SSMS的会话窗口:
-- Enable the Trace Flag 3604
DBCC TRACEON(3604)
GO
我们可以使用DBCC IND命令返回所有分配给指定表或索引的页:
-- Retrieve all pages of the table
DBCC IND(DataModifications, TestTable, -1)
GO
从输出可以看到,2个页属于我们的表:数据页本身,还有IAM(索引分配图(index allocation map))页。
我这里的页号是118,通过DBCC PAGE命令倾倒出页面:
-- Dump out one specific page
DBCC PAGE (DataModifications, 1, 118, 2)
GO
当你使用选项2的第3个参数倾倒,SQL Server返回你16进制的页倾倒,包括在页尾所谓的行偏移数组(Row Offset Array),不以任何方式影响数据。
行偏移数组指向在页上的物理位置,即每条记录存储的地方。第1条记录总是直接存储在页头偏移量96(0x60h)的地方。你也会看到,行偏移数组是逆向增长的。现在让我们从表里删除第2条记录:
-- Delete a record from the table
DELETE FROM TestTable
WHERE Col1 = 2
GO
通常这里你会期待记录从页里删除。但事实上并不如此:当你再次执行DBCC PAGE命令时,你会看到在页上老记录的内容还是可以看到。在DELETE操作期间,SQL Server唯一做的是,在页尾行偏移数组里,对应的槽无效了。
如你所见,第2个槽的偏移量是0x0,这是无效的,意味着我们的记录被删除了。在页开始部分,你总会找到96 bytes的页头。现在让我们从表里删除其它的剩余3条记录。
-- Delete all the remaining records from the table
DELETE FROM TestTable
GO
当你再次用DBCC PAGE命令查看页,你会看到页全部内容还是没改变:每条记录的每个数据在页上还是物理存在的!但是在行偏移数据里每条记录都指向偏移量0x0,这意味着每条记录都被删除。这与你的表是否使用了聚集索引无关——老数据在页上一直存在。
现在的问题是,SQL Server什么时候会初始化页?当你现在插入新的记录,SQL Server会覆盖页的原始内容。但在我们的情况里,这只是物理部分,第1条记录存储的位置。你还是能看到其它“删除”的记录内容。当你在页尾看下行偏移数组,你会看到它已被SQL Server完全初始化了,也意味着你在行偏移数组里你现在只有1个槽了:
当你下次授权给程序sysadmin特权时,要考虑下这个情况了。使用合适的命令,这些程序还是能看到已经“删除”的数据。
感谢关注!
参考文章:
https://www.sqlpassion.at/archive/2014/02/11/delete-operations-on-tables/
表上的DELETE操作的更多相关文章
- 在SqlServer2008R2中,在一张表上加上insert、update、delete触发器(带游标)
在日常工作中,在SqlServer2008R2中,需要向一张表上加上触发器,监控插入.更新.删除. --一个触发器内三种INSERT,UPDATE,DELETE状态 IF exists(select ...
- 背景:表A数据误操作,被delete了,恢复。
SELECT MAX(Scn) FROM Sys.Smon_Scn_Time WHERE Time_Dp < TO_DATE('2015-09-18', 'YYYY/MM/DD') select ...
- 请求部署在 IIS7.5 上的 REST 服务的 Put/Post/Delete 操作发生 HTTP Error 405.0 - Method Not Allowed 错误之解决
背景 请求部署在 IIS7.5 上的 REST 服务的 Put/POST/DELETE 操作发生 HTTP Error 405.0 - Method Not Allowed 错误. Issue 解决 ...
- MySQL的数据库,数据表,数据的操作
数据库简介 概念 什么是数据库?简单来说,数据库就是存储数据的"仓库", 但是,光有数据还不行,还要管理数据的工具,我们称之为数据库管理系统! 数据库系统 = 数据库管理系统 + ...
- PostgreSQL连接python,postgresql在python 连接,创建表,创建表内容,插入操作,选择操作,更新操作,删除操作。
安装 PostgreSQL可以用Python psycopg2模块集成. sycopg2是Python编程语言的PostgreSQL数据库的适配器. 其程序代码少,速度快,稳定.不需要单独安装这个模块 ...
- MySql常用操作语句(2:数据库、表管理以及数据操作)
本文主要内容转自一博文. 另外可供参考资源: SQL语句教程 SQL语法 1.数据库(database)管理 1.1 create 创建数据库 mysql> create database f ...
- 一起学HBase——总结HBase中的PUT、GET、DELETE操作
传统的关系型数据库有CRUD增删改查操作,同样对于NoSQL列式数据库也有CRUD操作.本文对HBase中常用的Scan.GET.PUT.DELETE操作的用法做个总结. Put操作 Put相当于传统 ...
- veridata实验举例(4)验证veridata查找出updata、delete操作导致的不同步现象
veridata实验举例(4)验证veridata查找出updata.delete操作导致的不同步现象 续接:<veridata实验举例(3)验证veridata查找出insert操作导致的不同 ...
- Go语言学习教程:xorm表基本操作及高级操作
在上节内容中,我们介绍了xorm框架表结构的映射规则和表结构的操作.本节课,继续来深入学习表结构基本操作和高级查询的相关功能. 表结构基本操作 对表结构的操作最常见的操作是查询和统计相关的方法,我们首 ...
随机推荐
- C++/Php/Python/Shell 程序按行读取文件或者控制台
写程序经常需要用到从文件或者标准输入中按行读取信息,这里汇总一下.方便使用 1. C++ 读取文件 #include<stdio.h> #include<string.h> i ...
- Dom4J解析xml文件动态转换为List<Bean>或者Map集合
大家在解析大量相似xml文件的时候是否会遇到这样一个问题:冗余的代码去set定义的实体对象Bean的值,基本都是一样的操作 而且毫无任何代码价值可言所以在这写了一个简单的例子,类封装了几个方法你只 ...
- Asp.Net customErrors与httpErrors的区别
先看一下简单的对比 customErrors Asp.Net级别的错误处理程序,只处理Asp.Net应用抛出的异常(404,403,500..) 在IIS7+的服务器依然可用(IIS7之前就引进了) ...
- 轻松搞定面试中的二叉树题目(java&python)
树是一种比较重要的数据结构,尤其是二叉树.二叉树是一种特殊的树,在二叉树中每个节点最多有两个子节点,一般称为左子节点和右子节点(或左孩子和右孩子),并且二叉树的子树有左右之分,其次序不能任意颠倒.二叉 ...
- BW CUBE 数据的聚集和压缩
大家都知道,压缩和聚集都是提高bw性能的方法,在新版bw里,压缩名称改成了折叠,聚集放在了滚动菜单里---集合.那么我们在使用这两种方法时需要注意的先创建聚集以后,再进行压缩,因为压缩的过程是把F表的 ...
- MySQL、PostgreSQL、Ingres r3、MaxDB等开源数据库的详细比较
1.MySQL 5 作为当今最流行的开放源码数据库之一,MySQL数据库为用户提供了一个相对简单的 解决方案,适用于广泛的应用程序部署,能够降低用户的TCO.MySQL是一个多线程.结构化查询语言(S ...
- Android学习笔记----TimerTask中显示Toast的问题
今天想在TimerTask的run函数中调用Toast显示一下提示信息,却总是导致程序崩溃.可是try语句块却又无法捕获到异常,代码如下: ...... Timer timer = new Timer ...
- tomcat java.net.BindException: Cannot assign requested address 解决方法
今天线上TOMCAT启动时遇到了下比较麻烦的问题,错误如下: 21-Apr-2016 15:14:19.077 SEVERE [main] org.apache.catalina.core.Stand ...
- CentOS 7.2 搭建 Ghost 博客
因为平时记录一些文档或想法基本使用 markdown 的语法,Mac 下推荐一款 markdown 的编辑器 Haroopad:上周无意发现 Ghost 有支持 Mac 的桌面版本了,并且同样开源 h ...
- 云服务器 ECS Linux 系统盘数据转移方法
转自:https://help.aliyun.com/knowledge_detail/41400.html 问题描述 购买云服务器 ECS Linux 服务器时,未购买数据盘,使用一段时间后,随着业 ...