WinFS
WinFS(全名为Windows Future Storage)[1]是以关系数据库为基础之数据保存与管理系统的代号名称,它由微软开发,在2003年首次用于Windows中的高端保存子系统,它针对结构化、半结构化与未结构化数据的保存与管理用途而设计。WinFS包含可用于保存信息的关系数据库,而且可保存任何类型的数据,前提是数据类型已有完整定义的结构描述。接着,便可通过关系来创建个别数据项目之间的关联,这样系统便可根据特定属性作参照,用户也可明确地描述属性作参照。此外,因数据具完整定义的结构描述,任何应用程序均可重复使用数据;而且通过使用关系,可有效率地组织与截取相关数据。因系统知道信息的结构与用途,故可作复杂的查找,以达成数据的高端搜索,并通过探索数据项目之间的关系来汇整各种不同的数据项目。
WinFS与其共用类型结构描述可让应用程序识别不同的数据类型,但仍需撰写应用程序以转译不同的数据类型。因此,WinFS并不适合用来开发可查看或编辑所有数据类型的单一应用程序;其目的是让应用程序能了解所有数据的结构并截取信息以作进一步处理。在2003专业开发人员大会,微软首度介绍WinFS,并发布了视频演示文稿,名为IWish[2],此视频演示文稿提供的原型接口显示应用程序如何公开接口以得益于统一类型系统。视频中展示的概念包含应用程序如何使用数据项目之间的关系来动态筛选选项,及应用程序如何将多个相关数据组成群组并以统一方式呈现数据。
WinFS是众多“Longhorn”技术的基础,而且将包含在下一版本的Windows中。原本WinFS应在Windows Vista发行后提供,但相关计划在2006年6月搁置,然而其某些组件技术已集成到即将发行的ADO.NET与Microsoft SQL Server[3]。某些评论家指WinFS项目已完成,但史蒂夫·鲍尔默在2006年11月曾公开称WinFS仍在开发,至于此技术将以何种方式提供仍未知[4]。
动机
许多常见操作系统中的文件系统(包括近年众多Windows 版本中使用的NTFS)都将文件与其他对象保存为比特流,且这些文件系统对文件中所存数据内容通常并不知道。此类文件系统也只有一种组织文件的方式(具体而言是通过目录与文件名称)[5][6]。
因文件系统完全不知其所存数据[5],应用程序常使用本身的文件格式(通常为专属格式)。这阻碍在多个应用程序之间共用的数据。创建可处理来自多种文件类型之信息的应用程序变得很困难,因程序员须了解所有文件的结构与语意[7]。使用常见文件格式是解决此问题的暂时方案,但非治本;因无法确保所有应用程序都会使用预期的格式。具有标准化结构描述的数据(例如,XML文档与关联式数据)无此问题,因为它们具有标准化的结构与运行阶段需求[8]。
此外,传统文件系统只能根据文件名称来截取与搜索数据,因为它对数据所知的范围仅限于用保存数据之文件名称[7]。较好的解决方案是使用属性为文件加上标记(tag),此处所谓的属性可描述文件内容。属性是有关文件的中继数据,如文件类型(例如:文档、图片、音乐、创建者等)[5]。这样可让系统依属性(而非使用文件夹阶层)来搜索文件(例如:寻找“包含人员X的图片”)。文件系统本身即可识别属性,或通过某些延伸模块来识别属性[5]。桌面搜索应用程序进一步采用此概念。它们会从文件截取数据(包含属性)并为文件编制索引。为了截取数据,它们为每种文件格式使用一个筛选器。这样就可依文件属性与文件中所包含的数据来搜索文件[5]。
但是,这仍不足以协助管理相关数据,因为不同的项目之间并未定义任何关系(例如:无法搜索“住在墨西哥阿卡波可市、在我的相片集中出现超过一百次、且我最近一个月曾经与其有过电子邮件往来的所有人员的电话号码”)。若要完成这种搜索,必须要一种同时定义语意与数据关系的数据模型[5][6]。WinFS的目的是提供这样的数据模型与运行阶段基础结构,以便保存数据与数据项目之间的关系(根据数据模型),同时以尽量不影响性能的方式完成此动作。
概观
WinFS可识别各种类型的数据,例如:图片、电子邮件、文档、音频、视频、行事历、连络人等;不像文件系统只能识别比特流。由系统保存与管理的数据是WinFS运行阶段所识别之数据类型的运行个体。数据结构的基础是属性。例如,履历类型的运行个体将通过公开特定属性(例如姓名、教育程度、工作经验等)来描述数据。属性的类型可能是字符串、整数或日期等简单类型,或连络人之类的复杂类型[7][9]。不同的数据类型会公开不同的属性。此外,WinFS也允许不同的数据运行个体与彼此关联,例如您可以利用作者关系来创建文档与连络人之间的关联[6][9]。关系也会公开为属性,例如若文档是通过创建者关系与连络人关联,则文档将具有创建者属性。当文档被访问时,系统会侦测到该关系并传回相关数据[9]。借由依循该关系即可截取所有相关数据[6]。

