WinFS

**WinFS**（全名為 **Windows Future Storage**）是以關聯式資料庫為基礎之資料儲存與管理系統的代號名稱，它由微軟開發，在 2003 年首次用於 Windows 中的進階儲存子系統，它針對結構化、半結構化與未結構化資料的儲存與管理用途而設計。WinFS 包含可用於儲存資訊的關聯式資料庫，而且可儲存任何類型的資料，前提是資料類型已有完整定義的結構描述。接著，便可透過關係來建立個別資料項目之間的關聯，這樣系統便可根據特定屬性作參照，使用者也可明確地描述屬性作參照。此外，因資料具完整定義的結構描述，任何應用程式均可重複使用資料；而且透過使用關係，可有效率地組織與擷取相關資料。因系統知道資訊的結構與用途，故可作複雜的查詢，以達成資料的進階搜尋，並透過探索資料項目之間的關係來彙整各種不同的資料項目。

WinFS 與其共享類型結構描述可讓應用程式識別不同的資料類型，但仍需撰寫應用程式以轉譯不同的資料類型。因此，WinFS 並不適合用來開發可檢視或編輯所有資料類型的單一應用程式；其目的是讓應用程式能瞭解所有資料的結構並擷取資訊以作進一步處理。在 2003 專業開發人員大會，微軟首度介紹 WinFS，並發佈了視訊簡報，名為 IWish，此視訊簡報提供的原型介面顯示應用程式如何公開介面以得益於統一類型系統。視訊中展示的概念包含應用程式如何使用資料項目之間的關係來動態篩選選項，及應用程式如何將多個相關資料組成群組並以統一方式呈現資料。

WinFS 是眾多「Longhorn」技術的基礎，而且將包含在下一版本的 Windows 中。原本 WinFS 應在 Windows Vista 發行後提供，但相關計畫在 2006 年 6 月擱置，然而其某些元件技術已整合到即將發行的 ADO.NET 與 Microsoft SQL Server。某些評論家指 WinFS 專案已完成，但史蒂夫・巴爾默在 2006 年 11 月曾公開稱 WinFS 仍在開發，至於此技術將以何種方式提供仍未知。

## 動機

許多常見作業系統中的檔案系統（包括近年眾多 Windows 版本中使用的 NTFS）都將檔案與其他物件儲存為位元流，且這些檔案系統對檔案中所存資料內容通常並不知道。此類檔案系統也只有一種組織檔案的方式（具體而言是透過目錄與檔案名稱）。

因檔案系統完全不知其所存資料，應用程式常使用本身的檔案格式（通常為專屬格式）。這阻礙在多個應用程式之間共享的資料。建立可處理來自多種檔案類型之資訊的應用程式變得很困難，因程式設計師須瞭解所有檔案的結構與語意。使用常見檔案格式是解決此問題的暫時方案，但非治本；因無法確保所有應用程式都會使用預期的格式。具有標準化結構描述的資料（例如，XML 檔案與關聯式資料）無此問題，因為它們具有標準化的結構與執行階段需求。

此外，傳統檔案系統只能根據檔案名稱來擷取與搜尋資料，因為它對資料所知的範圍僅限於用儲存資料之檔案名稱。較好的解決方案是使用屬性為檔案加上標記（tag），此處所謂的屬性可描述檔案內容。屬性是有關檔案的中繼資料，如檔案類型（例如：_檔案、圖片、音樂、建立者_等）。這樣可讓系統依屬性（而非使用資料夾階層）來搜尋檔案（例如：尋找「_包含人員 X 的圖片_」）。檔案系統本身即可識別屬性，或透過某些延伸模組來識別屬性。桌面搜尋應用程式進一步採用此概念。它們會從檔案擷取資料（包含屬性）並為檔案編製索引。為了擷取資料，它們為每種檔案格式使用一個篩選器。這樣就可依檔案屬性與檔案中所包含的資料來搜尋檔案。

但是，這仍不足以協助管理相關資料，因為不同的項目之間並未定義任何關係（例如：無法搜尋「_住在墨西哥阿卡波可市、在我的相片集中出現超過一百次、且我最近一個月曾經與其有過電子郵件往來的所有人員的電話號碼_」）。若要完成這種搜尋，必須要一種同時定義語意與資料關係的資料模型。WinFS 的目的是提供這樣的資料模型與執行階段基礎結構，以便儲存資料與資料項目之間的關係（根據資料模型），同時以儘量不影響效能的方式完成此動作。

