【问题标题】:Azure Table Storage RowKey restricted Character Patterns?Azure 表存储 RowKey 受限字符模式?
【发布时间】:2012-07-15 21:56:54
【问题描述】:

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 中,但我真的很想知道“规则”。

【问题讨论】:

标签: azure azure-table-storage


【解决方案1】:

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

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

延伸阅读Azure Docs > Understanding the Table service data model

【讨论】:

  • 还值得注意的是,虽然您可以在 RowKey/PartitionKey 中包含 %,但尝试检索其键中包含 % 的任何行时会遇到问题。 MS 已意识到该问题并正在寻找解决方案:blogs.msdn.com/b/windowsazurestorage/archive/2012/05/28/…
  • 刚刚发现一个 .也不行。无处可寻。
  • 经期没有问题
【解决方案2】:

我使用这个函数转换密钥:

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

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

【讨论】:

    【解决方案3】:

    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 文章中提到的字符之外,我还在模式中添加了 % 字符,因为我在一些地方看到人们提到它有问题。我想其中一些还取决于您用于访问表存储的语言和技术。

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

    【讨论】:

    • 如 Hans Olav 所述,值得在您的正则表达式中添加“+”号。我认为您以相同的理由在那里添加了 % 符号 - 它允许在密钥中,但很难查询以及 '+' 符号。我不是 100% 确定,但似乎所有 URL 不友好的字符都必须进行编码以进行查询...
    • @DoguArslan - 正则表达式以 verbatim 字符串 \\\\ 开头。如果我没记错的话,在逐字逐句的情况下,只有\\ 在模式上就足以匹配字符串中的\ ?还是我错过了什么?
    • @ShishirGupta 我最近看到了这篇文章,也不得不花点时间来解析正则表达式。当通过测试验证时,这里为什么使用四个反斜杠就很清楚了。它只检查字符串中是否存在\\ ,因为在通过HTTP 传输的数据中任何存在单个\ 都可以充当转义字符并一开始就给出意想不到的结果。因此,该数据需要在通过 HTTP 发送之前进行清理,并且在它到达 Azure 存储时应该只遇到 \\
    • 查询包含 % 或 + 字符的分区或行键没有任何问题(使用存储资源管理器进行测试)。微软似乎在某种程度上解决了这些问题?
    【解决方案4】:

    我刚刚(艰难地)发现“+”号是允许的,但不能在 PartitionKey 中查询。

    【讨论】:

    • 令人惊奇的是,单行插入不会检查+,这会在尝试删除行键中带有+ 的项目时给您带来麻烦。 batch 插入,但是拒绝任何此类项目。
    【解决方案5】:

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

    • |
    • []
    • {}
    • $^&

    使用 Azure Node.js SDK 测试。

    【讨论】:

    • 这个答案应该用一些说明问题的例子来支持。我已经成功地使用上面列出的所有字符作为RowKey 进行批处理请求。没测试过PartitionKey不知道有没有区别。限制(如果有)可能在 Node.js SDK 中(或仅适用于较旧的 Azure 存储 API 版本)。我发现唯一没有记录的是单引号 ' 必须在 URL 中转义,而不是使用 URI 编码,而是使用两个连续的单引号 ' 字符。即' -> ''.
    • 我在分区键中使用空格时也遇到了问题
    猜你喜欢
    • 2018-08-24
    • 1970-01-01
    • 2021-10-16
    • 2012-08-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多