2011-10-04 64 views
4

我正在構建一個將被分區幷包含FILESTREAM列的表。我遇到的問題是,看起來我必須有一個複合主鍵(FILE_IDFILE_UPLOADED_DATE),因爲FILE_UPLOADED_DATE是我的分區方案的一部分。那是對的嗎?我不希望這是一個複合鍵,只是有FILE_ID是主鍵......這可能只是一個用戶錯誤?具有分區的Sql服務器主鍵問題

任何建議,將不勝感激。

版:SQL Server 2008 R2的

分區方案和功能:

CREATE PARTITION FUNCTION DocPartFunction (datetime) 
AS RANGE RIGHT FOR VALUES ('20101220') 
GO 
CREATE PARTITION SCHEME DocPartScheme AS 
PARTITION DocPartFunction TO (DATA_FG_20091231, DATA_FG_201); 
GO 
CREATE PARTITION SCHEME DocFSPartScheme AS 
PARTITION DocPartFunction TO (FS_FG_20091231,FS_FG_201); 
GO 

創建聲明:

CREATE TABLE [dbo].[FILE](
    [FILE_ID] [int] IDENTITY(1,1) NOT NULL, 
    [DOCUMENT] [varbinary](max) FILESTREAM NULL, 
    [FILE_UPLOADED_DATE] [datetime] NOT NULL, 
    [FILE_INT] [int] NOT NULL, 
    [FILE_EXTENSION] [varchar](10) NULL, 
    [DocGUID] [uniqueidentifier] ROWGUIDCOL NOT NULL UNIQUE ON [PRIMARY], 
CONSTRAINT [PK_File] PRIMARY KEY CLUSTERED 
    ( [FILE_ID] ASC 
    ) ON DocPartScheme ([FILE_UPLOADED_DATE]) 
)ON DocPartScheme ([FILE_UPLOADED_DATE]) 
FILESTREAM_ON DocFSPartScheme; 

錯誤,如果我不包括FILE_UPLOADED_DATE

Msg 1908, Level 16, State 1, Line 1 
Column 'FILE_UPLOADED_DATE' is partitioning column of the index 'PK_File'. Partition columns for a unique index must be a subset of the index key. 
Msg 1750, Level 16, State 0, Line 1 
Could not create constraint. See previous errors. 

謝謝!

回答

8

你混淆了主鍵和聚集索引。兩者沒有理由相同。您可以在FILE_UPLOADED_DATE上使用聚簇索引,在FILE_ID上使用單獨的非羣集主鍵。事實上,你已經做了DocGUID列類似的東西:

CREATE TABLE [dbo].[FILE](
    [FILE_ID] [int] IDENTITY(1,1) NOT NULL, 
    [DOCUMENT] [varbinary](max) FILESTREAM NULL, 
    [FILE_UPLOADED_DATE] [datetime] NOT NULL, 
    [FILE_INT] [int] NOT NULL, 
    [FILE_EXTENSION] [varchar](10) NULL, 
    [DocGUID] [uniqueidentifier] ROWGUIDCOL NOT NULL, 
    constraint UniqueDocGUID UNIQUE NONCLUSTERED ([DocGUID]) 
     ON [PRIMARY]) 
    ON DocPartScheme ([FILE_UPLOADED_DATE]) 
    FILESTREAM_ON DocFSPartScheme; 

CREATE CLUSTERED INDEX cdx_File 
    ON [FILE] (FILE_UPLOADED_DATE) 
    ON DocPartScheme ([FILE_UPLOADED_DATE]) 
    FILESTREAM_ON DocFSPartScheme; 

ALTER TABLE [dbo].[FILE] 
    ADD CONSTRAINT PK_File PRIMARY KEY NONCLUSTERED (FILE_ID) 
    ON [PRIMARY]; 

但是這樣的設計會導致非對齊索引這可能會導致非常嚴重的性能問題,並阻止所有分區的快速切換操作。請參閱Special Guidelines for Partitioned Indexes

每個排序表都需要最少量的內存來構建。當您的 正在構建與其基表對齊的分區索引時, 使用較少的內存一次構建一個排序表。但是,當您構建非對齊分區索引時, 同時構建的排序表是 。

因此,必須有足夠的內存來處理這些 併發排序。分區數量越大,需要的內存越多 。每個分區的每個分類表的最小大小爲 40頁,每頁爲8千字節。例如,帶有100個分區的未對齊的 分區索引需要足夠的內存,以便 可以同時對4,000(40 * 100)個頁面進行連續排序。如果此內存 可用,則生成操作將會成功,但性能可能會受到影響。如果此內存不可用,則構建操作將失敗

您的設計已經有DocGUID的非對齊索引,因此性能問題可能已經存在。如果必須保持索引對齊,那麼必須承認選擇分區方案的一個副作用:除非密鑰包含分區鍵,否則不能再有邏輯主鍵或唯一的約束強制。

最後,你必須問:爲什麼要使用分區表?它們是始終是比非分區替代方法慢。除非您需要對ETL進行快速分區切換操作(由於DocGUID上的非對齊索引,您已經在進行分區切換操作),因此基本上沒有使用分區表的動機。 (搶先評論:FILE_UPLOADED_DATE上的聚簇索引是「分區消除」的更好選擇)。

+0

Remus,非常感謝你的信息。我需要分區,所以我可以把文件流文件組到另一個位置.....但只有最新的,因爲我們有空間限制....長故事。 – scarpacci

+0

上面提供的解決方案不起作用?部分原因是因爲保留字「FILE_ID」,但修復後,當我嘗試使用上述結構構建表時,仍然出現錯誤。 – scarpacci

+0

我修復了我的腳本(這次測試過)。使用分區進行文件組管理是部署分區的有效原因。不幸的是,對於ROWGUIDCOL上唯一約束的FILESTREAM要求是一個有保證的未對齊索引,這可能會導致將來出現問題(例如,如果您需要使用快速分區切換來刪除已延長最大強制保留策略生命週期的文檔)。 –

4

分區列必須始終存在於分區表的聚簇索引中。你想出的任何解決方法都必須考慮到這一點。

0

我知道,它的一個老問題,但也許谷歌會導致別人對這個問題:

一個可能的解決方案是不是日期列而是由file_id的分區。每天/每週/每月(或任何您使用的任何時間段),必須在午夜運行代理作業,其中Max(File_ID)其中file_uploadet_date < GetDate()將下一個文件組添加到分區方案,並在MaxID + 1上執行拆分。

當然,你仍然會遇到DocID上的非對齊索引的問題,除非你更加努力地將file_id添加到這個唯一索引(可能會導致非唯一的DocIds)和/或檢查插入/更新中的唯一性觸發。