The Durable Document Store You Didn't Know You Had, But Did
robots.thoughtbot.com
robots.thoughtbot.com
Ever since we began storing document data as JSON instead of serialized PHP arrays (yes. PHP - I can't port this behemoth to a more convenient language), I was thinking that maybe Postgres would eventually get some way of peeking inside these blobs.
Now that pl/v8 exists, we can. Combined with the right functional indexes, this can make our life much easier and help greatly to either reduce joins or data amounts transmitted between database and application server - both of which are concerning me at particular places - nothing real bad yet, but potentially.
Thanks a lot for posting this article. You might have just made my day.
I know igbinary exists to solve that, but it would make debugging something using psql even worse.
Also, there is no formal specification for the output of serialize() and there is some talk about changing the format sometime in the future. While they could have unserialize() understand both formats and serialize only write the new one, it would mean that I have to play catch-up and fix my code as the format changes.
As I would probably never really have time to do it, this would crate a fixed dependency on an old version of PHP which a) would preclude me from using new language features and b) would get me into trouble as distros update and the last version which writes the current format falls out of support.
Then there are also some encoding issues which are too complicated to explain here but basically force you to store the output of serialize() in a bytea column which again sucks for quick psql-based inspection and for PDO access which converts bytea fields into streams. See http://pilif.github.com/2011/09/serialize-mistake/ if you are really interested in how I f'ed up.
No. JSON only had advantages for me and now I get one more huge additional advantage without having to write even a single line of C code.
On a related note: do have a look at the sourcecode of unserialize() - it was generated by some parser generator and is completely unreadable on casual glance, forcing me to dive even deeper into PHPs build system were I to rebuild unserialize() as a Postgres extension, which I don't want to do anyways for all the other reasons.
PS: no, looking at the output of serialize() and kinda sorta inferring the format and then building a quick parser is a recipe for disaster. Think escaping. Think arbitrary data types, think nesting. Are you sure you can hack together a parser which is guaranteed to be correct in all cases?
It's also nice because it supports partial updates of the XML documents do that concurrent updates don't clobber each other during some kind of horrible read-then-write dance.
It would be really great to have first class JSON support at the level of this XML support built-in though. Certainly could convince some potential MongoDB converts to stay put.
It is a really cheap way of adding in XML data documents that are small-ish and infrequently used. We typically extract a field or two from the XML doc.
I wouldn't do it for really big XML docs (for some definition of really big) but it is handy for thousands of little XML docs.
Do other databases handle compression and querying simultaneously?
I recently used this strategy for storing raw XML data that we are receiving in the background from an API. We parse it, normalize some of it out to our own data model, but keep the raw XML around.
This is why you might not want to parse the XML: Maybe you don't control the XML schema or its upgrade schedule. If the API you're querying decides to add additional fields, you won't see them until you rewrite your parser.
Or if the API doesn't return perfectly consistent field sets (e.g. perhaps you're actually querying many different APIs to populate the same table, like a table storing the raw RSS feed output from a thousand websites) then you'll either drop the inconsistent portions on the floor or enjoy the thrill of maintaining one parser per possible result fieldset, plus a SQL schema that captures the intersection of all possible result fieldsets.
There's a case to be made that, by storing XML documents in a field, you've managed to violate first normal form. And it's generally downhill from there.
I think you've missed my point.
Storing XML in a field defeats normalisation and the benefits flowing there from. Being able to query it with XPath just doubles the number of query languages that I will need to know and keep track of in the database.
If you want to store XML blobs, use the file system and XPath to your heart's content.
If you want to talk to an arbitrary webservice as though it were a local table you can use www_fdw (Foreign Data Wrapper) https://github.com/cyga/www_fdw/wiki/Examples
And if you're doing geo stufff PostGIS speaks GeoJSON.
That is, if Postgres integrity checks would even allow HTML, which I'm guessing it probably wouldn't....