Windows Azure表服务 - 扩展属性和表架构(Windows Azure Table Services - Extended Properties and Table Schema)
我有一个实体,除了一些常见的属性外,还包含一个扩展属性列表,存储为集合中的(Name,Value)字符串对。 我应该提一下,这些扩展属性因实例而异,并且只需要为每个实例列出它们(不会对扩展属性进行任何查询,例如查找具有特定实例的所有实例(Name,价值)对)。 我正在探索如何使用Windows Azure Table Services来持久保存此实体。 使用我现在正在测试的特定方法,我担心随着应用程序遇到更多不同的扩展属性名称,性能可能会随着时间的推移而降低。
如果我将这个实体存储在典型的关系数据库中,我可能有两个表来支持这个模式:第一个将包含实体标识符及其公共属性,第二个将引用实体标识符并使用EAV样式行 - 建模以存储扩展(名称,值)对,每行一个。
由于Windows Azure中的表已经使用了EAV模型,因此我正在考虑对我的实体进行自定义序列化,以便存储扩展属性,就好像它们是在编译时为实体声明的一样。 我可以使用DataServiceContext提供的Reading和Writing-Entity事件来完成此任务。
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不是这样设计的? 如果是这样,我肯定需要改变我的方法。 我也对其他方法的建议持开放态度。
I have an entity that, in addition to a few common properties, contains a list of extended properties stored as (Name, Value) pairs of strings within a collection. I should probably mention that these extended properties widely vary from instance to instance, and that they only need to be listed for each instance (there won't be any queries over the extended properties, for example finding all instances with a particular (Name, Value) pair). I'm exploring how I might persist this entity using Windows Azure Table Services. With the particular approach I'm testing now, I'm concerned that there may be a degradation of performance over time as more distinct extended property names are encountered by the application.
If I were storing this entity in a typical relational database, I'd probably have two tables to support this schema: the first would contain the entity identifier and its common properties, and the second would reference the entity identifier and use EAV style row-modeling to store the extended (Name, Value) pairs, one to each row.
Since tables in Windows Azure already use an EAV model, I'm considering custom serialization of my entity so that the extended properties are stored as though they were declared at compile time for the entity. I can use the Reading- and Writing-Entity events provided by DataServiceContext to accomplish this.
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)); } } }
This works, and since I can define requirements for extended property names and values, I can ensure that they conform to all the standard requirements for entity properties within a Windows Azure Table.
So what happens over time as the application encounters thousands of different extended property names?
Here's what I've observed within the development storage environment:
The table container schema grows with each new name. I'm not sure exactly how this schema is used (probably for the next point), but obviously this xml document could grow quite large over time.
Whenever an instance is read, the xml passed to OnReadingEntity contains elements for every property name ever stored for any other instance (not just the ones stored for the particular instance being read). This means that retrieval of an entity will become slower over time.
Should I expect these behaviors in the production storage environment? I can see how these behaviors would be acceptable for most tables, as the schema would be mostly static over time. Perhaps Windows Azure Tables were not designed to be used like this? If so, I will certainly need to change my approach. I'm also open to suggestions on alternate approaches.
原文:https://stackoverflow.com/questions/3076499
最满意答案
在您的匹配字符串中附加通配符(*)应该可以执行您想要的操作。
WHERE MATCH (columnName) AGAINST ("term*");
编辑:哦,你需要:
IN BOOLEAN MODE
以及使用通配符匹配。
Appending a wildcard (*) to your match string should do what you want.
WHERE MATCH (columnName) AGAINST ("term*");
EDIT: oh, and you'll need:
IN BOOLEAN MODE
as well to use wildcard matching.
相关问答
更多-
您可以在选择中使用案例 CASE WHEN Left(`colname`, 5) = 'BC - ' THEN CONCAT('Business Continuity: ', SUBSTRING(`colname`, 6)) WHEN Left(colname, 3) = 'BC ' THEN CONCAT('Business Continuity: ', SUBSTRING(`colname`, 4)) WHEN Left(`colname`, 3) = 'BC-' THEN CONC ...
-
使用此模式的效率非常低,因为您需要对每次搜索进行全表扫描。 我将添加一个表,其中包含所有可能的子字符串到行ID的映射 Using this schema will be highly inefficient as you'd need full table scan for each search. I'd add a table with mapping of all possible sub-strings to row ids
-
Substring()出错(Error with Substring())[2022-05-22]
在PowerShell中,子字符串的工作方式略有不同。 使用现有代码,您可以尝试: $fileName = "Name of TheFolder_NE_ED" $lengthFileName = $fileName.length $shortenLengthFileName = $lengthFileName - 5 Write-Host("Name of TheFolder_NE_ED").Substring($shortenLengthFileName) 说明: Substring中的第一个参数应该是 ... -
substring1 or substring2 or substring3 假设substring1不是空字符串,则此表达式求值为substring1因为substring1是truthy。 然后检查它是否在string 。 其他子字符串对语句没有影响。 换句话说,这些or是在进入之前评估的,并且评估它找到的第一个真值(这被称为短路)。 你不能用这种方式来检查多个子字符串是否在字符串中。 你要: substring1 in string or substring2 in string or substr ...
-
SELECT FROM your_table WHERE Text2 LIKE '%yourstring%'; SELECT FROM your_table WHERE Text2 LIKE '%yourstring%';
-
你可以尝试这样的事情。 这是sqlfiddle select case substring(mystring,1,1) when 'G' then 'Green' when 'R' then 'Red' else '?' end as mycolumn from test; You could try something like this . Here is the sqlfiddle select case substring(mystrin ...
-
这个怎么样? select SUBSTR(usertext, INSTR(usertext, 'sunday'), length('sunday')) from myTable where CONCAT(' ', usertext, ' ') rlike ' sunday '; 如果您确定总是搜索完整的单词,那么更简单的版本可以是: select SUBSTR(usertext, INSTR(usertext, 'sunday'), length('sunday')) from myTable wh ...
-
在您的匹配字符串中附加通配符(*)应该可以执行您想要的操作。 WHERE MATCH (columnName) AGAINST ("term*"); 编辑:哦,你需要: IN BOOLEAN MODE 以及使用通配符匹配。 Appending a wildcard (*) to your match string should do what you want. WHERE MATCH (columnName) AGAINST ("term*"); EDIT: oh, and you'll need: ...
-
如何为MySQL中的每一行获取可变大小的子字符串?(How to get a substring of variable size for each row in MySQL?)[2023-04-13]
好吧,最后我明白了(感谢大家的贡献),这是最终的结果查询: select substring(subcolumn, 9,5) as Field1, substring(subcolumn, 24) as Field2 from ( select substring(COLUMN, 1, locate('\n',COLUMN,15)) as subcolumn from table ) as X 知道字符串“Field1:”和“Field ... -
select substring('abc@hotmail.com,xyz@yahoo.com,pqr@company.com', instr('abc@hotmail.com,xyz@yahoo.com,pqr@company.com', ',') + 1) as first; select substring('abc@hotmail.com,xyz@yahoo.com,pqr@company.com', instr('abc@hotmail.com,xyz@yahoo.com,pq ...