2013-04-14 35 views
1

的專欄中,我有一個簡單的表:獨特類型爲nvarchar

Filepath | deleted | categories | description

我想用表的LINQ to SQL的實體模型。在該模型中,該列path(它是字符串,數據庫中的nvarchar)可以設置爲主鍵,但Visual Studio表設計器不是這種情況。

路徑是什麼使一個文件唯一,所以我必須確保表中沒有重複的路徑。如何實現這一目標?謝謝你的時間。

+2

「nvarchar」聲明的長度是多少?最大的密鑰長度是900字節,所以需要'<= NVARCHAR(450)' –

+0

我將它設置爲nvarchar(MAX),這是一個「路徑」的好主意嗎? –

+4

您可以用作PK的最大長度是'NVARCHAR(450)'。 –

回答

3

你讓SQL中唯一具有UNIQUE約束,NOT NULL UNIQUE約束或PRIMARY KEY約束的列。但是我能想到的所有當前dbms對於可以被這種限制的列的長度有一個或多個限制。

這意味着有一個相當顯示停止問題,最常見的情況。例如,A UNC path on Windows可以是約32,767個字符長。

Linux系統差別很大。基於Google的快速研究,1024和4096似乎很常見。

我認爲你將不得不把唯一約束代理鍵。 (你有沒有的想法多麼傷害一個數據庫傢伙說這個問題。)問題是,你可以強制執行代理的唯一性,但不是它取代的東西。而它所取代的是重要的部分。

身份證號碼在一般情況下不起作用;你可以很容易地以{1,/ etc/adjtime},{2,/ etc/adjtime},{3,/ etc/adjtime}結束。您需要某種方式將實際數據與代理鍵的值聯繫起來。類似hashbytes()在T-SQL中「起作用」; linq具有類似的功能。 (但是你可以碰撞,就像你幾乎所有的散列函數一樣。)

+0

我認爲*與OP所使用的框架一樣,它必須是主鍵,因爲唯一的約束是 - 出於某種原因 - 不被識別爲實體標識符。我可能會混淆這與EF或Linq的其他口味,但我曾多次在這裏推出了一個獨特的限制「是不夠的」... ... –

+0

@AaronBertrand:你可能是對的。在我的第一段中,我沒有回答他的問題,因爲我列舉了後端的可能性。我相當肯定在任何*現代框架的設計中都沒有諮詢數據庫設計師。 –

+0

說到str8forward回答我的問題,似乎這確實是答案。我還沒有學會如何做到這一點。謝謝。 –

3

正如Martin已經解釋的,只要值< = 450個字符(或者900個字符,如果您能夠限制數據以使Unicode字符不被允許),您就可以創建主鍵。這工作得很好:

CREATE TABLE dbo.sample1 
(
    path NVARCHAR(450) NOT NULL PRIMARY KEY, 
    deleted BIT NOT NULL DEFAULT 0 
    -- ... other columns ... 
); 

CREATE TABLE dbo.sample2 
(
    path VARCHAR(900) NOT NULL PRIMARY KEY, 
    deleted BIT NOT NULL DEFAULT 0 
    -- ... other columns ... 
); 

無論是在Visual Studio中的一些未申報的版本有些可視化設計可以讓你做到這一點,我不知道,但你不知道使用一些可視化設計器來創建表,你做?

如果路徑可能超過900個字節,那麼您無法將其作爲關鍵字,對不起。您必須使用IDENTITY列,其他代理或密鑰中使用的路徑值的散列。哈希的例子,這將支持多達4000個字符的路徑 - 這不能滿足所有潛在的使用情況,但希望你不需要超過4000:

CREATE TABLE dbo.sample3 
(
    [path] NVARCHAR(4000) NOT NULL, 
    pathhash AS CONVERT(VARBINARY(900), HASHBYTES('MD5', path)) 
    PERSISTED PRIMARY KEY 
); 

INSERT dbo.sample3([path]) 
    SELECT '\\some\share\x' + REPLICATE('x', 900) + '.gif' 
    UNION ALL SELECT '\\some\share\x' + REPLICATE('x', 900) + '.jpg'; 

嘗試再次運行該插件。

(再次,你可以在4000個字符翻一番,達到8000個字符如果你能保證路徑將不包含Unicode字符,在這種情況下,你可以使用的varchar(8000)代替nvarchar(4000)。)

相關問題