## 概觀

WinFS 可識別各種類型的資料，例如：_圖片_、_電子郵件_、_檔案_、_音訊_、_視訊_、_行事曆_、_連絡人_等；不像檔案系統只能識別位元流。由系統儲存與管理的資料是 WinFS 執行階段所識別之資料類型的執行個體。資料結構的基礎是屬性。例如，_履歷_類型的執行個體將透過公開特定屬性（例如_姓名_、_教育程度_、_工作經驗_等）來描述資料。屬性的類型可能是_字串_、_整數_或_日期_等簡單類型，或_連絡人_之類的複雜類型。不同的資料類型會公開不同的屬性。此外，WinFS 也允許不同的資料執行個體與彼此關聯，例如您可以利用_作者_關係來建立檔案與連絡人之間的關聯。關係也會公開為屬性，例如若檔案是透過_建立者_關係與連絡人關聯，則檔案將具有_建立者_屬性。當檔案被存取時，系統會偵測到該關係並傳回相關資料。藉由依循該關係即可擷取所有相關資料。

WinFS 透過讓所有應用程式存取資料類型與其結構描述的方式來達成應用程式之間的資料共享。因此當任何應用程式想要使用 WinFS 類型時，可以使用結構描述來瞭解資料的結構，並有效利用資訊。因此，即使開發人員並未撰寫剖析器來識別不同的資料格式，應用程式也可以存取系統上的所有資料。它也可以使用關係與相關資料來建立動態篩選器，以不同的方式呈現應用程式所處理的資訊。WinFS API 進一步將資料的存取工作抽象化。所有 WinFS 類型都公開為.NET 物件，而物件的屬性則直接對應到資料類型的屬性。此外，透過讓處理相同資料的不同應用程式共享相同的 WinFS 資料執行個體，而非將相同的資料儲存為不同的檔案格式，系統管理員便不需要在資料發生變更時同步不同的存放區。因此 WinFS 可協助避免資料重複儲存的情形。

透過存取系統中所有資料的能力，您可以建立複雜的搜尋來尋找由 WinFS 所管理之所有資料項目中的資料。在上述範例（ _「住在墨西哥阿卡波可市、在我的相片集中出現超過一百次、且我最近一個月曾經與其有過電子郵件往來的所有人員的電話號碼」_ ）中，WinFS 可以周遊所有相片的_主體_關係以尋找_連絡人_項目。同樣地，它也可以篩選最近一個月的電子郵件並存取_通訊物件_關係以與連絡人聯繫。接著，系統便可以從上述兩個搜尋結果中找出適當的連絡人，並透過存取連絡人項目的適當屬性來擷取其電話號碼。

除了完全語意化的資料（如同 XML 與關聯式資料）之外，WinFS 也支援半結構化資料（例如影像，影像具有未結構化的位元資料流與結構化的中繼資料）以及未結構化資料（例如檔案）。它可將未結構化的元件直接儲存為檔案，同時將結構化的中繼資料儲存在結構化的存放區中。WinFS 在內部使用關聯式資料庫來管理資料。但是，它不會將資料限制為屬於任何特定資料模型，例如關聯式或階層式，而且它可以是任何已完整定義的結構描述。WinFS 執行階段會將結構描述對應到關聯式特徵（modality），方式是定義將儲存類型的資料表，以及重新呈現關係時所需的主索引鍵與外部索引鍵。WinFS 預設包含物件與 XML 結構描述的對應；至於其他結構描述的對應，則必須另行指定。物件結構描述是使用 XML 來指定；WinFS 會產生指令碼以將結構描述公開為.NET 類別。您可以使用 ADO.NET 直接指定關聯式結構描述，雖然您必須提供物件結構描述的對應以將它以類別方式公開。所有關係周遊動作都是在這些資料表上以 Joins 方式執行。WinFS 也會自動在這些資料表上建立索引，以便應用程式可以更快速地存取資訊。索引可大幅加快 Joins 的速度，因此周遊關係以擷取相關資料的動作非常快。搜尋資訊時也會使用索引；搜尋與查詢會使用索引，因此操作可以快速完成，這跟桌面搜尋軟體很類似。

## 發展

