沒有辦法以可伸縮的方式使用像Azure Table這樣的鍵值NoSQL數據庫服務實現所請求的功能。我建議的解決方案是創建兩個新表,Entity1TransitionTable和Entity2TransitionTable。該提議是在Azure Table存儲相對便宜的前提下,即時檢測轉換並維護這些表中的轉換列表。該解決方案假定應用程序可以隨時跟蹤的ID值,它總是由1
public class LogEntry : TableEntity
{
public LogEntry() { }
public LogEntry(string userid, int id, string date, bool entity1, bool entity2)
{
PartitionKey = userid;
RowKey = id.ToString();
Id = id;
Entity1 = entity1;
Entity2 = entity2;
Date = date;
}
public int Id { get; set; }
public string Date { get; set; }
public bool Entity1 { get; set; }
public bool Entity2 { get; set; }
}
static void TransitionDetection(CloudTable tbl, CloudTable e1Tbl, CloudTable e2Tbl, LogEntry currentLogEntry)
{
if (currentLogEntry.Id> 1)
{
// Retrieve the previous log entry
string pkFilter = TableQuery.GenerateFilterCondition("PartitionKey", QueryComparisons.Equal, currentLogEntry.PartitionKey);
string rkFilter = TableQuery.GenerateFilterCondition("RowKey", QueryComparisons.Equal, (currentLogEntry.Id - 1).ToString());
string combinedFilter = TableQuery.CombineFilters(pkFilter, TableOperators.And, rkFilter);
TableQuery<LogEntry> query = new TableQuery<LogEntry>().Where(combinedFilter);
LogEntry prevLogEntry = tbl.ExecuteQuery(query).ToList()[0];
// If Entity1 transitioned, record it
if (prevLogEntry.Entity1 != currentLogEntry.Entity1)
{
e1Tbl.Execute(TableOperation.Insert(currentLogEntry));
}
// If Entity2 transitioned, record it
if (prevLogEntry.Entity2 != currentLogEntry.Entity2)
{
e2Tbl.Execute(TableOperation.Insert(currentLogEntry));
}
}
}
static void Main(string[] args)
{
string storageConnection = "DefaultEndpointsProtocol=https;AccountName=MyTable;AccountKey=MY_KEY";
// Select table
CloudStorageAccount storageAccount = CloudStorageAccount.Parse(storageConnection);
CloudTableClient tableClient = storageAccount.CreateCloudTableClient();
CloudTable table = tableClient.GetTableReference("LogTable");
CloudTable entity1TransitionTable = tableClient.GetTableReference("Entity1TransitionTable");
CloudTable entity2TransitionTable = tableClient.GetTableReference("Entity2TransitionTable");
table.CreateIfNotExists();
entity1TransitionTable.CreateIfNotExists();
entity2TransitionTable.CreateIfNotExists();
// Add Log Entries
int id = 0;
LogEntry le1 = new LogEntry("0", ++id, "May 1 2015", true, false);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le1);
table.Execute(TableOperation.Insert(le1));
LogEntry le2 = new LogEntry("0", ++id, "May 2 2015", false, true);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le2);
table.Execute(TableOperation.Insert(le2));
LogEntry le3 = new LogEntry("0", ++id, "May 3 2015", false, false);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le3);
table.Execute(TableOperation.Insert(le3));
LogEntry le4 = new LogEntry("0", ++id, "May 4 2015", true, false);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le4);
table.Execute(TableOperation.Insert(le4));
LogEntry le5 = new LogEntry("0", ++id, "May 5 2015", false, true);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le5);
table.Execute(TableOperation.Insert(le5));
LogEntry le6 = new LogEntry("0", ++id, "May 7 2015", true, false);
TransitionDetection(table, entity1TransitionTable, entity2TransitionTable, le6);
table.Execute(TableOperation.Insert(le6));
Console.ReadKey();
}
遞增如果您檢查與像TableXplorer申請表,你會看到下面的結果:
LogTable
![enter image description here](https://i.stack.imgur.com/P8A0U.png)
Entity1TransitionTable
![enter image description here](https://i.stack.imgur.com/O8X3D.png)
Entity2TransitionTable
你插入每個實體當天更改的記錄?我的意思是,今天是7月12日。當時鍾在7月13日到達時,你是否在表中爲所有實體以其當前狀態(真或假)插入新記錄?隨着時間的推移,如果實體狀態發生變化,您是否更新這些實體?然後在第二天再次插入新記錄?另外請介紹一下你的PartitionKey/RowKey值。 –
不一定每天插入記錄,但在同一天(即可能每天,也可能每隔一天等)插入多個記錄。 'PartitianKey'是一個userid(所以假設上面的例子都具有相同的'PartitianKey''''' RowKey'''是一個簡單的'GUID'. – Brett
這裏有一個想法:你使用entity ids作爲分區鍵和反時間(最大時間 - 當前日期)作爲行鍵,因此每個實體最終將在不同的分區中,最近的更新將始終位於最前面,每當添加一個新更新時,都會有一個額外的字段作爲變化的指示符。最近的更新將會非常高效。在一組分區中的查詢將具有高吞吐量。 – mert