They have similar names but solve completely different problems. JSONB is just a binary representation of JSON, with the same limited set of data types. It doesn't provide "decimal, date, and binary types", which OP identified as part of the draw to BSON.
It originated with MongoDB as their primary storage and interchange format, so I'd assume it at least was meant to be optimized for that purpose.
Either way, like I said, JSONB and BSON are solving slightly different problems—you probably would not choose BSON if you don't need the extra data types, and if you do need the extra data types JSONB can't help you any more than JSON can.
BSON is more like traditional JSON. All collection elements are ended with specific sub element (just like ']' '}' in JSON), you don't need the complete document before output the first byte. So it is streamable and memory efficient when output.
But this also affect decoding. Not prefixed with size means the memory size you need to allocate is unknown at the time of decoding. You may need to allocate more than required amount of memory or grow on demand if you don't know the size at the time that decoding starts.
Beside this, BSON is also an exchange format. There is full spec and you can use it outside of mongodb. (For example, you need to write an object that contains ArrayBuffer to disk? Just serialize it as BSON and write to disk.) While jsonb in progress is just a DB internal representation, you don't actually see the binary format anywhere.
> All collection elements are ended with specific sub element (just like ']' '}' in JSON)
I don't think so. Arrays and documents store the number of elements before the data and don't use a terminator value. Only element names are nul terminated strings.
JSON[B] does work perfectly fine with decimal and float inside postgres and pgsql, e.g. select (data->>'amount')::numeric. The issue is moving that data in and out of postgres (or truly, any other data manager) with precision. If the JSON[B] is {amount: 12.09} then you have no guarantee that someone picking it up outside of postgres uses float conversion which could lead to 12.0899999. With BSON, amount is a decimal128 and stays that way, fromBytes() and toBytes().
> If the JSON[B] is {amount: 12.09} then you have no guarantee that someone picking it up outside of postgres uses float conversion which could lead to 12.0899999. With BSON, amount is a decimal128 and stays that way, fromBytes() and toBytes().
But how is that relevant? With BSON as transfer format you still don't have that guarantee that the client won't misinterpret the data it receives by using bfl8 as its own internal data format after deserialization.
All languages I know have libraries that can decode the numbers from JSON strings into their relevant arbitrary-precision decimal type. If the user doesn't use that, why would it be a failure of JSON[B]/PostgreSQL?
With BSON I am guaranteed that, for example, in Java, when I do `Document d = BSON.fromBytes()`, then `BigDecimal amount = d.getDecimal128('amount')` is non-lossy. `amount` is typed; `double amount = d.getDouble('double')` is an error.
Again, it's not a failure of JSON[B]/postgres. It's what happens when the data carrier (JSON) is just a string with a small inferred type suite. How many times have we run into issues when `{"v": 1.3}` works and `{"v": 1.0}` works but `{"v":1}` gets turned into an `int` by accident?
Fair. A charitable interpretation would be that they're referring to the fact that in BSON you can specify the exact number type you want to use [0], whereas in JSONB you just have one shared number type for all number fields.