【问题标题】:ItemSize in DynamoDBDynamoDB 中的项目大小
【发布时间】:2012-02-17 18:59:52
【问题描述】:

我正在尝试计算 dynamoDB 中项目的大小,但我无法理解定义。

我找到的定义:项目大小是其属性名称和值的长度之和(二进制和 UTF-8 长度)。因此,如果您保持属性名称简短会有所帮助。

这是否意味着如果我在数据库中输入一个数字,例如:1,它会占用一个 int 的大小?沿着?双?它会占用与 100 或 1000000 相同的空间还是只占用相应二进制文件的大小?

String 的计算方法是什么?

有人知道如何计算吗?

谢谢

【问题讨论】:

    标签: amazon-dynamodb


    【解决方案1】:

    这确实是一个重要的话题 - 您已经引用了 Amazon DynamoDB Data Model 中有些草率的定义:

    项目大小是其属性名称和值的长度之和 (二进制和 UTF-8 长度)。

    这在Amazon DynamoDB Data Types 中的页面下方有更详细的说明:

    • 字符串 - 字符串是带有 UTF8 二进制编码的 Unicode。
    • 数字 - 数字是正或负的精确值小数和整数。一个数字在小数点后最多可以有 38 位精度,并且可以在 10^-128 到 10^+126 之间。 Amazon DynamoDB 中的表示是可变长度的。前导零和尾随零被修剪。

    Amazon DynamoDB forum 中也提出了与您类似的问题(请参阅Curious nature of the "Number" type),answer from Stefano@AWS 更清楚地说明了这个问题:

    • “数字”类型有 38 位精度这些是实际的小数 位数。所以它可以表示相当大的数字,并且没有 精度损失。
    • Number 值占用多少空间? 不太 很多。 我们的内部表示是可变长度的,所以大小是 与值中的实际(相对于最大)位数相关。 顺便说一句,前导零和尾随零被修剪。 [强调我的]

    Christopher Smith's follow up post 提供了更多关于存储消耗及其计算的结果的见解,他总结道:

    现有 API 对存储的了解很少 消费,即使那是一部分(诚然不是 显着)的计费。唯一的信息是汇总 表大小,甚至这些数据也可能不同步数小时。

    虽然 Amazon does not expose it's billing data via an API yet,但他们希望在某个时候向 DynamoDB API 添加一个选项来检索有关项目大小的一些信息,正如 Christopher 所建议的那样。

    【讨论】:

    • 不幸的是,这是模糊的。 Postgres 还存储具有“可变”长度的小数 - 除了它使用的二进制格式仅用于开销(至少在二进制副本导出格式中)占用 8 个字节。我希望 AWS 做得更好!
    • 注意:在 DynamoDB (DDB) 中,数字作为字符串保存,因此考虑了可变长度(123 vs. 1.23456 vs. 123,456,789.1)。在检索值时,它们将转换为正确的数据类型。任何项目的大小都是属性名称的大小加上所述的值。此外,“项目”不需要在表中具有相同的属性(通过省略“放置”操作中的属性来实现)。因此,每个项目可能具有不同的大小。 CAP 上的 DDB:“可用性”和“分区容错”优于“一致性”。
    • 再强调一点——添加到表中的每个全局二级索引都会根据该表中的数据量增加数据使用量。您可以将其视为创建一个单独的表,该表自动与父表保持同步。您可以决定是否保留部分、全部或仅索引表键,以便您可以控制存储与可访问性(递归查询的吞吐量权衡)。目标:让用户灵活地定义他们的索引而不是开销 RDBMS 在数据结构上的位置。
    • 如果我在项目中包含列表,DynamoDB 会占用任何内存开销吗?当我以列表的形式插入数据时,DynamoDB 以映射的形式显示列表中的每个值,以了解该特定项目属于哪种数据类型。 "s":"Pur123112",是列表中的一个值,它指定该值属于字符串数据类型{ "Customer ID":"123412341234", "Year":"2016" //stored as a number "Purchase ID":["S":"Pur123112","S":"Pur12317",...100 values], "Date of Purchase":["S":"2016-04-20","S":"2016-05-01",...100 values] }
    【解决方案2】:

    我在 Clarence@AWS 回答的亚马逊开发者论坛中找到了这个答案:

    例如:-

    "Item":{
    "time":{"N":"300"},
    "feeling":{"S":"not surprised"},
    "user":{"S":"Riley"}
    }
    

    为了计算上述对象的大小:

    项目大小是属性名称和值的长度之和, 解释为 UTF-8 字符。在示例中,字节数为 因此,该项目是

    Time : 4 + 3 
    Feeling : 7 + 13 
    User : 4 + 5          
    

    36

    正式定义见: http://docs.amazonwebservices.com/amazondynamodb/latest/developerguide/WorkingWithDDItems.html

    【讨论】:

    • 这个答案对我来说似乎很可疑,因为你在计算字符,而不是字节。如果字符串是 UTF-8(作为另一个答案报告),则不能用一个字节表示一个字符。
    • 这个答案中也提到了“项目大小是属性名称和值的长度之和,解释为 UTF-8 字符”。一个 utf-8 字符可以占用 1-4 个字节。 “this”示例计算中给出的每个字符仅占用 1 个字节。 (只需在此处查看长度:mothereff.in/byte-counter
    • 这似乎相当准确。我有一个非常大的项目(其中有超过 16,000 个值),上面的公式完全匹配 get-item 返回的消耗容量 (6) 乘以 4K。而删除空格的原始 JSON 输出本身(来自 aws-cli)超过 100K。
    • 所以 Dynamo 用 3 个字节来表示数字300,太奇怪了。 @AsangaDewaguru 你还有 AWS 论坛上答案的链接吗?谢谢
    【解决方案3】:

    一个项目的大小是其所有属性大小的总和,包括哈希和范围键属性。 属性本身具有名称和值。名称和值都会影响属性的大小。 名称的大小与字符串值的大小相同。所有值的大小都根据其数据类型而不同。

    如果您对细节感兴趣,请阅读this blog post

    否则,我还创建了一个 DynamoDB Item Size and Consumed Capacity Calculator 来准确确定项目大小。

    数字很容易成为 DynamoDB 中最复杂的类型。 AWS 没有公开记录如何确定一个数字中有多少字节。他们说这是为了让他们可以更改内部实现,而无需任何人与之绑定。然而,他们所说的听起来很简单,但在实践中却更加复杂。

    不过,非常粗略地说,该公式类似于 每 2 个有效数字加 1 个字节,正数加 1 个额外字节,负数加 2 个字节。因此,27 是 2 个字节,-27 是 3 个字节。如果位数不均匀,DynamoDB 将四舍五入,因此461 将使用 3 个字节(包括额外的字节)。在计算大小之前修剪前导零和尾随零。

    【讨论】:

      【解决方案4】:

      您可以在 DynamoDB Storage Backend for Titan DynamoDBDelegate 类中使用计算 DynamoDB 项目大小的算法。

      【讨论】:

      • 有 .net 等价物吗?
      • 对于 Titan 的 DynamoDB 存储后端还是项目大小方法?两者的答案是否定的,但移植项目大小方法应该很简单。
      • 如果你关心更准确的数字,算法是不够的。它遗漏了长度和类型数据。
      【解决方案5】:

      以上所有答案都跳过了存储属性长度以及属性名称长度每个属性的类型的问题。

      DynamoDB Naming Guide 表示名称的长度可以是 1 到 255 个字符,这意味着 1 字节的名称长度开销

      我们可以从 400kb 的最大项目限制开始计算,以了解二进制或字符串项目所需的长度上限 - 它们不需要存储超过 19 位的长度数字。

      使用一点自适应编码,我会期待

      • 数字具有 1 字节的前导类型和长度值,但也可以编码为单个字节(例如:零值数字的特殊代码,后面没有 值字节
      • 字符串和二进制有 1-3 个字节的前导类型和长度
      • Null 只是一个没有值的类型字节
      • Bool 是一对类型字节,没有任何其他值
      • 集合类型有 1-3 个字节的前导类型和长度。

      哦,DynamoDB 不是 无模式。它是 schema-per-item,因为它存储了所有这些可变长度项的类型、名称和长度。

      【讨论】:

        【解决方案6】:

        一个项目在您的 DynamoDB 表中占用多少的近似值是使用 boto3 库进行获取请求。

        这不是关于元素大小的精确解决方案,但它会帮助您产生想法。执行batch_get_item(**kwargs) 时,您会收到包含ConsumedCapacity 的响应,格式如下:

        ....
        'ConsumedCapacity': [
            {
                'TableName': 'string',
                'CapacityUnits': 123.0,
                'ReadCapacityUnits': 123.0,
                'WriteCapacityUnits': 123.0,
                'Table': {
                    'ReadCapacityUnits': 123.0,
                    'WriteCapacityUnits': 123.0,
                    'CapacityUnits': 123.0
                },
                'LocalSecondaryIndexes': {
                    'string': {
                        'ReadCapacityUnits': 123.0,
                        'WriteCapacityUnits': 123.0,
                        'CapacityUnits': 123.0
                    }
                },
                'GlobalSecondaryIndexes': {
                    'string': {
                        'ReadCapacityUnits': 123.0,
                        'WriteCapacityUnits': 123.0,
                        'CapacityUnits': 123.0
                    }
                }
            },
        ]
        ...
        

        从那里您可以看到它占用了多少容量单位,并且您可以提取项目的近似大小。显然,这是基于您的系统配置,因为:

        一个读取请求单元代表一个高度一致的读取请求,或两个最终一致的读取请求,用于大小不超过 4 KB 的项目。事务性读取请求需要 2 个读取请求单元才能对不超过 4 KB 的项目执行一次读取。如果您需要读取大于 4 KB 的项目,DynamoDB 需要额外的读取请求单位。所需的读取请求单元总数取决于项目大小,以及您想要最终一致还是高度一致的读取。

        【讨论】:

          【解决方案7】:

          最简单的方法是在表中创建一个项目并将该项目导出到 csv 文件,这是 DynamoDB 中可用的一个选项。 csv 文件的大小将为您提供大约项目大小。

          【讨论】:

          • 那不是真的。此 CSV 文件中还有元数据 - 例如每个属性、括号、空格等的类型信息。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-02-09
          • 1970-01-01
          • 2018-10-16
          • 1970-01-01
          • 1970-01-01
          • 2011-08-07
          相关资源
          最近更新 更多