NoSQL Databases: A Survey and Decision Guidance
medium.com
medium.com
At work, it doesn't matter if we have a perfect use case for a particular NoSQL solution (I'm working on something now that I think would be a great fit for a Graph database like Neo4J). We use Oracle, because it's expensive, we're already paying for it, so damn it, we're going to use it.
That would be the single biggest difference... Neither have particularly great DBAAS offerings, outside of RDS Postgres, though if you're on Amazon, you can use Compose.io's rethinkdb option there too.
RethinkDB has sharding + redundancy similar to ElasticSearch or Cassandra, while having some other features that put it more in line with an SQL rdbms, while having an administrative UI that's second to none.. and I mean none.
If I'm doing something where I'm storing JSON (e.g., from an external service), but only care about certain bits of it, I'll store the bits I care about in columns, then put the whole JSON object into a jsonb column.
The key advantage that I see is that when I decide that a new piece of the JSON needs to be cared about, I can do something like this:
(modify data types as required)
ALTER TABLE blah ADD COLUMN newthing text;
CREATE INDEX ON blah.newthing; -- if needed
UPDATE blah SET newthing = jsoncolumn->>'new_thing';Just add an expression index for your new field:
CREATE INDEX ON blah BTREE ((jsoncolumn->>'new_thing'));
Then, the following kind of queries are blazingly fast due to the index: SELECT * FROM blah WHERE jsoncolumn->>'new_thing' = 'some_value';
This is less error prone than managing the consistency of the additional columns on your own. And if you still need some kind of pseudo-table, consider creating a simple view for that.[1] https://www.postgresql.org/docs/current/static/indexes-expre...
If the table is already fairly large you'd have to use Postgres CREATE INDEX CONCURRENTLY to avoid locking the table while it sorted out the index. The only downside is that you have very little control of the process.
If you already have the data available in a JSONB column you can create the column, create the index and then set your app code to look to the JSON data if the column is null during transition while a background job goes through and populates rows either individually or in smaller batches to avoid disrupting user experience.
eg
create index on blah((jsoncolumn->>'new_thing'));
although I haven't tried it myself yet, I've been meaning to play with that feature.The advantage of Neo4J is that its query language is explicitly optimized for the graph use case, whereas querying a relational database as a graph engine would necessitate fairly complex SQL.
One way to think about relationships in graph databases is as materialized joins. Relationships are modeled and stored explicitly so there is no join at query time, only a constant time graph traversal. There are differences in flexibility of data model, ease of expressing traversals in the query language, etc but I think traversal vs JOIN is a good way to compare relational vs graph.
Example: News Feed - JOIN with my friends - JOIN recent posts - JOIN topics / keywords that I tend to care about - Filter by people I interact with more - Filter out shared posts from sources I ignore - Sort by some combination of recency, likes, likes from my friends
The idea, it seems, is to be optimized for wide joins.
- It is Open Source under MIT license, very liberal, at no cost.
- It has property graph features like Neo4j.
- It does realtime updates, like Firebase.
- You can store JSON and Relational Documents, like RethinkDB.
- Offline first (or mobile first), like CouchDB.
- Upcoming release has been benchmarked at 25M+ reads/sec and 6K+ writes/sec.
- The community is really friendly and accepting.
However, re: document store, I've been bouncing Postgres around in my head for that: all required columns (ie, columns that always exist, or will be queried on) are normal SQL columns, everything else is stashed in one or more hstore columns.
This has the same problem as most NoSQL solutions: You don't get the benefit of a schema, and schemas are damn useful things.
The alternative I've also been bouncing around in my head is multiple tables: objects (rows in the "primary" table) have traits (rows in "secondary" tables with identical primary keys) that break out columns according to what they do.
Having 9000 columns in a single table is a bit unwieldy.
Everything does. Data without schema are just noise.
The real question is whether you'll enforce it at the DB level (and suffer from inflexibility) or enforce it at the code level (that, obviously, should know what field is what, and which fields are available, e.g. enforcing a schema at runtime) and get potentially corrupted data, management overhead, etc.
Love that concise adage. Will probably adopt it when explaining databases to novices.
Any good examples?
You may know some invariants, but much can change without notice. So you want to be able to work with the structure you have without preventing non-conforming data from entering your system.
In some cases schema conformance is just delayed, in other cases it is never achieved completely or not even a goal.
Can you give a more specific example?
A similar thing happens when you retrieve data on securities and companies from various exchanges, from the SEC, from national registries all over the world or you try to include XBRL from different countries.
And then you often have documents (like quarterly reports) that contain structured fields and tables but not in a formally specified syntax. You don't know exactly what fields will be in those documents before you parse them. So you parse the documents, store key/value pairs, and then you clean them up gradually.
There are tons of situations like this in data integration. It's a never ending cleanup and merge process. You can use RDBMS for all of that but they're not always the best tool for the job (but they are still my preferred tool most of the time).
We need to store the key/value pairs and explore them in a reasonably productive fashion (i.e using queries) in order to come up with machine learning algorithms. And any new algorithms we write need access to all historical data.
Similarly, events.
The source entity, more often than not, is also complemented with other data that needs to remain a part of the persistence layer.
Imagine you want to store random metadata from a digital camera picture, or perhaps even XML/HTML attributes. You can create another table and add each new attribute – join on query – but if you don't plan to search for that data directly, it's easier to skip normalisation and dump the original set into a JSON(B) or HStore field. You don't have to add every possible attribute to your data model or schema, you can carry data along and not analyse it if it's not relevant to you.
Which looking at the table, doesn't seem to include Aphyr's work (Jepsen), so much of what is being said may in fact be wrong. I'd prefer a chart populated from that (though admittedly such a chart would largely be "undefined", "inconsistent", etc).
For more information, read the excellent blog posts from their official blog: https://blog.couchdb.org/
In any case I will be happy to update the article and include it.
(Ignore that it's under /en/1.6.1, built-in clustering is 2+ only.)
I'm really excited about CouchDB 2.0.
I'd love to see something similar on the various ETL/data pipeline tools. In that regard, we still write a ton of SAS code because we have a variety of sources, which SAS does well, pretty solid if you need to do some data cleansing into the target, and the code itself is very batch-friendly and maintainable. It's been a while since I've surveyed alternatives.
It feels like a second-generation NoSQL database where most of the drawbacks with earlier NoSQL-databases has been taken care of!
1: https://codahale.com/you-cant-sacrifice-partition-tolerance/
i personally use Cloud DataStore and find it a great fit, wish there was some comparisons against it.
This is a bit misguided, redis cluster has been in GA for over a year.
But you are right, I think Redis Cluster could be added as a separate system.
[1] https://aphyr.com/posts/283-jepsen-redis [2] https://github.com/antirez/redis/issues/2672
1) It is true that Redis is not AP or CP, but this is not covered by [1] that covers Redis Sentinel (a previous version with different behavior compared to Sentinel v2 btw). So, while Redis Cluster is just an eventually consistent system that does not guarantees strong consistency nor availability (so is not AP nor CP), the pointed post is not related.
2) Redis Cluster is very scalable actually, since it is a flatly partitioned no-proxed system. Pub/Sub is not very scalable in Redis Cluster but Pub/Sub is a minor sub-system of Redis, most users look at the ability to scale the key-value store that is... 90% of what Redis is, so I think your claim is not justified.
3) The fact of not being AP or CP does not mean that a system is not useful. Depends on the business requirements. In fact, most SQL databases + failover setups, that is what takes a seizable portion of the big services of the internet up, are not AP or CP as well.
Database systems features are related to use cases, I believe that the Redis Cluster properties cover a huge set of real world use cases, in fact is the most actively mentioned/requested feature right now, even if we document in very clear terms the tradeoff and the actual behavior of the system. So people know what they want. IMHO excluding systems because of what you think being acceptable tradeoffs is not a good idea.
Otherwise you should also mention that SQL+ Main_widely_used_failover_solutions systems have the same unacceptable shortcomings, for instance.
Actually if the Redis Cluster implementation will be made the center of the future Redis development, it could easily become the most used sub-system of Redis, like Sentinel is already becoming. There are many devs that know what they are doing and know how to apply things depending on the requirements even if those things are not CP or AP.
In any case, it's difficult in terms of presentation, since a "normal" master-slave-replicated Redis is a totally different system from Redis Cluster as the distribution models of Redis Cluster also affects the functional properties to a large extend, e.g. regarding atomic Multi/Lua blocks and all types of multi-key operations.
The failover solutions for relational database systems are a good point, they too should be included.
Regarding use cases, I totally agree: every system should be discussed in the light of the use cases it tries to solve. I personally think that Redis Cluster with a choice for trading consistency against latency would open up a whole new range of use cases that are currently not a good fit for Redis Cluster. For example, we have a Redis-Coordinator project (not open source, yet) which behaves similar to a scalable Zookeeper (BTW also neither CA nor CP [1]). However, it has weaker guarantees, due to lack of tuning knobs in Redis and Redis Cluster regarding consistency.
[1] https://martin.kleppmann.com/2015/05/11/please-stop-calling-...
EDIT: Also, it might be too niche, but you can also have a look at redis+dynomite, which makes redis behave like a distributed database. https://github.com/Netflix/dynomite
edited for typo.