数据库中的万圣节问题(Database "Halloween problem")
2012-05-28 20:27
381 查看
参考文献:
1.What is the Halloween Problem in databases?2.Halloween Problem
3.Table scans to avoid the Halloween problem
4.数据库索引实例
正文
今天在看《数据库系统概念》这本书的查询优化章节,在其中的第13.6.3节中提到了万圣节问题(Halloween problem)。这是一个挺有意思的问题,不过现在已经不存在这样的问题了,大多数数据库管理系统都为我们解决了这样的问题。不过我们可以来看看这个万圣节问题到底是什么。在1976年的万圣节那一天,IBM的两位程序要需要修改数据库库中内容,其所对应的业务内容是“给所有工资小于25000的员工加薪百分之十”,他们运行的sql语句如下:
UPDATE EMP_TABLE SET SALARY=SALARY*1.1 WHERE SALARY<25000
但是他们执行完这条语句以后发现了一个大问题,那就是数据库中所有员工的工资都至少为25000。后来发现出现这样的结果的主要问题是:所有工资小于25000的哪些记录被无限次数得加薪了百分之十,直到工资大于等于25000为止。
如果更新操作是在选择操作扫描索引的执行过程中完成,一个更新的元组可能会在扫描之前和扫描之后重复插入索引两次;同一个元素的元素可能不正确地更新多次(在上述情况下会更新多次直到工资大于等于25000为止)。上述更新操作本身可能影响自己执行的问题称为万圣节问题(Halloween problem)。在前面的博客:数据库索引实例中我们提到,如果我们在一个字段上创建了索引,那么元组会按照索引进行排序。假如我们在之前的EMP_TABLE表中的SALARY字段上创建了所以呢,那么每次更新SALARY字段都会更新索引,然后对元组的位置进行调整。假设原本数据库中有三个员工信息,内容如下:
1 张三 2000 2 李四 2100 3 王五 2300
然后执行工资增加10%的操作,在更新第一条记录(1 张三 2000)以后,这三条记录在数据库中的存储位置如下:
2 李四 2100 1 张三 2200 3 王五 2300
然后继续更新第二条记录(2 李四 2100),更新以后三条数据库记录的位置如下所示:
1 张三 2200 3 王五 2300 2 李四 2310
这一次我们需要再一次更新(1 张三 2200)这条记录,那么这一条记录就更新了多次。这也是造成万圣节问题的根本原因所在。
如果更新不影响索引属性,则万圣节问题不会发生。即使影响索引属性,如果更新减小该值,而索引扫描以升序执行,更新过的元素在扫描时不会再遇到。在这种情况下,查询执行的同时可以更新索引。
不过现在的数据库管理系统基本解决了万圣节问题,不会再出现上述情况,不过具体的解决方法是什么,我还有待研究。
举例
我们以数据库索引实例的示例来进行说明,假设一张表emp_pay(employeeID, base_pay, commission),其中在base_pay上加了索引,因此最后查询结果以base_pay的升序显示,查询结果如下;然后我们执行一个加薪的sql,让所有工资大于100的员工加薪10%,那么假设存在万圣节问题,那么employeeID为7的员工可能会出现多次加薪,但是当我们执行下述sql以后,发现并没有出现万圣节问题:
UPDATE emp_pay SET base_pay=base_pay*1.1 WHERE base_pay>100
进行加薪以后我们再次执行查询语句,查询结果如下:
从上述查询结果我们可以发现,每个员工都只加工了一次。这也说明在现在的关系数据库中,数据库管理系统已经帮我们解决了万圣节问题。
相关文章推荐
- 数据库中的万圣节问题(Database "Halloween problem")
- 使用FMDB多线程访问数据库 及databaseislocked的问题
- JSP和Servlet连接数据库 登陆验证ResultSet.getString("power")空指针问题
- 解决vs2010“创建或打开C++浏览数据库文件 发生错误”的问题"
- 使用FMDB多线程访问数据库,及database is locked的问题
- asp + Access 常见的数据库访问失败问题 Microsoft JET Database Engine 错误 '80004005' 解决办法
- Sql Server 2008 出现"provider:命名管道提供程序,error:40"问题,无法登录数据库
- 可空类型"int?" 解决: 【数据库里的int类型可以为null,而在c#里int类型不能为Nul】的问题
- ADO.NET Entity framework 中 实体的对应数据库中text类型的问题 (更新) :asp.net entity 传入的表格格式数据流(TDS)远程过程调用(RPC)协议流不正确。参数 3 ("@0"): 数据类型 0
- 如何解决数据保存数据库后出现中文变"?"的问题
- FMDB多线程下"is currently in use" 或者 "database is locked" 问题
- VS下QT插件 连接数据库出现error LNK2019: 无法解析的外部符号QSqlDatabase问题解决
- 安装cm初始脚本配置数据库scm_prepare_database.sh(在主节点上)遇到的问题
- asp + Access 常见的数据库访问失败问题 Microsoft JET Database Engine 错误 '80004005' 解决办法
- 数据库连接问题之:Caused by: java.sql.SQLException: Connections could not be acquired from the underlying database!
- jsp数据库连接中"无效的描述符索引"问题的解决
- [Database] Oracle: Oracle 9i 数据库乱码(字符集)问题解决方案
- vs.net2008在开发环境下调试没有问题,发布后运行却提示"无法更新数据库,因为数据库是只读的"
- sql-"无法删除数据库,因为该数据库当前正在使用"问题解决
- JSP和Servlet连接数据库 登陆验证ResultSet.getString("power")空指针问题