10 ms·
The key value store we ignored (Postgresql)
Postgres had this hstore for structure free storage and nobody ever mentions it. This post will hopefully bring attention to something we ignored long ago.
- sqrt17 15y agoIn my opinion, Postgresql + hstore + PLv8js (Javascript as a language for stored procedures, see http://code.google.com/p/plv8js/ http://code.google.com/p/plv8js/) could really rock the world if it became an accepted standard and got some people behind it. It's not so great if you start using something and one year later see that the original authors lost interest and move on, leaving you with 10k lines of code that depend on a pray-for-no-bugs unsupported piece of software.
- grncdr 15y agoTotally agree. I've been building out a new system with hstore and it's been great, planning to do some benchmarking with plv8js as well. If you've got a dataset that you can conceivably scale vertically to accomodate, postgres is a solid and feature-packed database.
- chrismealy 15y agoAnybody using this with rails? https://github.com/softa/activerecord-postgres-hstore https://github.com/softa/activerecord-postgres-hstore
- jashkenas 15y agoYes -- but not with that module. We're using it to tag documents (individual rows in Postgres and Solr) with user-defined metadata. http://blog.documentcloud.org/blog/2011/05/arbitrary-metadata/ http://blog.documentcloud.org/blog/2011/05/arbitrary-metadat... ... which can then be used to power custom indexes of particular collections of documents, like this one: http://www.nytimes.com/interactive/2011/12/02/us/oil-and-gas-leases.html http://www.nytimes.com/interactive/2011/12/02/us/oil-and-gas... The fun bit being, that in both Postgres and Solr, you can still run a precise search (including joins for access control, sharing, and boolean full text clauses) with a single query because the HStore keys and values are indexed.
- tptacek 15y agoHow did you build it? Are you using hstore SQL directly? Do you just have migrations with raw SQL in them?
- jashkenas 15y agoLet's dig through it a bit. Our hstore column isn't directly on the document row, but rather in a joined "docdata" table. There was a semi-raw migration to add it: https://github.com/documentcloud/documentcloud/blob/master/db/migrate/20110429150927_add_data_to_documents.rb https://github.com/documentcloud/documentcloud/blob/master/d... The "Docdata" model handles serializing JSON hashes of keys -> string values into the hstore format, and parsing 'em back out. This is a little loose, but works for most of the simple things you'd like for tagging documents (senator: Kerry, statecode: WV, recordid: 019281) https://github.com/documentcloud/documentcloud/blob/master/app/models/docdata.rb https://github.com/documentcloud/documentcloud/blob/master/a... ... the resulting effect is that from the Rails side, working with "document.data" directly is like working with a lazy-loaded hash. The more interesting bit is the search side of things, here's the query parser and query object (which generates SQL and Solr queries): https://github.com/documentcloud/documentcloud/blob/master/lib/dc/search/parser.rb https://github.com/documentcloud/documentcloud/blob/master/l... https://github.com/documentcloud/documentcloud/blob/master/lib/dc/search/query.rb https://github.com/documentcloud/documentcloud/blob/master/l... ... for any given query, we detect if Solr is required (if full-text is involved), or if the search can be satisfied purely in Postgres. So there's one way of generating the key:value query for each back end. Hope that answers the question. (Edit:) Forgot to mention that we add a little extra on top of vanilla hstore "key:value" queries. You can write "dob: *" to show documents with any senator tagged, and "dob: !" to show documents that haven't been tagged with a date of birth yet.
- tptacek 15y agoThis is awesome, thank you (didn't think to check if you were in Github, but the explanations are great too).
- ruckusing 15y agoI built this gem for ActiveRecord hstore serialization. Uses ActiveRecord 3.1+ custom serializer hooks. https://github.com/ruckus/active_record_hstore_serializer https://github.com/ruckus/active_record_hstore_serializer
- deleted 15y ago[deleted]
- sciurus 15y agoDid you click the link? Unless I'm missing something, it's completely different content. One submission focuses on Postgres's hstore data type, and the other focuses on its XML data type.
- protik001 15y ago@chrismealy.. http://croak.eu/rTBVKX http://croak.eu/rTBVKX
- nullymcnull 15y agoQuit spamming this bullshit here. HN is a text-based discussion forum.
- henrikschroder 15y agoThe main selling point of the various NoSQL products out there today isn't the schemaless storage, instead it's the ability to grow beyond a single server that's compelling. 228MB of data is nothing, it fits in RAM of any machine. What would the examples in this blog post look like if it was 228GB of data spread across 10 servers instead? How would you grow/shrink such a cluster? How would you perform a query that cuts across servers and aggregates data from some of them? How would you replicate data across multiple servers?
- sqrt17 15y agoThe trick is, you wouldn't necessarily. If your workload can be handled with one beefed-up lots-of-RAM-and-solid-state-drives server, you could spend your money on two of these instead of having 10 smaller servers, and be perfectly happy with it. I don't care about what sells NoSQL products to enterprise users - there are lots of workloads where the data fits in RAM (for some reasonable quantity of RAM that money can buy) and you still prefer the durability and consistency that comes with standard SQL databases, even if you denormalize and/or use schemaless (XML or JSON) storage.
- mulander 15y agoEach database worth its salt will use as much memory as you allow it to use in order to avoid physical IO. Your point is valid of course. I just wanted to point it out for people that think each action in a RDBMS results in a costly IO operation.
- maxpert 15y agoI think for schema-less storage systems we know 2 major competitors in market. MongoDB and CouchDB. - CouchDB by default has not ability to scale out except master master replication, solution? Sharding for distribution and Replication for reliability. Or you BigCouch with prayers that it won't trash out your data. - MongoDB is know to stand on its Sharding server mongos and you have to issue sharding commands whenever you scaleout and rebalance. So its again Sharding for distribution and Replication for reliability! - Postgres -> Reliable in storage than both if you do same Sharding and Replication yourself :). I am in no way substituting or saying 228MB is enough data! I would rather hate MongoDB for being RAM hungry and storing same 115k tweets in Gigabytes of memory (256MB is just like a started of 100 Course meal for MongoDB). Again Facebook ultimately prefers his data to go to MySQL and they have largest 600 shard for a reason!
- solitaire 15y agoDocumentation about hstore in postgresql http://www.postgresql.org/docs/9.1/static/hstore.html http://www.postgresql.org/docs/9.1/static/hstore.html
- 7952 15y agoI tried hstore on a project for many of the reasons mentioned. I just hated having to always represent data as strings.
- tptacek 15y agoIsn't this effectively what Redis does too? There are whole Salvatore posts about doing binary data structures in Redis string values.
- iFire 15y agohttp://redis.io/topics/data-types http://redis.io/topics/data-types Strings are the most basic kind of Redis value. Redis Strings are binary safe, this means that a Redis string can contain any kind of data, for instance a JPEG image or a serialized Ruby object.
- saurik 15y agoI am confused by this comment. In the PostgreSQL protocol, everything is a string if you use the text protocol, but you can also use the binary protocol, in which case there is a reasonable binary storage format for hstore. It is even more confusing, as whichever protocol you use seems like an implementation detail of your driver: at the level of an application you should only be working with dictionaries.
- mikeytown2 15y agohow does this compare to MySQL's HandlerSocket?
- maxpert 15y agoI haven't done benchmarks yet but if you are looking for HandlerSocket benchmarks http://blog.creapptives.com/post/3329352663/the-nosql-dogma http://blog.creapptives.com/post/3329352663/the-nosql-dogma is the link
- mikeytown2 15y agoThose benchmarks are very flawed as HandlerSocket only works in InnoDB. This is a better post on the subject: http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-as-nosql-story-for.html http://yoshinorimatsunobu.blogspot.com/2010/10/using-mysql-a...
- djb_hackernews 15y ago> ...database grew to a size of 239691780 bytes (Just 228MB) > ...gives me 14689 rows just under 360ms on average Uh, 360ms seems like an awfully long time to query such a small dataset.
- joevandyk 15y agoI think that includes the time to transfer the data.
- djb_hackernews 15y agoI sure hope not. That's usually not the way you benchmark database queries.
- cbs 15y agoThen its a good thing that line in the article had nothing to do with benchmarking a database query.
- Jugglernaut 15y agoThe point of the article wasn't how fast the query ran, nor is the hardware specified. Without that information any assessment of speed is meaningless.
- jedberg 15y agoreddit used (and still for the most part uses) postgres as a schemaless storage (although they don't use hstore). Also, I'm pretty sure Heroku uses hstore, because they're the ones that taught me about it. So not everyone forgot about it.
- imbriaco 15y agoI agree with the author that hstore is very interesting, but the data structures are not the key selling point in the NoSQL space in my opinion. The most overlooked advantage to things like Cassandra and Riak are the fact that you have no single point of failure in the system. If an individual node fails, there is no operational impact. Postgres does have (finally!) a nice replication story, so you have data protection on a second server, but the failover mechanics are much more complicated and you still have a single point of failure at the master/writer node. The story gets even more operationally complex when you talk about sharding and the fact that you now have to have a replica per master -- and it really needs to be the same size as the master if you want to be able to trust that you have enough capacity to fail over to it. Suddenly you need to have half of your database capacity sitting idle. Now, don't get me wrong, I think Postgres is a wonderful database server. For the vast majority of applications it is the correct default choice. Very few applications ever get to the point where they need to scale further than they can get vertically on a single node and most can tolerate a few minutes of downtime to fail over to a backup server. Hand-wavy "sharding is easy" comments, however, ignore a lot of operational reality and that's dangerous. Understand your use case. Understand the failure modes. Decide how available your datastore needs to be and how much data you need to support. Know the consequences of the choices you make.
- maxpert 15y agoI totally agree with just what your said, this post actually is meant for know your choices. I actually hate it when people make a lame excuse of using a NoSQL store when they don't need it and they don't know the consequences!
- fauigerzigerk 15y agoAgreed, but of course the massive write parallelism and fault tolerance of DBMS like Cassandra comes at the cost of dropping ACID, which may cause a lot of complexity elsewhere in the system. It also comes at the cost of limiting the types of queries you can perform without resorting to procedural code (at least in the case of column family based architectures). In other words, it comes at the cost of productivity. So, even if sharding is not easy, you can do quite a lot of it in the time you save by not having to code around the limitations of most noSQL DBMS. The day will come when RDBMS are secret productivity weapon of smaller companies that don't feel they have to act like they were Google. That said, there are very good reasons not to use RDBMS in cases where the data model or specific access patterns just don't fit. But in most of those cases, I find that using in memory data structures combined with file system storage or something like BerkeleyDB is a much better fit than any server based DBMS.
- keeran 15y agoThoughtbot posted a similar Postgres article recently: http://robots.thoughtbot.com/post/13829210385/the-durable-document-store-you-didnt-know-you-had-but http://robots.thoughtbot.com/post/13829210385/the-durable-do...
- zobzu 15y agoI've been using a lot of MySQL and some NoSQL solutions over the years. I don't need most of what NoSQL is supposed to offer and uhm, a couple of years ago I tried PGSQL. I've never found the same level of finish, performance, etc. It's also very customizable and very dependable. You can get extremely good performance out of it. Finally... the devs are plain AWESOME. Every time I had an issue, question, etc, not even necessarily related to PGSQL but to SQL and performance in general they would reply quickly, and accurately (I owe one of them many, many beers). To give you an example, a company I worked for was doing a 10M to 10M comparison (for very specific needs). All businesses we have found were using custom NoSQL solutions, or even Oracle, with huge clusters, costing a lot, and taking ~24h for a result. So we implemented ours. After a year of testing, coding, etc, it was settled on PGSQL (on FBSD), with the help of the said dev, we were doing the same comparison,in 3H, on a single quad core system (with heaps of ram). Sure, maybe the other businesses never cared that much for performance, but its still astonishing. Most optimizations were made thanks to PGSQL's dev help were usually speeding up the process by thousand of times. Disclaimer: I can't detail the comparison (its still under NDA), but it included very specific stuff, in case you wonder about the time taken, etc.
- smosher 15y agoFinally... the devs are plain AWESOME. About 10 years ago I had cause to look at the source and I have to say I don't think I've ever seen better written C. The changes we were considering were vetoed, but I marveled at how easy it was to identify the place I would have needed to make the changes and verify that they would not have unintended consequences. I don't know if it still does, but the code I saw back then read like a book.
- einhverfr 15y agoFinally... the devs are plain AWESOME. A few years ago I got a dreaded call from a customer. A point of sale system was taking 45 seconds suddenly to post invoices. This is a big deal for a cash register role, as you can imagine. So I went on site, ran some diagnostics, isolated the problem query, etc. At this point they were into the slow part of the afternoon so I asked about it on the -perform list along with query plans and everything else I could think of. Within an hour I had received an email from Tom Lane explaining: 1) What the planner was getting wrong 2) Why the planner was making an error there, and why this was a special planner case. 3) Giving me suggestions as to how to fix it. First rate support, let me tell you. (Also, planner behavior was changed in a release soon after to accommodate my use case.)