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