Azure表存储RowKey限制字符模式?

时间:2012-07-17 01:01:16

标签: azure azure-table-storage

Azure TableStorage RowKeys中是否存在受限制的字符模式?我无法通过大量搜索找到任何记录。但是,我在某些性能测试中会遇到这样的行为。

我有一些奇怪的行为,RowKeys包含随机字符(测试驱动程序确实阻止了受限制的字符(/ \#?),并阻止在RowKey中发生单引号)。结果是我有一个RowKey,可以很好地插入到表中,但无法查询(结果是InvalidInput)。例如:

RowKey: 9}5O0J=5Z,4,D,{!IKPE,~M]%54+9G0ZQ&G34!G+

尝试通过此RowKwy(相等)进行查询将导致错误(在我们的应用程序中,使用Azure Storage Explorer和Cloud Storage Studio 2)。我看了一下通过Fiddler发送的请求:

GET /foo()?$filter=RowKey%20eq%20'9%7D5O0J=5Z,4,D,%7B!IKPE,~M%5D%54+9G0ZQ&G34!G+' HTTP/1.1

看起来RowKey中的%54未在过滤器中转义。有趣的是,对于包含此RowKey的批处理XML中包含URI的表存储的批处理请求,我得到了类似的行为。我也看到过带有双引号的RowKeys的类似行为,尽管我还没有分离出这种模式。

有没有人陪我这个行为?我可以很容易地限制RowKeys中出现的其他字符,但是我们真的想知道“规则”。

6 个答案:

答案 0 :(得分:46)

PartitionKey和RowKey字段中不允许使用以下字符:

  • 正斜杠(/)字符
  • 反斜杠(\)字符
  • 数字符号(#)字符
  • 问号(?)字符

有关详细信息,请参阅以下文章: http://msdn.microsoft.com/en-us/library/windowsazure/dd179338.aspx

答案 1 :(得分:13)

public static readonly Regex DisallowedCharsInTableKeys = new Regex(@"[\\\\#%+/?\u0000-\u001F\u007F-\u009F]");

检测无效的表分区和行键:

bool invalidKey = DisallowedCharsInTableKeys.IsMatch(tableKey);

清理无效分区或行键:

string sanitizedKey = DisallowedCharsInTableKeys.Replace(tableKey, disallowedCharReplacement);

在此阶段,您可能还希望使用原始密钥的散列为已清理密钥(分区密钥或行密钥)添加前缀,以避免具有相同清理值的不同无效密钥的错误冲突。

不要使用string.GetHashCode(),因为它可能会为同一个字符串生成不同的哈希码,不得用于标识唯一性,也不得保留。

我使用SHA256:https://msdn.microsoft.com/en-us/library/s02tk69a(v=vs.110).aspx

创建无效密钥的字节数组哈希,将字节数组转换为十六进制字符串,并使用该字符串为已清理的表密钥添加前缀。

另请参阅相关的MSDN文档: https://msdn.microsoft.com/en-us/library/azure/dd179338.aspx

链接中的相关部分: 关键字段中不允许使用的字符

PartitionKey和RowKey属性的值不允许使用以下字符:

  

正斜杠(/)字符

     

反斜杠(\)字符

     

数字符号(#)字符

     

问号(?)字符

     

控制字符从U + 0000到U + 001F,包括:

     
      
  • 水平制表符(\ t)字符

  •   
  • 换行符(\ n)字符

  •   
  • 回车(\ r)字符

  •   
     

控制字符从U + 007F到U + 009F

请注意,除了MSDN文章中提到的字符之外,我还在模式中添加了%char,因为我在一些人们提到它存在问题的地方看到了。我想其中一些还取决于您用来访问表存储的语言和技术。

如果您在案例中检测到其他有问题的字符,那么您可以将它们添加到正则表达式模式中,其他任何内容都不需要更改。

答案 2 :(得分:6)

我发现除了Igorek的回答中列出的字符外,这些也会导致问题(例如插入失败):

  • |
  • []
  • {}
  • <>
  • $ ^&安培;

使用Azure Node.js SDK进行测试。

答案 3 :(得分:6)

我刚刚发现(艰难的)' +'允许使用sign,但不能在PartitionKey中查询。

答案 4 :(得分:2)

我使用此函数转换密钥:

private static string EncodeKey(string key)
{
    return HttpUtility.UrlEncode(key);
}

这当然需要为插入和检索完成。

答案 5 :(得分:1)

除了上述内容之外,您无法在分区键的开头使用下划线_,也会返回一个错误,指出以下划线开头的键不是有效的分区键。< / p>