WinFS 的開發是 1990 年代早期計畫之功能的延續，此功能稱為**物件檔案系統（Object File System，簡稱 OFS）** ，它原本應該包含在 Cairo 專案中。OFS 被認為應該具有強大的資料彙整功能。但 Cairo 專案當時遭擱置，因此 OFS 也被延宕。但是，稍後在開發 COM 時，規劃了一個稱為 **Storage+**（以後來發行的 SQL Server 8.0 為基礎）的儲存系統，Storage + 預期應提供類似的彙整功能。但是，這項計畫也沒有實現，而類似的技術**關聯式檔案系統（Relational File System，RFS）** 據信將在 SQL Server 2000 中提供。但是，SQL Server 2000 最後只是對於 SQL Server 7.0 進行些許更新，但並未實作 RFS。

但此概念從未被忘卻。因此才有 WinFS 的出現。WinFS 原本預計包含在 Windows Vista 中，以及後來代號名稱為「Longhorn」的 Windows Vista 組建 4051（此版本在 2003 年的微軟專業開發者大會公開發布），但當時 WinFS 有嚴重的效能問題。在 2004 年 8 月，微軟宣布 WinFS 將不會內建於 Windows Vista；而是會在 Vista 正式發行後以可下載的更新方式提供。

在 2005 年 8 月 29 日，微軟悄悄地將 WinFS Beta 1 提供給 MSDN 訂戶。該版本可以在 Windows XP 執行，而且需要.NET Framework 才能執行。WinFS API 包含在「System.Storage」命名空間中。該 Beta 版本在 2005 年 12 月 1 日更新，以與.NET Framework 2.0 相容。WinFS Beta 2 預計在 2006 年末推出，而且預期會與 Windows 桌面搜尋整合，因此搜尋結果會包含來自一般檔案與 WinFS 存放區的結果；此外，您可以使用 ADO.NET 來存取 WinFS 資料 。

但是，在 2006 年 6 月 23 日，微軟的 WinFS 團隊宣布將不再以獨立產品方式提供 WinFS，而且某些元件將以其他技術提供 - 例如物件關係對映元件至 ADO.NET Entity Framework；支援未結構化資料、操作的無管理模式、透過 FILESTREAM 資料類型支援檔案系統物件，以及 SQL Server 2008（代號名稱為「Katmai」）中的階層式資料，以及與 Win32API 及 Windows Shell 整合，以及在未來的 Microsoft SQL Server 版本中透過周遊關係以支援階層的周遊；以及將元件同步到 Microsoft Sync Framework。但是尚未排除在 Windows 的未來版本中內建 WinFS 的情況。

微軟宣布此訊息之後，大部份評論分析家均認為 WinFS 專案已遭放棄。但在 2006 年 11 月，巴爾默在一場會議中說明 WinFS 仍在開發中，但要等到技術成熟時才會整合到 Windows 程式碼基礎。2006 年 12 月，比爾蓋茲的會議證實此訊息，而且微軟計畫移植 Windows Media Player、Windows Photo Gallery、Microsoft Outlook 等應用程式以使用 WinFS 做為資料儲存後端。

2013 年，比爾蓋茲稱 WinFS 專案的擱置是他對微軟最大的失望，並且認為 WinFS 已經超越了時代。

## 資料存放區

### 架構

WinFS 不是實體檔案系統；相反，它在 NTFS 檔案系統之上提供系統化的資料模型建構能力。它仍使用 NTFS 在實體檔案中儲存其資料。WinFS 使用從 SQL Server 2005 衍生的關聯式引擎來提供資料關係機制。WinFS 存放區僅是已設定 FILESTREAM 屬性的 SQL Server 資料庫（.MDF）檔案。這些檔案是儲存在磁碟區根目錄下名為「System Volume Information」的資料夾（此資料夾具有限制的存取權）下的 "WinFS" 子資料夾中，其名稱為這些存放區的 GUID。

WinFS 堆疊的底層是 **WinFS Core**，它會與檔案系統互動並提供檔案存取與定址能力。關聯式引擎使用 WinFS 核心服務來提供結構化的存放區與其他服務（例如：鎖定將使用哪個 WinFS 執行階段來實作該功能。WinFS 執行階段會公開服務（例如：同步處理與規則），其可用於同步處理 WinFS 存放區或在發生特定事件時執行特定動作。

