2012-08-01 57 views
9

我一直在試圖讓Azure Table中存儲的一點點把握好一段時間了,雖然我知道它通常是如何工作的,我真的很努力動搖我的關係型數據庫的思維。我通常通過示例學習最好,所以我想知道如果有人能幫助我。我將簡要介紹一下如何使用關係數據庫解決問題的簡單設置,有人可以幫助指導我將其轉換爲使用Azure表存儲嗎?如何擺動關係數據庫思維來設計一個天藍色的表存儲數據存儲?

比方說,我有簡單的筆記應用程序,它擁有用戶和他們希望每個用戶可以有許多的筆記,每一個音符可以有很多用戶(業主或觀衆),因爲它需要。如果我打算使用關係數據庫來部署這個如下我可能會部署:

對於數據庫,我會像這樣的東西開始:

CREATE TABLE [dbo].[Users](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [Username] [nvarchar](20) NOT NULL) 

CREATE TABLE [dbo].[UsersNotes](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [UserID] [int] NOT NULL, 
    [NoteID] [int] NOT NULL) 

CREATE TABLE [dbo].[Notes](
    [ID] [int] IDENTITY(1,1) NOT NULL, 
    [NoteData] [nvarchar](max) NULL)   

然後,我會設置之間的關係Users.ID and UsersNotes.UserID以及Notes.ID and UsersNotes.NoteID與約束來實施參照完整性。

對於應用程序,我將有一個ORM產生一些實體與各個匹配名稱屬性,我可能會收工:

public class Users 
{ 
    public int ID { get; set; } 
    public String Username { get; set; } 
} 
// and so on and so forth 

我認識到,這樣的設計是完全依賴在關係型數據庫上,我正在尋找的是一些關於如何擺脫使用Azure Table存儲或任何其他非關係數據存儲技術的思路的建議。

爲了爭辯的緣故,我們也假定我已經安裝了Azure SDK並且已經玩過了,但是我對使用SDK的工作知識是有限的,我寧願不專注於此,而寧願上面的一個好的解決方案是什麼樣的。一個好的起點將有助於使SDK對我有意義,因爲我將有一個參考點。

爲了完整起見,可以說

  • 注意數據會經常更改首次創建時,並逐漸減少隨着時間的推移
  • 用戶將有許多筆記和筆記可以有多個用戶(未同時,只要觀衆)
  • 我期望相當一些用戶(低幾百個),但我希望有相當數量的音符(數百低,每用戶)
  • 我希望對查詢Username最多,然後顯示的音符用戶有權訪問
  • 觀看時注意,顯示其他用戶訪問這一點,反向查找
+0

我得到的問題是「如何」,但我的問題是「爲什麼」?你是否在SQL Azure中定價? 1 TB的日誌文件是ATS。 10 GB的關係是SQL。在之間進一步分析。但10 GB的關係數據是很多的。 – Paparazzi 2012-08-01 23:01:48

+2

@Blam我對學習練習以及成本感興趣。 – Nate 2012-08-02 00:01:30

+0

酷,但是SO是針對特定的編程問題。如果你想了解有很多書籍和在線資料。 – Paparazzi 2012-08-02 02:17:44

回答

5

一些想法...

  1. 認爲,在全部不同的實體,並從它們分解進一步使用任何標準化技術棄權。
  2. 想出每個實體,其中,如果索引上,將同時允許一個精確搜索鍵,以及一個範圍鍵搜索匹配單個標識符。
  3. 分割標識符分爲2段爲天青表存儲的可擴展性的需求。如何分割好,是對自己的一個獨立的主題,但通常分裂跨越定義良好的自然段的作品足夠好。

在你的例子中,這兩個實體是User和Note。

用戶標識將足以唯一地標識用戶。在用戶範圍搜索可能不是很有用。用戶ID可以是任何固定長度值。

UserId + NoteId足以唯一標識一個音符。 note ID可以是類似日期/時間戳+唯一性的GUID。這樣的密鑰與UserId一起將唯一標識該筆記,並且允許在給定時間段內對所有用戶筆記或用戶筆記進行範圍搜索。

因此,如果UserId =「ABCD」,NoteId可能是「20120801-00f64829-6044-4fbb-8b4e-ae82ae15096e」。

你可以在相同或不同表中兩個實體店。這裏有一些不同的方法......

如果每個實體都有自己的表,

  • 對於用戶分區鍵可以是「ABCD」和行鍵可以 其實任何東西,你只在分區搜索鍵。

  • 或者分區鍵可以是「AB」而行鍵可以是「CD」。

    以上兩種方式都能很好地適應大量用戶。

  • 或分區鍵可以是「*」,行鍵可以是「ABCD」。這對於一小部分用戶來說效果很好,您可以將用戶和筆記放在同一個表中。

對於注

  • 分區鍵可以是「ABCD」和行鍵可以是「20120801- 00f64829-6044-4fbb-8b4e-ae82ae15096e」

  • 範圍搜索這裏可能是

    • On PartitionKey =「ABCD」獲取用戶的所有筆記。
    • On PartitionKey =「ABCD」and RowKey> =「20120801」and RowKey < =「20120901」在日期範圍內獲取備註。

UPDATE

我誤解你的問題,只是假設一個用戶與音符之間一對多的關係。由於存在多對多的關係,需要4個實體進行建模,除非您不介意重複。 (如果筆記短小而且不可變,它們可以被複制,並且您不必模擬連接)。