WinFS通过让所有应用程序访问数据类型与其结构描述的方式来达成应用程序之间的数据共用[7]。因此当任何应用程序想要使用WinFS类型时,可以使用结构描述来了解数据的结构,并有效利用信息。因此,即使开发人员并未撰写剖析器来识别不同的数据格式,应用程序也可以访问系统上的所有数据。它也可以使用关系与相关数据来创建动态筛选器,以不同的方式呈现应用程序所处理的信息。WinFS API进一步将数据的访问工作抽象化。所有WinFS类型都公开为.NET 对象,而对象的属性则直接对应到数据类型的属性[5]。此外,通过让处理相同数据的不同应用程序共用相同的WinFS数据运行个体,而非将相同的数据保存为不同的文件格式,系统管理员便不需要在数据发生变更时同步不同的存放区[10]。因此WinFS可协助避免数据重复保存的情形[5][8]。
通过访问系统中所有数据的能力,您可以创建复杂的搜索来寻找由WinFS所管理之所有数据项目中的数据。在上述范例(“住在墨西哥阿卡波可市、在我的相片集中出现超过一百次、且我最近一个月曾经与其有过电子邮件往来的所有人员的电话号码”)中,WinFS可以周游所有相片的主体关系以寻找连络人项目。同样地,它也可以筛选最近一个月的电子邮件并访问通信对象关系以与连络人联系。接着,系统便可以从上述两个搜索结果中找出适当的连络人,并通过访问连络人项目的适当属性来截取其电话号码。
除了完全语意化的数据(如同XML与关联式数据)之外,WinFS也支持半结构化数据(例如影像,影像具有未结构化的比特数据流与结构化的中继数据)以及未结构化数据(例如文件)。它可将未结构化的组件直接保存为文件,同时将结构化的中继数据保存在结构化的存放区中[9]。WinFS在内部使用关系数据库来管理数据。但是,它不会将数据限制为属于任何特定数据模型,例如关联式或阶层式,而且它可以是任何已完整定义的结构描述。WinFS运行阶段会将结构描述对应到关联式特征(modality)[5],方式是定义将保存类型的数据表,以及重新呈现关系时所需的主索引键与外部索引键。WinFS缺省包含对象与XML结构描述的对应;至于其他结构描述的对应,则必须另行指定。对象结构描述是使用XML来指定;WinFS会产生脚本以将结构描述公开为.NET 类别。您可以使用ADO.NET直接指定关联式结构描述,虽然您必须提供对象结构描述的对应以将它以类别方式公开[9]。所有关系周游动作都是在这些数据表上以Joins方式运行。WinFS也会自动在这些数据表上创建索引,以便应用程序可以更快速地访问信息[9]。索引可大幅加快Joins的速度,因此周游关系以截取相关数据的动作非常快。搜索信息时也会使用索引;搜索与查找会使用索引,因此操作可以快速完成,这跟桌面搜索软件很类似。
发展
WinFS的开发是1990年代早期计划之功能的延续,此功能称为对象文件系统(Object File System,简称OFS),它原本应该包含在Cairo项目中。OFS被认为应该具有强大的数据汇整功能[11]。但Cairo项目当时遭搁置,因此OFS也被延宕。但是,稍后在开发COM时,规划了一个称为Storage+(以后来发行的SQL Server 8.0为基础)的保存系统,Storage+预期应提供类似的汇整功能[11]。但是,这项计划也没有实现,而类似的技术关联式文件系统(Relational File System,RFS)据信将在SQL Server 2000中提供[11]。但是,SQL Server 2000最后只是对于SQL Server 7.0进行些许更新,但并未实作RFS。
但此概念从未被忘却[11]。因此才有WinFS的出现。WinFS原本预计包含在Windows Vista中[13],以及后来代号名称为“Longhorn”的Windows Vista 组建4051(此版本在2003年的微软专业开发者大会公开发布),但当时WinFS有严重的性能问题[11]。在2004年8月,微软宣布WinFS将不会内置于Windows Vista;而是会在Vista正式发行后以可下载的更新方式提供[11]。
在2005年8月29日,微软悄悄地将WinFS Beta 1提供给MSDN订户。该版本可以在Windows XP运行,而且需要.NET Framework才能运行。WinFS API包含在“System.Storage”命名空间中[11][14]。该Beta版本在2005年12月1日更新,以与.NET Framework 2.0兼容[15]。WinFS Beta 2预计在2006年末推出[16],而且预期会与Windows桌面搜索集成,因此搜索结果会包含来自一般文件与WinFS存放区的结果;此外,您可以使用ADO.NET来访问WinFS数据[17] 。
但是,在2006年6月23日,微软的WinFS团队宣布将不再以独立产品方式提供WinFS[3],而且某些组件将以其他技术提供 - 例如对象关系映射组件至ADO.NET Entity Framework;支持未结构化数据、操作的无管理模式、通过FILESTREAM数据类型支持文件系统对象,以及SQL Server 2008(代号名称为“Katmai”)中的阶层式数据[18][19],以及与Win32API及Windows Shell集成,以及在未来的Microsoft SQL Server版本中通过周游关系以支持阶层的周游[18];以及将组件同步到Microsoft Sync Framework[18]。但是尚未排除在Windows的未来版本中内置WinFS的情况[18]。
微软宣布此消息之后,大部分评论分析家均认为WinFS项目已遭放弃。但在2006年11月,鲍尔默在一场会议中说明WinFS仍在开发中,但要等到技术成熟时才会集成到Windows代码基础。2006年12月,比尔盖兹的会议证实此消息,而且微软计划移植Windows Media Player、Windows Photo Gallery、Microsoft Outlook等应用程序以使用WinFS做为数据保存后端[20]。
2013年,比尔盖兹称WinFS项目的搁置是他对微软最大的失望,并且认为WinFS已经超越了时代[21]。
数据存放区
架构

