介绍 FileTable 如何使用 SQL Server 的其他功能。
AlwaysOn 可用性组和 FileTable
当包含 FILESTREAM 或 FileTable 数据的数据库属于 AlwaysOn 可用性组时:
AlwaysOn 可用性组部分支持 FileTable 功能。 故障转移后,主副本上可访问 FileTable 数据,但在可读次要副本上无法访问 FileTable 数据。
注释
请注意,故障转移后,将全面支持所有 FILESTREAM 功能。 FILESTREAM 数据可在可读次要副本和新主副本上访问。
FILESTREAM 和 FileTable 函数接受或返回虚拟网络名称 (VNN),而非计算机名称。 有关这些函数的详细信息,请参阅 Filestream 和 FileTable 函数(Transact-SQL)。
通过文件系统 API 对 FILESTREAM 或 FileTable 数据进行的所有访问都应该使用 VNN,而非计算机名称。 有关详细信息,请参阅具有 AlwaysOn 可用性组的 FILESTREAM 和 FileTable(SQL Server)。
分区和 FileTable
FileTable 不支持分区。 借助对多个 FILESTREAM 文件组的支持,可以处理纯纵向扩展问题,而无需在大多数情况下使用分区(与 SQL 2008 FILESTREAM 不同)。
复制和 FileTable
FileTable 不支持复制和相关功能(包括事务复制、合并复制、更改数据捕获和更改跟踪)。
事务语义和 FileTable
Windows 应用程序
Windows 应用程序不了解数据库事务,因此 Windows 的写入操作不具备数据库事务的 ACID 属性。 因此,Windows 更新操作无法执行事务回滚和恢复。
Transact-SQL 应用程序
对于处理 FileTable 中 FILESTREAM (file_stream) 列的 TSQL 应用程序,隔离语义与常规用户表中的 FILESTREAM 数据类型相同。
查询通知和 FileTable
查询不能包含对 FileTable 中 FILESTREAM 列的引用,无论是在 WHERE 子句中还是在查询的任何其他部分。
SELECT INTO 和 FileTables
FileTable 中的 SELECT INTO 语句不会在创建的目标表上传播 FileTable 语义(就像常规表中的 FILESTREAM 列一样)。 所有目标表列的行为就像普通列一样。 它们不会具有任何与 FileTable 相关联的语义。
触发器和 FileTable
DDL (数据定义语言) 触发器
对于具有 FileTable 的 DDL 触发器,没有特殊注意事项。 对于创建/修改数据库操作以及 FileTable 的创建/修改 TABLE 操作,将触发正常的 DDL 触发器。 触发器可以通过调用 EVENTDATA() 函数来检索包含 DDL 命令文本和其他信息的实际事件数据。 现有 Eventdata 架构没有新事件或更改。
DML (数据操作语言)触发器
在 DDL 操作期间将强制实施这些限制以创建触发器。
FileTables 不支持用于 DML 操作的 INSTEAD OF 触发器。 这是对包含 FILESTREAM 列的所有表的现有限制。
FileTable 将支持用于 DML 操作的 AFTER 触发器。
在 FileTable 上定义的触发器无法更新任何 FileTable(包括父 FileTable)。 存在此限制主要是为了防止触发器在同一事务中与文件系统访问所持有的锁发生锁定冲突。
非事务性访问及其对触发器的影响
在数据库中允许非事务性更新访问时,可以就地更新任何表中的 FILESTREAM 数据,包括该数据库中的 FileTable。 由于这种可能性,FILESTREAM 内容的先前映像可能无法被触发器使用。
对于通过文件系统进行的非事务性更新操作,SQL Server 将创建一个内部事务来捕获 CloseHandle 操作,并且定义的任何 DML 触发器可能会作为该事务的一部分被触发。 在触发器主体中回滚此类事务,虽然未被禁止,但不会回滚对 FILESTREAM 已进行的修改。 此类回滚也可能阻止更新触发器被触发,即使 FILESTREAM 内容可能已更改。
除了这些影响之外,FileTable 上的触发器还需要处理几个其他行为
如果通过文件系统对 FileTable 执行非事务性更新操作,可能会被其他 Win32 操作独占锁定 FILESTREAM 内容,并且无法通过触发器主体进行读/写访问。 在这种情况下,任何尝试访问触发器正文中的 FILESTREAM 内容都可能导致“共享冲突”错误。 应将触发器设计为适当地处理此类错误。
在某些情况下,FILESTREAM 的后映像可能不稳定,因为可能会同时被其他非事务性更新主动写入(由于文件系统访问中允许的共享模式)。
Win32 句柄的异常终止(例如管理员或数据库崩溃的 Win32 句柄的显式终止)不会在恢复作期间执行用户触发器,即使 FILESTREAM 内容可能已被异常终止的 Win32 应用程序更改。
视图和 FileTable
视图
可以在 FileTable 上创建视图,就像在任何其他表上一样。 但是,以下注意事项适用于在 FileTable 上创建的视图:
视图将没有任何 FileTable 语义。 例如,视图中的列(包括文件属性列)的行为与普通视图列类似,没有任何特殊语义,表示 Files/directory 的行也是如此。
视图可能基于“可更新视图”语义进行更新,但基础表约束可以拒绝更新,就像在表中一样。
通过将文件作为显式列添加到视图中,可以在视图中可视化文件路径。 例如:
CREATE VIEW MP3FILES AS SELECT column1, column2, ..., GetFileNamespacePath() AS PATH, column3,... FROM Documents
索引视图
当前,索引视图不能包含 FILESTREAM 列,或计算/持久化计算列,而这些计算列依赖于 FILESTREAM 列。 此行为即便在 FileTable 上定义的视图中也保持不变。
快照隔离和 FileTable
读取已提交的快照隔离(RCSI)和快照隔离(SI)依赖于能够在数据被更新操作时仍然为读取者提供数据快照的功能。 但是,FileTable 允许对 Filestream 数据进行非事务性写入访问。 因此,以下限制适用于在包含 FileTable 的数据库中使用这些功能:
可以更改包含 FileTable 的数据库以启用 RCSI/SI。
当数据库的 non_transactional 访问被设置为 FULL 时,在 RCSI 或 SI 下运行的事务表现如下:
文件表 file_stream 列的任何 Transact-SQL 读取失败。 插入和更新到该列仍然可以成功,只要它们不从文件流列读取。
如果 Transact-SQL 语句指定了 READCOMMITTEDLOCK 表提示,则读取操作会成功,并锁定数据行,而不是使用行版本化。
事务化 Win32 FileStream 打开请求也会失败。
非事务处理 FileTable Win32 访问成功。 FileTable 执行的所有内部查询都不会受到影响。
无论数据库选项是什么(READ_COMMITTED_SNAPSHOT或ALLOW_SNAPSHOT_ISOLATION),全文索引过程总是会成功。
可读辅助数据库
与快照相同的注意事项适用于可读的辅助数据库,如前一节中所述,快照隔离和 FileTables。
包含的数据库和 FileTable
FileTable 功能所依赖的 FILESTREAM 功能需要数据库外部的某些配置。 因此,使用 FILESTREAM 或 FileTable 的数据库不是完全独立的。
如果要使用包含的数据库的某些功能(如包含的用户),可以将数据库包含设置为 PARTIAL。 但是,在这种情况下,必须注意,某些数据库设置不包含在数据库中,并且不会在数据库移动时自动移动。