WinFS 是以服務的方式執行，此服務會執行三個處理程序 - 裝載關聯式資料存放區的 **WinFS.exe**、裝載索引編製與查詢引擎的 **WinFSSearch.exe** 以及與底層檔案系統互動的 **WinFPM.exe (WinFS File Promotion Manager)**。您可以利用一組.NET Framework API 來撰寫程式以存取其功能，這些.NET Framework API 可讓應用程式定義自訂資料型別、定義資料之間的關係、儲存與擷取資訊，以及實作進階搜尋。接著應用程式可以彙整資料，並將資料呈現給使用者。

#### 資料存放區

WinFS 將資料儲存在關聯式存放區中，這些存放區會公開為虛擬位置，稱為「存放區」。WinFS 存放區是通用存放庫，任何應用程式都可以在其中儲存資料，以及中繼資料、資料關係與結構描述。WinFS 執行階段本身可以套用特定的資料關係；例如，若圖片的「subject」屬性與連絡人的「name」屬性相同，則 WinFS 可以在該連絡人與該圖片之間建立關聯。資料之間的關係也可以由其他應用程式或使用者指定 。

WinFS 提供一致性的存放區，但無法定義將儲存於存放區之資料的格式。但是，它支援以應用程式支援的特定格式寫入資料。前提是應用程式必須提供結構描述，以定義解譯檔案格式的方式。例如，您可以新增結構描述以讓 WinFS 知道如何讀取（甚至是進一步搜尋或分析）特定檔案格式，例如 PDF 檔案。透過使用結構描述，任何應用程式都可以讀取由其他應用程式所建立的資料，而且不同的應用程式也可以透過共享結構描述以其他應用程式支援的格式來寫入資料。

您可以在一部電腦上建立多個 WinFS 存放區。這樣可以獨立儲存不同類別的資料，例如，您可以將公司檔案與私人檔案儲存在不同的存放區中。根據預設，WinFS 只提供一個存放區，其名稱為「DefaultStore」。WinFS 存放區是公開為殼層（shell）物件（類似虛擬資料夾），此物件會動態產生存放區中的項目清單，並以資料夾檢視方式呈現這些項目。利用殼層物件也可以搜尋資料存放區中的資訊。

資料單位是以 WinFS 項目的方式儲存在 WinFS 存放區中。WinFS 項目與核心資料項目亦包含資料項目與其他資料之關聯的資訊。此「關聯」是以邏輯連結的方式儲存。連結指的是目前的項目與哪些資料項目關聯。換句話說，連結是用以指定資料與其他資料項目的關係。連結實體上是以連結識別碼來儲存，此識別碼指定資料關聯的名稱與用途，例如，「所屬型別」或「組成要素」。連結識別碼是儲存為資料項目的屬性（attribute）。具有相同連結識別碼的所有物件將被視為相關物件。您必須事先將 XML 結構描述（定義將儲存在 WinFS 中之資料項目的結構）提供給 WinFS 執行階段。在 WinFS 的 Beta 1 版本中，您必須先將結構描述組件新增到 GAC，才能開始使用結構描述。

### 資料模型

WinFS 模型資料會使用資料項目、其關聯、延伸（extension）與規則來規範其使用方式。WinFS 必須知道資料項目的類型與結構，才能將資料項目中儲存的資訊提供給要求該資訊的應用程式。這是透過使用結構描述來完成。對於即將儲存在 WinFS 中的每種資料項目類型，您必須提供對應的結構描述，以定義資料的類型、結構與關聯。這些結構描述是使用 XML 來定義。

預先定義的 WinFS 結構描述不僅包含檔案、電子郵件、約會、工作、媒體、音訊、視訊等的結構描述；也包含系統結構描述，其中包括組態、程式與其他系統相關資料。如果要讓應用程式在 WinFS 中儲存資料，但不想與其他應用程式共享該資料的結構，或這些資料可跨系統提供，則可以針對個別應用程式定義自訂結構描述。

#### 型別系統

檔案系統與 WinFS 之間最大的差異在於 WinFS 知道其所儲存之每個資料項目的型別。型別會指定資料項目的屬性（property）。WinFS 型別系統與.NET Framework 的類別與繼承概念緊密關聯。透過延伸與巢狀化任何預先定義的型別，即可建立新型別。

