共用方式為


合併式複寫在已篩選發行集中評估資料分割的方式

使用參數化篩選和聯結篩選來篩選合併發行集中的一或多個資料表時,會分割已發行資料表中的資料。 資料分割單純是資料表中資料列的子集。 當「訂閱者」與「發行者」同步時,「發行者」必須根據「訂閱者」提供給系統函數 SUSER_SNAME() 和 (或) HOST_NAME() 的值,判斷哪些資料列屬於「訂閱者」的資料分割。 在發行者端針對每一個接收到已篩選資料集來判斷變更的資料分割成員資格之處理,稱為資料分割評估。

根據已發行資料表中的資料,以及建立參數化篩選和任何相關聯結篩選時選擇的設定,已發行資料表中的各資料行可以:

  • 屬於一個資料分割並且僅複寫至一個「訂閱者」(sp_addmergearticle 參數 @partition_options 的值為 3)。 例如,在 AdventureWorks 資料庫中,您可以使用下列篩選子句篩選 Employee 資料表:WHERE Employee.LoginID = SUSER_SNAME()。 符合各「登入識別碼」的資料列只會傳送到一個「訂閱者」。

  • 屬於一個資料分割並且複寫至多個「訂閱者」(@partition_options 的值為 2)。 例如,在 AdventureWorks 資料庫中,您可以使用下列篩選子句篩選 Products 資料表:WHERE Products.ProductLine = HOST_NAME()。 HOST_NAME() 這個值會被覆寫,如此一來,負責銷售登山腳踏車的銷售人員群組就會收到所有 ProductLine 資料行中的值為「M」的資料列,而雖然擁有「M」值的各資料行只屬於一個資料分割,但會傳送至多個「訂閱者」。 如需使用 HOST_NAME() 的詳細資訊,請參閱<參數化資料列篩選器>中的「使用 HOST_NAME() 篩選」一節。

  • 屬於多個資料分割並且複寫至多個「訂閱者」(@partition_options 的值為 01)。 例如,在 AdventureWorks 資料庫中,您可以使用下列篩選子句篩選 Products 資料表:WHERE Products.ProductLine = HOST_NAME() or Products.ListPrice < 100。 在這個案例中,負責銷售登山腳踏車的銷售人員亦可出售其他類別目錄中的產品,只要銷售價格低於美金 $100 元即可。 由於篩選子句中使用 OR,因此資料列可以屬於多個資料分割。

評估資料分割的方式

資料分割評估會在合併複寫中使用兩種方式之一進行,端視是否有使用預先計算資料分割功能而定。 如果符合某些需求,根據預設會建立新的合併發行集,且其中預先計算資料分割功能為已啟用狀態,而現有發行集會自動更新並使用該功能。 如需完整的需求清單,請參閱<使用預先計算的資料分割最佳化參數化篩選效能>。

使用預先計算資料分割的資料分割評估

有了預先計算資料分割,便會在對已發行資料表進行變更時,預先計算並且保存「發行者」端所有變更的資料分割成員資格。 如此一來,訂閱者與發行者同步處理時,它可以立即啟動來下載與其資料分割相關的變更,不必再經過資料分割評估處理。 當發行集內有大量的變更、訂閱者或發行項時,如此就可以大幅提高效能。

預先計算資料分割評估中包含的系統資料表為:

  • MSmerge_partition_groups

  • MSmerge_current_partition_mappings

  • MSmerge_past_partition_mappings

MSmerge_partition_groups 針對發行集內定義的每個資料分割均包含一個資料列。 資料分割可以:

  • 使用 sp_addmergepartition 或 [發行集屬性] 對話方塊的 [資料分割] 頁面明確地定義。

  • 在訂閱者同步處理時自動建立 (如果訂閱者要求一個在 MSmerge_partition_groups 中還沒有項目的資料分割)。

其他兩個資料表 (MSmerge_current_partition_mappingsMSmerge_past_partition_mappings) 會在變更已發行資料表時擴展。 每次發行集資料庫中的已發行資料表變更時,合併觸發程序便會引發並記錄中繼資料:

  • 針對 MSmerge_contentsMSmerge_partition_groups 中每個唯一的資料列組合,MSmerge_current_partition_mappings 都會有一個資料列。 例如,使用者資料表中的一個資料列若是屬於兩個資料分割,則在資料列更新時,會在 MSmerge_contents 插入一個資料列以反映更新,並在 MSmerge_current_partition_mappings 插入兩個資料列,以表示更新的資料列屬於兩個資料分割。

  • 針對不再屬於給定資料分割的每個資料列,MSmerge_past_partition_mappings 中就會有一個資料列。 有下列情況時,資料列會從資料分割中移出:

    • 已刪除資料列。 如果是從使用者資料表刪除資料列,就會在 MSmerge_tombstone 中插入一個資料列,並在 MSmerge_past_partition_mappings 中插入一或多個資料列。

    • 資料行中用於篩選的值已經變更。 例如,參數化篩選若是以公司總部所在的州別為基準,則在公司搬遷後,公司的資料列 (和其他資料表中的相關資料列) 就可能會從某個營業人員的資料分割中移出,並移入另一個業務人員的資料分割中。 如果資料列更新之後不再屬於資料分割,則會在 MSmerge_contents 中插入或更新一個資料列,並在 MSmerge_past_partition_mappings 中插入一或多個資料列。

    [!附註]

    如果使用每個資料分割一個訂閱的不重疊資料分割 (sp_addmergearticle 參數 @partition_options 的值為 3),系統資料表 MSmerge_current_partition_mappingsMSmerge_past_partition_mappings 就不會用來追蹤資料列的資料分割對應,因為每個資料列只屬於一個資料分割,而且只能在一個「訂閱者」端變更。

使用 SetupBelongs 處理序進行資料分割評估

如果沒有預先計算資料分割,則會使用稱為 SetupBelongs 的處理序。 在同步處理期間,會針對自上一次「合併代理程式」為特定「訂閱者」執行後,「發行者」端已篩選資料表的各項變更執行資料分割評估。 這個處理序會針對每個與「發行者」同步的「訂閱者」重複執行。

為了對「訂閱者」執行資料分割評估,「合併代理程式」會呼叫系統預存程序 sp_MSsetupbelongs,該程序會:

  1. 為每個已篩選發行項建立兩個暫存資料表:#belongs_<RandomNumber>#notbelongs_<RandomNumber>

  2. 使用「訂閱者」端的 SUSER_SNAME() 和 (或) HOST_NAME() 函數傳回的值查詢系統檢視,這項查詢是用來判斷 MSmerge_contentsMSmerge_tombstone 中的資料列是否與「訂閱者」的資料分割相關。

  3. 如果資料列與「訂閱者」完全無關 (例如,另一個資料分割的插入項),這個資料列的中繼資料便不會儲存到 #belongs#notbelongs 中。 如果資料列相關,則會有兩種可能的結果:

    • 資料列會加入至 #belongs,如果 MSmerge_contents 中的資料列是屬於資料分割的插入項,或者 MSmerge_contents 中的資料列是一項更新,它不會改變用於篩選的任何資料行中的值。

    • 資料列會加入至 #notbelongs,如果 MSmerge_contents 中的資料列是一項更新,且會改變用於篩選的任何資料行中的值 (換言之,它會將資料列移到新的資料分割),或者 MSmerge_tombstone 中的資料列代表刪除資料分割中的資料列。

[!附註]

即使已啟用預先計算資料分割,如果訂閱是在其他訂閱開始接收變更之後才建立,SetupBelongs 處理序仍會在第一次同步處理訂閱時使用。