我有一个实体,除了一些常见属性外,还包含一个扩展属性列表,这些属性存储为集合中的(Name,Value)字符串对。我应该提一下,这些扩展属性因实例而异,并且只需要为每个实例列出它们(不会对扩展属性进行任何查询,例如查找具有特定实例的所有实例(Name,价值)对)。我正在探索如何使用Windows Azure Table Services来持久保存此实体。通过我现在正在测试的特定方法,我担心随着应用程序遇到更多不同的扩展属性名称,性能可能会随着时间的推移而降低。
如果我将此实体存储在典型的关系数据库中,我可能有两个表来支持这个模式:第一个将包含实体标识符及其公共属性,第二个将引用实体标识符并使用EAV样式行建模,用于存储扩展(名称,值)对,每行一个。
由于Windows Azure中的表已经使用了EAV模型,因此我正在考虑对我的实体进行自定义序列化,以便存储扩展属性,就好像它们是在编译时为实体声明的一样。我可以使用DataServiceContext提供的阅读和写作实体事件来实现这一目标。
private void OnReadingEntity(object sender, ReadingWritingEntityEventArgs e)
{
MyEntity Entry = e.Entity as MyEntity;
if (Entry != null)
{
XElement Properties = e.Data
.Element(Atom + "content")
.Element(Meta + "properties");
//select metadata from the extended properties
Entry.ExtendedProperties = (from p in Properties.Elements()
where p.Name.Namespace == Data && !IsReservedPropertyName(p.Name.LocalName) && !string.IsNullOrEmpty(p.Value)
select new Property(p.Name.LocalName, p.Value)).ToArray();
}
}
private void OnWritingEntity(object sender, ReadingWritingEntityEventArgs e)
{
MyEntity Entry = e.Entity as MyEntity;
if (Entry != null)
{
XElement Properties = e.Data
.Element(Atom + "content")
.Element(Meta + "properties");
//add extended properties from the metadata
foreach (Property p in (from p in Entry.ExtendedProperties
where !IsReservedPropertyName(p.Name) && !string.IsNullOrEmpty(p.Value)
select p))
{
Properties.Add(new XElement(Data + p.Name, p.Value));
}
}
}
这很有效,因为我可以定义扩展属性名称和值的要求,所以我可以确保它们符合Windows Azure表中实体属性的所有标准要求。
那么随着应用程序遇到数千个不同的扩展属性名称会发生什么?
以下是我在开发存储环境中观察到的内容:
表容器架构随着每个新名称的增长而增长。我不确定这个架构究竟是如何使用的(可能是下一点),但显然这个xml文档会随着时间的推移而变得非常大。
每当读取实例时,传递给OnReadingEntity的xml都包含为任何其他实例存储的每个属性名称的元素(不仅仅是为正在读取的特定实例存储的属性)。这意味着实体的检索会随着时间的推移而变慢。
我是否应该在生产存储环境中预期这些行为?我可以看到这些行为对于大多数表来说是如何可接受的,因为随着时间的推移,模式将主要是静态的。也许Windows Azure Tables不是这样设计的?如果是这样,我肯定需要改变我的方法。我也对其他方法的建议持开放态度。
答案 0 :(得分:4)
开发存储使用SQL Express来模拟云表存储。忽略你在那里看到的......生产存储系统不存储任何模式,因此在表中拥有大量独特属性没有任何开销。