WinFS不是实体文件系统;相反,它在NTFS文件系统之上提供系统化的数据模型建构能力。它仍使用NTFS在实体文件中保存其数据[11]。WinFS使用从SQL Server 2005[22]衍生的关联式引擎来提供数据关系机制。WinFS存放区仅是已设置FILESTREAM属性的SQL Server数据库(.MDF)文件[23]。这些文件是保存在磁盘区根目录下名为“System Volume Information”的文件夹(此文件夹具有限制的访问权)下的"WinFS"子文件夹中,其名称为这些存放区的GUID。[23]
WinFS 堆栈的底层是WinFS Core,它会与文件系统交互并提供文件访问与寻址能力[7]。关联式引擎使用WinFS内核服务来提供结构化的存放区与其他服务(例如:锁定将使用哪个WinFS运行阶段来实作该功能。WinFS运行阶段会公开服务(例如:同步处理与规则),其可用于同步处理WinFS存放区或在发生特定事件时运行特定动作[7]。
WinFS是以服务的方式运行,此服务会运行三个处理进程[24] - 装载关联式数据存放区的WinFS.exe、装载索引编制与查找引擎的WinFSSearch.exe以及与底层文件系统交互的WinFPM.exe (WinFS File Promotion Manager)。您可以利用一组.NET Framework API来撰写程序以访问其功能,这些.NET Framework API可让应用程序定义自订数据类型、定义数据之间的关系、保存与截取信息,以及实作高端搜索[5][7]。接着应用程序可以汇整数据,并将数据呈现给用户。
数据存放区
WinFS将数据保存在关联式存放区中,这些存放区会公开为虚拟位置,称为“存放区”[11]。WinFS存放区是通用存放库,任何应用程序都可以在其中保存数据,以及中继数据、数据关系与结构描述。WinFS运行阶段本身可以套用特定的数据关系;例如,若图片的“subject”属性与连络人的“name”属性相同,则WinFS可以在该连络人与该图片之间创建关联[25]。数据之间的关系也可以由其他应用程序或用户指定[26] 。
WinFS提供一致性的存放区,但无法定义将保存于存放区之数据的格式。但是,它支持以应用程序支持的特定格式写入数据。前提是应用程序必须提供结构描述,以定义解译文件格式的方式[5]。例如,您可以添加结构描述以让WinFS知道如何读取(甚至是进一步搜索或分析)特定文件格式,例如PDF文件。通过使用结构描述,任何应用程序都可以读取由其他应用程序所创建的数据,而且不同的应用程序也可以通过共用结构描述以其他应用程序支持的格式来写入数据[26]。
您可以在一部电脑上创建多个WinFS存放区[26]。这样可以独立保存不同类别的数据,例如,您可以将公司文档与私人文档保存在不同的存放区中。根据缺省,WinFS只提供一个存放区,其名称为“DefaultStore”[11]。WinFS存放区是公开为壳层(shell)对象(类似虚拟文件夹),此对象会动态产生存放区中的项目清单,并以文件夹查看方式呈现这些项目。利用壳层对象也可以搜索数据存放区中的信息[11]。
数据单位是以WinFS项目的方式保存在WinFS存放区中[5][26]。WinFS项目与内核数据项目亦包含数据项目与其他数据之关联的信息。此“关联”是以逻辑链接的方式保存。链接指的是目前的项目与哪些数据项目关联。换句话说,链接是用以指定数据与其他数据项目的关系。链接实体上是以链接识别码来保存,此识别码指定数据关联的名称与用途,例如,“所属类型”或“组成要素”[5]。链接识别码是保存为数据项目的属性(attribute)。具有相同链接识别码的所有对象将被视为相关对象[5]。您必须事先将XML结构描述(定义将保存在WinFS中之数据项目的结构)提供给WinFS运行阶段[5]。在WinFS的Beta 1版本中,您必须先将结构描述组件添加到GAC,才能开始使用结构描述。
数据模型
WinFS模型数据会使用数据项目、其关联、延伸(extension)与规则来规范其使用方式[7]。WinFS必须知道数据项目的类型与结构,才能将数据项目中保存的信息提供给要求该信息的应用程序。这是通过使用结构描述来完成。对于即将保存在WinFS中的每种数据项目类型,您必须提供对应的结构描述,以定义数据的类型、结构与关联。这些结构描述是使用XML来定义[5]。
预先定义的WinFS结构描述不仅包含文档、电子邮件、约会、工作、媒体、音频、视频等的结构描述;也包含系统结构描述,其中包括组态、程序与其他系统相关数据[7]。如果要让应用程序在WinFS中保存数据,但不想与其他应用程序共用该数据的结构,或这些数据可跨系统提供,则可以针对个别应用程序定义自订结构描述[7]。
类型系统

文件系统与WinFS之间最大的差异在于WinFS知道其所保存之每个数据项目的类型。类型会指定数据项目的属性(property)。WinFS类型系统与.NET Framework的类别与继承概念紧密关联。通过延伸与嵌套化任何预先定义的类型,即可创建新类型[5]。
WinFS提供四种预先定义的基础类型– Items、Relationships、ScalarTypes与NestedTypes[5]。Item是可保存的基础数据对象,而Relationship则是两个数据项目之间的关系或链接。因为所有WinFS项目都必须具有类型,保存之项目的类型会定义其属性(property)。Item的属性可以是ScalarType(定义属性可包含之信息的最小单位)或NestedType(多个ScalarTypes和/或NestedTypes的集合)。所有WinFS类型都以.NET CLR 类别的方式提供[26]。
任何以数据单位(例如:连络人、影像、视频或文档等)所代表的对象都可以保存在WinFS存放区中做为Item类型的特殊项[26]。根据缺省,WinFS为文件、连络人、文档、图片、音频、视频、连络人与邮件提供Item类型。文件Item可以保存任何一般数据,这在文件系统中是保存为文件。但除非为文件提供高端结构描述(通过将它定义为特殊化的Item),WinFS将无法访问其数据。此类文件Item仅能支持与其他Item相关联[5]。

开发人员可以扩充这些类型或基础类型Item,以为其自订数据提供类型。Item中包含的数据是以属性或实际保存数据的字段来定义。例如,连络人Item可能包含类型为ScalarType的Name字段,以及类型为NestedType(进一步由两个ScalarType组成)的Address字段。为定义此类型,会扩充基础类别Item,而且会添加必要字段至该类别[5]。NestedType字段可定义为包含两个ScalarType字段的另一个类别。一旦定义类型,就必须定义结构描述以表示每个字段的原始类型,例如Name字段的类型是String、Address字段是自订的Address类别,每个字段的类型都是String。WinFS支持的其他原始类型包括Integer、Byte、Decimal、Float、Double、Boolean与DateTime等[5]。结构描述也会定义哪些字段为必要字段,哪些字段为选用字段[27]。系统会使用以此方式定义的连络人Item来保存有关连络人的信息,方式是填入属性字段并予以保存。首次保存时只需要填入标示为必要的字段。[26]其他字段可在稍后由用户填入,或完全不填入。若需要添加多个字段(例如:“上次交谈日期”),只要视需要简单地扩充此类型即可。您可以使用相同的方式定义其他数据的Item类型。

WinFS会为所有已定义的Item创建数据表[27]。为Item定义的所有字段会构成数据表的数据栏,而每个对应Item的Item实体则会保存为数据表的数据列。当数据表中的某些字段参照某些其他数据表中的数据时,即表示这些数据表之间有特定的关系存在。关系的结构描述会指定相关的数据表有哪些,以及关系的种类与名称。WinFS运行阶段负责管理关系结构描述[26]。所有Item都会公开为.NET CLR 对象,此对象具有统一的接口,可让应用程序轻松访问字段中保存的数据。因此,任何应用程序都可以截取具有任何Item类型的对象,而且可以使用该对象中的数据,而不需要了解字段中保存之数据的实际结构[5]。
WinFS类型是公开为.NET类别,它可以具现化为.NET对象。通过设置属性即可在这些类型中保存数据。完成之后,它们变会永久保存至WinFS存放区。使用ItemContext类别即可访问WinFS存放区。ItemContext允许以交易式方式访问WinFS存放区,例如,从将ItemContext对象绑定到存放区到因为全部成功而关闭或所有变更都已复原。当数据发生变更时,它们不会写入到磁盘;而是会写入到内存内的记录。只有当连接关闭时,变更才会以批量方式写入磁盘。这样可协助优化磁盘I/O[9]。下列代码片段会创建连络人并保存在WinFS存放区中。
//Connect to the default WinFS store
using(ItemContext ic = ItemContext.Open())
{
//Create the contact and set the data in appropriate properties
ContactEAddress contact = new ContactEAddress();
//Name is a ComplexType
contact.Name = new PersonName();
contact.Name.Displayname = "Doe, John";
contact.Name.FirstName = "John";
contact.Name.LastName = "Doe";
//Telephone number is a ComplexType
contact.TelephoneNumber = new TelephoneNumber(); //ComplexType
contact.TelephoneNumber.Country = CountryCode.Antarctica;
contact.TelephoneNumber.Areacode = 4567;
contact.TelephoneNumber.Number = 9876543210;
//Age is a SimpleType
contact.Age = 111;
//Add the object to the user's personal folder.
//This relates the item with the Folder pseudo-type, for backward
//compatibility, as this lets the item to be accessed in a folder
//hierarchy for apps which are not WinFS native.
Folder containingFolder = UserDataFolder.FindMyPersonalFolder();
containingFolder.OutFolderMemberRelationship.AddItem(ic, contact);
//Find a document and relate with the document. Searching begins by creating an
//ItemSearcher object. Each WinFS type object contains a GetSearcher() method
//that generates an ItemSearcher object which searches documents of that type.
using(ItemSearcher searcher = Document.GetSearcher(ic))
{
Document d = searcher.Find(@"Title = 'Some Particular Document'");
d.OutAuthoringRelationship.AddItem(ic, contact);
}
//Since only one document is to be found, the ItemContext.FindOne() method
//could be used as well.
//Find a picture and relate with it
using(ItemSearcher searcher = Picture.GetSearcher(ic))
{
Picture p = searcher.Find(@"Occasion = 'Graduation' and Sequence = '3'");
p.OutSubjectRelationship.AddItem(ic, contact);
}
//Persist to the store and close the reference to the store
ic.Update();
ic.Close();
}
参考文献
- . [2007-05-04]. (原始内容存档于2007-09-30).
- . Microsoft. [2007-07-03]. (原始内容存档于2006-06-02).
- Quentin Clark. . What's in Store. MSDN Blogs. June 23, 2006 [2006-06-23]. (原始内容存档于2010-03-05).
- . [2007-06-30]. (原始内容存档于2012-11-10).
- Shawn Wildermuth. . MSDN. [2007-06-30]. (原始内容存档于2008-04-20).
- Vijay Bangaru. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-06-09).
- Sean Grimaldi. . MSDN. [2007-06-30]. (原始内容存档于2007-09-13).
- Thomas Rizzo. . MSDN. [2007-06-30]. (原始内容存档于2007-09-16).
- . [2007-07-04].
- Vijay Bangaru. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-07-08).
- Paul Thurrott. . [2007-06-30]. (原始内容存档于2007-07-02).
- . [2008-01-25]. (原始内容存档于2007-10-31).
- Cath Everett. . ZDNet. [2007-06-30]. (原始内容存档于2010-03-12).
- . NTFS.com. [2007-07-04]. (原始内容存档于2007-07-03).
- Vijay Bangaru. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-05-20).
- Shan Sinha. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-03-08).
- Sanjay Anand. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-07-09).
- Quentin Clark. . [2008-05-17]. (原始内容存档于2008-05-17).
- Quentin Clark. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-07-03).
- Daniel Kornev. . Channel 9. 2006-12-19.
- . www.theregister.com. 2013-02-12 [2020-09-23]. (原始内容存档于2021-12-09) (英语).
- Nate Mook. . BetaNews. [2007-07-02]. (原始内容存档于2008-07-06).
- Shishir Mehrotra. . Professional Developers Conference 2005 presentations. Microsoft. September 2005 [2006-05-22]. (原始内容存档于2006-01-06).(Currently offline, mirror (页面存档备份,存于)).
- Erwyn van der Meer. . [2007-07-03]. (原始内容存档于2007-06-09).
- Vijay Bangaru. . WinFS Team Blog. [2007-06-30]. (原始内容存档于2007-05-22).
- Richard Grimes. . MSDN Magazine. [2007-06-30]. (原始内容存档于2007-06-27).
- Shawn Wildermuth. . MSDN. Microsoft. July 2004 [2007-06-30]. (原始内容存档于2008-04-04).
外部链接
- WinFS Blog
- WinFS at the Microsoft Developer Network
- Channel 9 Videos
- WinFS Newsgroup
- WinFS Beta 1 Review
- WinFS area on NetFXGuide.com