我已经使用这些来源对表存储及其大小限制,开销等进行了大量研究:
> http://blogs.msdn.com/b/windowsazurestorage/archive/2010/07/09/understanding-windows-azure-storage-billing-bandwidth-transactions-and-capacity.aspx
> http://msdn.microsoft.com/en-us/library/dd179338.aspx
使用这些信息,我写了一些代码来有效地存储多个属性的二进制数据,计算任何行和属性开销,并保持64KB属性限制和1MB行限制.
不幸的是它只是不起作用.作为一个例子,存储大约0.5MB返回400 Bad Request,说明实体太大 – 我不明白为什么它会被赋予1MB行大小限制.
<?xml version="1.0" encoding="utf-8" standalone="yes"?> <error xmlns="http://schemas.microsoft.com/ado/2007/08/dataservices/metadata"> <code>EntityTooLarge</code> <message xml:lang="en-GB">The entity is larger than allowed by the Table Service.</message> </error>
我一直在使用的代码是相当简单的,但我可能在估算开销时犯了错误 – 但我怀疑它会被100%的数据大小所取消.
class Program { static void Main(string[] args) { var client = CloudStorageAccount.DevelopmentStorageAccount.CreateCloudTableClient(); var table = client.GetTableReference("sometable"); table.CreateIfNotExists(); const int rowOverhead = 4; const int maxRowSize = 1024 * 1024; // 1MB row size limit const int maxProperties = 252; // 255 less 3 system properties const int maxPropertySize = 64 * 1024; // 64KB property size limit var stream = new MemoryStream(new byte[512 * 1024]); // 0.5MB of data var entity = new DynamicTableEntity("pk","rk"); var buffer = new byte[maxPropertySize]; var keySize = (entity.PartitionKey.Length + entity.RowKey.Length) * 2; var used = rowOverhead + keySize; for (var i = 0; i < maxProperties + 1; i++) { if (i > maxProperties) { throw new ArgumentException(string.Format("You have exceeded the column limit of {0}.",maxProperties)); } var name = string.Concat("d",i); var overhead = CalculatePropertyOverhead(name,EdmType.Binary); var read = stream.Read(buffer,maxPropertySize - overhead); used += read + overhead; if (used > maxRowSize) { throw new ArgumentException(string.Format("You have exceeded the max row size of {0} bytes.",maxRowSize)); } if (read > 0) { var data = new byte[read]; Array.Copy(buffer,data,read); entity.Properties.Add(name,new EntityProperty(data)); } else { break; } } Console.WriteLine("Total entity size: {0}",used); table.Execute(TableOperation.InsertOrReplace(entity)); } static int CalculatePropertyOverhead(string name,EdmType type) { const int propertyOverhead = 8; int propertyNameSize = name.Length * 2; int propertyTypeSize; switch (type) { case EdmType.Binary: case EdmType.Int32: case EdmType.String: propertyTypeSize = 4; break; case EdmType.Boolean: propertyTypeSize = 1; break; case EdmType.DateTime: case EdmType.Double: case EdmType.Int64: propertyTypeSize = 8; break; case EdmType.Guid: propertyTypeSize = 16; break; default: throw new NotSupportedException(); } return propertyOverhead + propertyNameSize + propertyTypeSize; } }
任何帮助解释我缺少的东西是值得赞赏的!
谢谢,
马蒂亚斯
Mattias,您所参考的限制是针对实际的存储服务,但您的目标是本地存储模拟器.模拟器使用本地SQL Server作为其后备存储,并且具有与实际存储服务不同的限制.有关更多信息,请参阅
http://msdn.microsoft.com/en-us/library/windowsazure/gg433135.aspx,特别是此行:
* The total size of a row in a table in the storage emulator is limited to less than 1 MB.