Every time I've bet against Postgres and used some other data storage mechanism, I always come back to Postgres.
Every time I've bet against Postgres and used some other data storage mechanism, I always come back to Postgres.
Yes, ArangoDB is young (6 years) in comparison to PostgreSQL (30 years).
Yes, PostgreSQL is a phantastic database with an amazing open source community and is not going away any time soon.
Yes, PostgreSQL is a good choice for a project in which you need a relational single server database.
However, ArangoDB actually has a different value proposition, so in a sense, it is not a direct competitor.
ArangoDB is native multi-model, which means it is a document store (JSON), a graph database and a key/value store, all in one engine and with a uniform query language which supports all three data models and allows to mix them, even in a single query.
Furthermore, ArangoDB is designed as a fault-tolerant distributed and scalable system.
In addition it is extensible with user defined JavaScript code running in a sandbox in the database server.
Finally, we do our best to make this distributed system devops friendly with good tooling and k8s integration.
Last but not least, ArangoDB is backed by a company which offers professional support.
Therefore any well informed decision for a project needs to look at the value propositions and capabilities and not only at the age and experience, which is of course a big argument, since people are - rightfully so - conservative with their databases.
What is the consistency model and have you validated that it actually works as designed (for example with Jepsen)? I didn't find anything detailed on your website.
You might also end up with a LOT of servers unless you starting sharing servers for different shards (but still with different sets of 3 servers for every shard).
A huge proportion of modern software businesses can run on single-writer RDBMS instances, properly engineered, at a fraction of the operational and implementation cost of a scale-out solution. That applies to hosted and self-managed solutions equally, in my experience.
Modern distributed databases scale better but also have better replication, high-availability with automatic failover and no downtime, easier upgrades, easier backups, and generally less maintenance. Removing the single-point of failure with efficient distribution while being able to run easily on docker/kubernetes makes a big difference over a single monolithic database server.
Overall, I agree -- PG with JsonB is extraordinary powerful system, covering document oriented and typical row-oriented use cases.
PGs ecosystem with external foreign interfaces, and in memory streaming solutions (like PipelineDB) - must be an envy of any other db ecosystem.
1. Unify JSON and SQL syntax, instead of user->>'email' make it user.email
2. Support sub tables, so I can decide if I want a sub table (schema) or JSONB (schema-less)
You definitely need to think about pooling fro the beginning of the design of your application.
Connection pools are a necessary work around for a specific design decision with the system software. They can be helpful other problems as well, but they aren't necessarily a requirement.
We have tens of thousands of connections and no problems. We also forked pgbouncer to use multicore [0] which allows us properly utilize servers.
It's just an external connection pooler when your native language driver doesn't have a good one
Not sure what solution are you imagining would be the right one.
Most distributed systems have eventual consistency. Very few can achieve strong consistency. Postgres sacrifices a lot for a strong consistency and predictable performance.
I'm not saying that PG has the best model, but for the wast majority of users, out of connections is just not an issue. Most clients have now direct pooling and they are very easy to setup. There are a few who need more connections, but there are poolers for it.
What you gain but separating connections is much easier monitoring and debugging process. You can examine each connection, its impact on resources, state, what locks they need to acquired, ...
Additionally, because each connection opens a file descriptor, you gain a lot of operating security from the underlying OS and its kernel.
PG contributors spent almost 3 decades building on this system. I'm pretty sure the gain would be so minuscule in comparison to the effort that would have to be put in to rebuild the connection model.
I for one would appreciate server polling built in, better HA including simple discoverability, handoffs, ...
Fundamentally just needs isolation to be done at a different layer.
That to me is a compelling reason to use something other than Postgres.
One solution is to have a generic reference property paired with another indicating which table to reference
reference_id: '1234',
reference_table: 'posts'
reference_id: '4321',
reference_table: 'comments'
You can still benefit from indexes for joins in the same way that you would with actual foreign key constraints, but the downside with this is that you can't actually apply a foreign key constraint.Another solution you can look into, which I don't have much experience with myself, is table inheritance: https://stackoverflow.com/questions/3074535/when-to-use-inhe...
Another form of modeling the data in such a manner is called Exclusive Arc, which is that you just simply put all of the possible keys you might reference on the table, and add a foreign key on all of them. Then, when you need to make a reference, you just leave all but the one in use on that row as null values. If a "like" can go on a "post" or a "comment" or an "image", you would just have all 3 foreign key columns/constraints on the "like" table.
And lastly, and probably best of all, is to simply use 1-2 tables for your entire data model for vertices/edges, and just treat Postgres as a graph database.
> You can still benefit from indexes for joins in the same way that you would with actual foreign key constraints, but the downside with this is that you can't actually apply a foreign key constraint.
Thanks, I had not thought JOINs possible on this - how would a query look? I'm guessing it works only for one type of reference_table.
> Another solution you can look into, which I don't have much experience with myself, is table inheritance: https://stackoverflow.com/questions/3074535/when-to-use-inhe....
Been there, tried it, banged my head on most of these (particularly the FK limitation): https://www.postgresql.org/docs/11/ddl-inherit.html :)
If it was fixed by Postgres it'd be awesome. I've lost the wiki page which was around on the topic, but it was unchanged for ~10 years, so really should've been marked 'wontfix'.
> Another form of modeling the data in such a manner is called Exclusive Arc,
> And lastly, and probably best of all, is to simply use 1-2 tables for your entire data model for vertices/edges, and just treat Postgres as a graph database.
That's what I'm doing, with the 'node' table using JSON to store the node-specific data. I feel sooooooo dirty but it works. Yet to figure out schema evolution of the JSON in a controlled manner :)
So this is for the structure with the two columns
reference_id: '1234',
reference_table: 'posts'
reference_id: '4321',
reference_table: 'comments'
So let's say that this is the `likes` table that can like either `comments` or `posts`, here are some queries: // Get comments and their respective likes
SELECT * from comments
JOIN likes ON comments.id = likes.reference_id;
// Get posts and their respective likes
SELECT * from posts
JOIN likes ON posts.id = likes.reference_id;
// Get likes and their referenced comments
SELECT * from likes
JOIN comments ON comments.id = likes.reference_id;
And so on.