发布网友 发布时间:2023-03-12 16:40
共1个回答
热心网友 时间:2023-10-18 13:43
第 章 多用户环境
数据库并不是一个孤岛 可以想象这样的场景 一个或多个用户都在访问数据库 所有的修改和保存都按照一种正确的顺序执行 不会陷入混乱 在现实中 创建数据库通常都是为了实现多人共享数据 即使对于桌面型数据库 Microsoft Access和OpenOffice BASE 也可以通过网络进行共享 RDBMS服务器本身就是专门设计用于支持多用户环境的
当一个以上的用户访问同一个数据集时 一些新的问题就产生了 哪些数据应该对于每一个用户都可见呢?谁的修改应该具有优先权?在执行一个较长的数据库过程期间 用什么保证数据的修改不会丢失?为了找到这些问题(以及很多其他问题)的答案 下面将介绍会话 事务和锁的概念
上面的这些问题可以用RDBMS的术语重新表述为
事务为潜在的数据一致性问题提供了解决方案
锁用于处理数据的并发性问题
会话代表了事务和锁存在的上下文环境
会话
在RDBMS服务器和访问它的一个用户之间发生的任何通信过程都是发生在一个会话的上下文环境中 可以将会话视为一个唯一的通道 它仅为你打开 供你访问数据 或者在桌面型数据库的情形下 例如Microsoft Access和OpenOffice BASE 就是专属于你自己的一个数据文件的副本 当你连接到数据库并通过认证时 RDBMS将为你自动创建一个会话
在多用户环境中 令人担忧的问题之一就是数据的完整性 当一个客户端应用程序建立了一个到RDBMS服务器的连接时 称为 打开了一个会话 会话就是该应用程序与服务器进行通信的私有通道 在会话期间 用户可能修改了一些首选项(例如默认语言或默认数据格式) 这些设置仅影响到当前这个特定的用户环境 并且仅仅只在该会话期间有效 各种RDBMS对会话的实现细节和会话的默认行为可能有所差异 但这些基本的原则是保持一致的
本书中使用的工具都是客户端在会话上下文中访问RDBMS服务器的例子 对于桌面型数据库则有所不同 例如Microsoft Access文件 它既可以作为数据存储使用 也可以包含很多通常与应用程序相关的对象 例如表单 报表等(有很多办法可以将这些功能划分到前端和后端文件中) 对于Microsoft Access 会话就是打开的mdb/accdb文件的一个本地副本 在使用完之后必须将其合并回 主 文件(关于这一话题的更多内容 请参考有关Microsoft Access的专业出版物)
OpenOffice BASE的架构与Microsoft Access不同 从本质上讲 OpenOfficeBASE被设计为一个桌面型的通道 为任何支持JDBC驱动程序的数据库提供一个前端 它内置的HSQLDB数据库引擎是一个默认的选择 嵌入版本的OpenOffice BASE并未设计用于多用户环境
RDBMS为各自的RDBMS服务器都提供了一些命令行工具 这是所有RDBMS的共同特性 所有RDBMS都提供了一个图形化的用户界面(GUI) 另外还有很多第三方工具 关于这些工具的更多信息 请参考附录C和附录D的内容
SQL标准定义了很多参数 可以使用这些参数来连接数据库 并在会话期间保持这些参数 RDBMS已经实现了其中绝大部分参数 尽管在某些元素的实现上使用了私有的语法 但是只是语法形式的不同 本质是一样的
在Oracle中 为了建立一个数据库连接 用户必须具有系统特权CREATESESSION;要想修改会话的参数 用户必须具有ALTER SESSION特权 在初始时 会话的所有默认参数都是从一个特殊的Oracle配置文件中加载的 只有数据库管理员或者具有必要特权的人才能修改这个配置文件 一旦连接建立之后(即创建了会话) 用户就可以根据自己的偏好和工作的要求修改会话的参数
IBM DB 为会话环境提供了非常少的用户控制 它提供了一个SET SESSION AUTHORIZATION语句(遵循SQL标准)和一个等效的SET SESSION_USER语句 用于修改会话的上下文
SETPASSTHRU语句为会话提供了最直接的控制 它可以为将SQL数据直接提交到数据库打开和关闭一个会话 另外 在会话期间创建的全局临时表将使用SESSION组件作为限定的模式(在临时表的名称与某个永久表的名称相同的情况下 避免在访问表时出现歧义)
当客户端终止了一个会话 自发地终止会话或异常地终止会话 为会话设置的所有参数都将消失 此外 对于所有悬而未决的事务 在客户端自发地终止会话的情况下将执行一个隐式的提交 在会话异常终止的情况下将执行一个回滚
数据库管理员(DBA)可以杀死或断开一个会话 但在各个RDBMS中执行该命令的语法存在一定的差别
试一试修改会话参数
Microsoft SQL Server 提供了大量的语句 可以修改当前会话的设置 这些语句并不是SQL标准的一部分 实际上它们是Transact SQL方言的一部分 下面的例子将修改其中一个设置 ANSI_NULLS 并查看该设置对查询输出的影响
( ) 打开Microsoft SQL Server Management Studio Express 连接到LIBRARY数据库
( )下面的语句用于从LIBRARY数据库的PHONE表中获取所有BK_PRICE字段不为NULL的记录
SET ANSI_NULLS ON
GO
SELECT bk_title
FROM books
WHERE bk_price <> NULL
GO
( row(s) affected)
( ) 尽管实际上可以料想到 LIBRARY数据库中的所有图书都具有相应的价格 表中一定存在满足这一条件的记录 但是该查询却没有返回任何记录
( ) 清除查询窗格中的内容 输入新的SQL批语句 如下所示
SET ANSI_NULLS OFF
GO
SELECT bk_title
FROM books
WHERE bk_price<> NULL
GO
BK_TITLE
SQL Bible
Steppenwolf
示例说明
由于NULL并不是一个特殊的值 它是一个 表示缺少值的占位符 因此对NULL值应该区别对待 SQL 标准强制要求凡是涉及NULL值的比较操作总是返回FALSE 把MicrosoftSQL Server 的ANSI_NULLS参数调整为ON将指示数据库遵循这一标准 但Oracle / g和IBM DB 都没有类似于ANSI_NULLS这样的设置
如果使用更为标准的ISNULL语法 就可以完全避免这一情况
SELECT bk_title
FROM books
WHERE bk_price IS NOT NULL
在所有RDBMS中 上面这个查询都可以返回正确的结果
返回目录 SQL实战新手入门
编辑推荐
Oracle索引技术
高性能MySQL
lishixin/Article/program/SQL/201311/16452