WinFS 提供四種預先定義的基礎型別– _Items_、_Relationships_、_ScalarTypes_ 與 _NestedTypes_。Item 是可儲存的基礎資料物件，而 Relationship 則是兩個資料項目之間的關係或連結。因為所有 WinFS 項目都必須具有型別，儲存之項目的型別會定義其屬性（property）。Item 的屬性可以是 ScalarType（定義屬性可包含之資訊的最小單位）或 NestedType（多個 ScalarTypes 和 / 或 NestedTypes 的集合）。所有 WinFS 型別都以.NET CLR 類別的方式提供。

任何以資料單位（例如：連絡人、影像、視訊或檔案等）所代表的物件都可以儲存在 WinFS 存放區中做為 Item 型別的特殊項。根據預設，WinFS 為檔案、連絡人、檔案、圖片、音訊、視訊、連絡人與郵件提供 Item 型別。檔案 Item 可以儲存任何一般資料，這在檔案系統中是儲存為檔案。但除非為檔案提供進階結構描述（透過將它定義為特殊化的 Item），WinFS 將無法存取其資料。此類檔案 Item 僅能支援與其他 Item 相關聯。

開發人員可以擴充這些型別或基礎型別 Item，以為其自訂資料提供型別。Item 中包含的資料是以屬性或實際儲存資料的欄位來定義。例如，_連絡人_ Item 可能包含型別為 ScalarType 的 _Name_ 欄位，以及型別為 NestedType（進一步由兩個 ScalarType 組成）的 _Address_ 欄位。為定義此型別，會擴充基礎類別 Item，而且會新增必要欄位至該類別。NestedType 欄位可定義為包含兩個 ScalarType 欄位的另一個類別。一旦定義型別，就必須定義結構描述以表示每個欄位的原始型別，例如 Name 欄位的型別是 String、Address 欄位是自訂的 Address 類別，每個欄位的型別都是 String。WinFS 支援的其他原始型別包括 Integer、Byte、Decimal、Float、Double、Boolean 與 DateTime 等。結構描述也會定義哪些欄位為必要欄位，哪些欄位為選用欄位。系統會使用以此方式定義的連絡人 Item 來儲存有關連絡人的資訊，方式是填入屬性欄位並予以儲存。首次儲存時只需要填入標示為必要的欄位。其他欄位可在稍後由使用者填入，或完全不填入。若需要新增多個欄位（例如：「上次交談日期」），只要視需要簡單地擴充此型別即可。您可以使用相同的方式定義其他資料的 Item 型別。

WinFS 會為所有已定義的 Item 建立資料表。為 Item 定義的所有欄位會構成資料表的資料欄，而每個對應 Item 的 Item 實體則會儲存為資料表的資料列。當資料表中的某些欄位參照某些其他資料表中的資料時，即表示這些資料表之間有特定的關係存在。關係的結構描述會指定相關的資料表有哪些，以及關係的種類與名稱。WinFS 執行階段負責管理關係結構描述。所有 Item 都會公開為.NET CLR 物件，此物件具有統一的介面，可讓應用程式輕鬆存取欄位中儲存的資料。因此，任何應用程式都可以擷取具有任何 Item 型別的物件，而且可以使用該物件中的資料，而不需要瞭解欄位中儲存之資料的實際結構。

WinFS 型別是公開為.NET 類別，它可以具現化為.NET 物件。透過設定屬性即可在這些型別中儲存資料。完成之後，它們變會永久儲存至 WinFS 存放區。使用 _ItemContext_ 類別即可存取 WinFS 存放區。ItemContext 允許以交易式方式存取 WinFS 存放區，例如，從將 ItemContext 物件繫結到存放區到因為全部成功而關閉或所有變更都已復原。當資料發生變更時，它們不會寫入到磁碟；而是會寫入到記憶體內的記錄。只有當連線關閉時，變更才會以批次方式寫入磁碟。這樣可協助最佳化磁碟 I/O。下列程式碼片段會建立連絡人並儲存在 WinFS 存放區中。

## 參考文獻

## 參見

* 分類：微軟磁碟檔案系統
  * FAT
  * NTFS
  * ReFS
* 關聯式資料庫管理系統
* GNOME Storage，GNOME 桌面的儲存管理系統
* NEPOMUK

## 外部連結

* WinFS Blog
* WinFS at the Microsoft Developer Network
* Channel 9 Videos
* WinFS Newsgroup
* WinFS Beta 1 Review
* WinFS area on NetFXGuide.com