Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How many bits of integer data can be stored in a DynamoDB attribute of type Number?

DynamoDB's Number type supports 38 digits of decimal precision. This is not big enough to store a 128-bit integer which would require 39 digits. The max value is 340,282,366,920,938,463,463,374,607,431,768,211,455 for unsigned 128-bit ints or 170,141,183,460,469,231,731,687,303,715,884,105,727 for signed 128-bit ints. These are both 39-digit numbers.

If I can't store 128 bits, then how many bits of integer data can I store in a Number?

like image 249
Justin Grant Avatar asked Oct 30 '18 02:10

Justin Grant


People also ask

How many bytes is a number in DynamoDB?

Numbers are variable length, with up to 38 significant digits. Leading and trailing zeroes are trimmed. The size of a number is approximately (length of attribute name) + (1 byte per two significant digits) + (1 byte).

How much data can DynamoDB store?

The maximum item size in DynamoDB is 400 KB, which includes both attribute name binary length (UTF-8 length) and attribute value lengths (again binary length).

How many attributes does DynamoDB allow?

The cumulative size of attributes per item must fit within the maximum DynamoDB item size (400 KB). There is no limit on the number of values in a List, a Map, or a Set, as long as the item containing the values fits within the 400 KB item size limit. Save this answer.


1 Answers

DynamoDB attribute of type Number can store 126-bit integers (or 127-bit unsigned integers, with serious caveats).

According to Amazon's documentation:

Numbers can have up to 38 digits precision. Exceeding this results in an exception.

This means (verified by testing in the AWS console) that the largest positive integer and smallest negative integers, respectively, that DynamoDB can store in a Number attribute are:

99,999,999,999,999,999,999,999,999,999,999,999,999 (aka 10^38-1) -99,999,999,999,999,999,999,999,999,999,999,999,999 (aka -10^38+1)

These numbers require 126 bits of storage, using this formula:

bits = floor (ln(number) / ln (2))
     = floor (87.498 / 0.693)
     = floor (126.259)
     = 126

So you can safely store a 126-bit signed int in a DynamoDB.

If you want to live dangerously, you can store a 127-bit unsigned int too, but there are some caveats:

  • You'd need to avoid (or at least be very careful) using such a number as a sort key, because values with a most-significant-bit of 1 will sort as negative numbers.
  • Your app will need to convert unsigned ints to signed ints when storing them or querying for them in DynamoDB, and will also need to convert them back to unsigned after reading data from DynamoDB.

If it were me, I wouldn't take these risks for one extra bit without a very, very good reason.

One logical question is whether 126 (or 127 given the caveats above) is good enough to store a UUID. The answer is: it depends. If you are in control of the UUID generation, then you can always shave a bit or two from the UUID and store it. If you shave from the 4 "version" bits (see format here) then you may not be losing any entropy at all if you are always generating UUIDs with the same version.

However, if someone else is generating those UUIDs AND is expecting lossless storage, then you may not be able to use a Number to store the UUID. But you may be able to store it if you restrict clients to a whitelist of 4-8 UUID versions. The largest version now is 5 out of a 0-15 range, and some of the older versions are discouraged for privacy reasons, so this limitation may be reasonable depending on your clients and whether they adhere to the version bits as defined in RFC 4122.

BTW, I was surprised that this bit-limit question wasn't already online... at least not in an easily-Google-able place. So contributing this Q&A pair so future searchers can find it.

like image 167
Justin Grant Avatar answered Oct 04 '22 18:10

Justin Grant