如果密鑰位於不同的密鑰範圍內並且可以輕鬆識別,則可以將多於1個實體放在一個表中。儘管在實踐中這是不常見的,除非有特定需求,通常是對同一分區的事務寫入(不適用於此)。

所以一個表格模式可能看起來像這樣。對於多個表,分區鍵前綴可以被刪除。

  • 你也可以在3個表,一個是用戶,一個Notes和一個在兩個方向上的關係建模。
  • 您也可以在SQL中部分建模,部分在Azure存儲中建模。 Blob或表中的註釋和用戶數據以及SQL中的關係。

Entity  Partition Key    Row Key    
User   「U」 + UserId  
Note   「N」 + NoteId(Date)   NodeId(GUID) 
User Note  「X「 + UserId    NoteId(Date+GUID) 
Note User  「Y「 + NoteId(Date+GUID) UserId  

這些都是一些替代品,你會想,以確定哪些適合您的數據和您的需求最好的。

另一個UPDATE
其實3個實體應該是足夠用的UserNote實體的注意。

如果用戶ID = GUID
而NoteId =日期+ GUID

Entity  Partition Key Row Key    Note User   
User  UserId  
User Note UserId   NoteId(Date+GUID) Note   (Contains Note and can query for all notes for a user). 
Note User NoteId(Date) NodeId(GUID)    UserId (Can query for all Users of a note. Join on ‘User Note’ to get note.) 
+0

您能否詳細說明一下如何將兩個實體存儲在一個表中?你是否也跳過我的UsersNotes表,因爲它沒有必要? – Nate 2012-08-02 15:25:51

+0

@Nate。我誤解了這些問題。請看我最新的回覆。 – hocho 2012-08-02 16:42:46

+0

我非常感謝你的幫助。首先,我的筆記不是一成不變的,用戶可能會經常更換它們。其次,把它們放在一張桌子裏是明智的嗎?如果我將它們存儲在三個表中並繼續爲關係概念建模,並在我的應用程序中手動強制引用完整性,那麼我是否會首先破壞使用表存儲的目的?此外,NoteId(日期)從何而來?) – Nate 2012-08-02 16:52:14

5

你可以認爲天青表爲對象的集合我也期望。

在天青表說法,一個對象是一個實體。

要使用您的示例,用戶將從中獲得TableStorageEntity。

Azure的表存儲是不是關係。沒有聯接。但是LINQ是一種支持各種語言的查詢語言。所以加入操作和參照完整性不是由系統提供的。開發者必須這樣做。

一些顯著的優勢:

(1)天青表自動縮放跨多個存儲節點以維持性能,即使你正在處理數十億的實體。 (3)它們被複制3次 (3)它們附帶SLA (4)Table服務API符合REST API,因此可以從非Microsoft技術訪問它們。

要允許將對象存儲在Azure表中,只需從TableStorageEntity派生。

如果您搜索「Microsoft Azure表虛擬實驗室」,可以找到更多信息。

下面的代碼片段忽略(1)分區鍵(2)rowkey。但這是你需要擔心的事情。將兩個鍵看作關係表上的主鍵。

你需要仔細考慮這兩個關鍵的。他們決定表現。由於您只能獲得一組密鑰,因此您可能需要保持數據的非標準化副本以獲得最佳性能。

 
    public class Users : TableStorageEntity 
    { 
     public int ID { get; set; } 
     public String Username { get; set; } 
    } 

檢查出來的手。 Azure桌子很便宜,易於使用。

+0

...「不要」需要擔心嗎? – 2012-08-01 22:13:08

+0

因此,我應該只創建三個獨立的天藍色表格,並通過LINQ手動自己加入數據?本質上只是保持關係設置,只是手動執行它? – Nate 2012-08-01 22:25:34

1

爲什麼UsersNotes有一個ID?爲什麼不只是用戶ID,NoteID作爲複合主鍵?

所以三個表各有兩個屬性。第一個是PartitionKey,第二個是RowKey。

如果您希望在NoteID上查詢以獲得大量用戶ID,則在PartitionKey上搜索的第4個表比在RowKey上搜索要快。它通常會更便宜,因爲它減少了交易。但是你有事務加載表。

public class NotesUsers : TableStorageEntity 
    { 
     public int NoteID { get; set; } 
     public int UserID { get; set; } 
    } 

而對於用戶表,請使用UserName作爲PartitionKey,如果這是常見的查詢條件。

在ATS中沒有聲明性參照完整性。您將需要在應用程序中強制執行所有數據關係。兩部分組合鍵。 RowKey上的搜索就像掃描(而不是查找)。在PartitionKey上進行搜索就像搜索一樣。

但我會去SQL。如果筆記是有人打字,那麼這是一個相對較低的數據量。它是關係數據。

+0

UsersNotes有一個不符合協議/習慣的ID。我想這不是明確需要的。我瞭解參照完整性必須在我的應用代碼中實現。也許我的問題應該是:「我是否放棄了使用表存儲的好處,通過建模我的關係數據並手動實施參照完整性?」 - 我的印象是,要有效地使用ATS,你必須以不同的方式建模數據(非關係型),但也許我錯了? – Nate 2012-08-02 17:00:49

+0

如果ID不需要,那麼爲什麼使用它的UsersNotes。回到我對SO的原始評論是針對特定的編程問題。你讀過我的回答了嗎?附加表NotesUsers是表格模型在ATS和SQL之間的差異的一個例子。在SQL中,我不會把用戶名放在第一位。 – Paparazzi 2012-08-02 17:46:43