У меня есть объект, который, в дополнение к нескольким общим свойствам, содержит список расширенных свойств, хранящихся в виде пар (имя, значение) строк в коллекции.Я должен, вероятно, упомянуть, что эти расширенные свойства широко варьируются от экземпляра к экземпляру, и что их нужно перечислять только для каждого экземпляра (не будет никаких запросов по расширенным свойствам, например, для нахождения всех экземпляров с определенным именем (Значение) пара).Я изучаю, как можно сохранить эту сущность с помощью Windows Azure Table Services.С конкретным подходом, который я сейчас тестирую, я обеспокоен тем, что со временем может произойти снижение производительности, поскольку приложение встречает более четкие расширенные имена свойств.
Если бы я хранил эту сущность втипичная реляционная база данных, я бы, вероятно, имел две таблицы для поддержки этой схемы: первая будет содержать идентификатор сущности и ее общие свойства, а вторая будет ссылаться на идентификатор сущности и использовать моделирование строк в стиле EAV для хранения расширенной (Name,Пары значений), по одной на каждую строку.
Поскольку таблицы в 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.
Так что же происходит со временем, когда приложение встречает тысячи различных расширенных имен свойств?
Вот что яВы наблюдали в среде хранения development :
Схема контейнера таблицы увеличивается с каждым новым именем.Я не совсем уверен, как именно используется эта схема (вероятно, для следующего пункта), но, очевидно, этот XML-документ может со временем стать довольно большим.
Всякий раз, когда экземпляр читается,xml, переданный OnReadingEntity, содержит элементы для каждого имени свойства, когда-либо сохраненного для любого другого экземпляра (а не только те, которые хранятся для конкретного экземпляра, который читается).Это означает, что получение объекта со временем замедлится.
Стоит ли ожидать такого поведения в среде хранения production ?Я могу видеть, как эти поведения будут приемлемы для большинства таблиц, поскольку схема будет в основном статической с течением времени.Возможно, таблицы Windows Azure не были предназначены для такого использования?Если это так, мне, безусловно, придется изменить свой подход.Я также открыт для предложений по альтернативным подходам.