Also relevant: the draft changelog for the next version (due out in December): https://sqlite.org/draft/changes.html
Generalized graph traversals require each query to have additional data structures that grow with table size. This becomes an expensive proposition as tables get large, especially if you have many concurrent queries. Some databases designed for graph processing have internals and storage models that make it more efficient to resource manage this extra state. A SQL database, which has other priorities, would not implement this.
SQL has a knack for doing really easy things well, and moderately complicated things badly. I would assume by default that anything involving graphs should not involve SQL. Recursive CTEs to me scream "you're about to spend hours debugging something trivial".
That would be a questionable assumption. SQL databases are a widely tested tool, and SQL itself can allow you to augment your "graph" with constraints and semantics that many graph-focused systems have trouble with. CTE's, while not entirely trivial, are not overly complex; they're not something you'd spend "hours" debugging.
Probably not in the same kind of resource-constrained way, no. Whilst it might be a suboptimal graph database, it's also not going to require 2GB of RAM to run...
Because SQLite is ubiquitous. It's simply everywhere. And it doesn't need a dedicated server to run.
I've actually been considering migrating away from neo4j to sql with recursive queries for performance reasons.
A schema may have only one, or anyway, comparatively very few instances, of recursion.
In this case, using two separate data stores would be too much overhead; if the CTE doesn't do anything particularly fancy, that is, if it just retrieves records recursively associated via keys, it's not implicitly hard to debug (actually, there isn't much to debug).
A point in case is GitLab's users management, which dropped MySQL also because of the lack of CTEs (at the time).
There are pure graph stores out there, AllegroGraph, OpenLink Virtuoso (although this is a strange hybrid of SQL + Graph technologies) and others - and for more advanced graph query constructs like path finding there are optimisations that are difficult/not well supported in SQL.
Slightly off-topic, but I want to point out how well Richard deals with a slightly rude commenter [1]. Keeps it classy and productive while still calling out the bad behavior.
Hipp's response is also fine! The only thing that wouldn't be fine is if someone inappropriately reacted to that comment as an insult.
> The type affinity of a column is the recommended type for data stored in that column. The important idea here is that the type is recommended, not required. Any column can still store any type of data.
I simply don't want weird rows (that violate the _expressly declared_ type of a SQL table) to be merrily allowed into persistent storage.
Some problems are easy to solve given a column of type VARIANT: 1. simple sparse columns instead of a multi-type EAV table, 2. a BIG Table style schema that is easily range partitioned.
The main reason in SQLite is that most SQL dialects just work. SQLite becomes a universal desktop workbench for SQL. This flexibility also applies to things like delimited identifiers [1].
The problem is not that SQLite uses VARIANT datatypes, the problem is that once a datatype is specified it is not enforced by the engine. SQLite could/should add a PRAGMA to enable Domain Integrity much like it does with Foreign Keys (PRAGMA foreign_keys = ON;).
Fixed length data types in SQL were a premature optimization that led to verbose syntax like LONG VARCHAR FOR BIT DATA [1] and incompatibilities tied to internal implementation details. There is no reason why more specific constraints can't be specified on top of the core storage types.
One can argue that SQLite is sorely missing an exact NUMERIC type but that holds true for most/all language runtimes as well. Datetime is a bit weird too but the format of the DB file is a thing of beauty.
[1] https://db.apache.org/derby/docs/10.1/ref/rrefsqlj30118.html
The most common place I've encountered recursive CTEs being massively useful in real world work is working with company responsibility & reporting hierarchies (line management, regulatory supervision, "spans of control" reporting, ...) where there is not a fixed number of levels.
When there are a small and fixed number of levels (for instance every drone has a supervisor and senior supervisor and you don't monitor connections above that) there are often other solutions that people find easier to understand and/or perform faster but for deeper trees or those where the level structure is any less static, recursive CTEs are a godsend.
Other examples include nested taxonomies (nature, book or other publication filing, nested tags for categorisation), properly threaded discussion records, family trees (though these are graphs rather than trees unless you impose some strict limits on what you count), representing file-system like structures in the DB, ...
Graphs get tricker (trees are a subset of graphs) as you may need to consider multiple paths to the same node, infinite loops, and other complications, so I suggest looking into trees first then expending your research.
The most common example for graphs in DBs would be a graph representing the friends/contacts of users. It's one of these "you'll know when you need it" solutions.
Sometimes your data structure is a graph, and sometimes you want that graph to live in a database.
And in even rarer cases you want to search that graph in your database in some recursive manner.
The Fossil discussion involves the SCM's representation of a File System, probably the most common hierarchical data structure we regularly encounter. Hierarchical data structures are notoriously hard in SQL. Recursive CTEs are not easy but they are useful and efficient for hierarchical data.
[1] https://www.sqlite.org/draft/lang_with.html#hierarchical_que...
[1] http://dcx.sap.com/1200/en/dbusage/ug-commontblexpr.html
[2] http://dcx.sap.com/1200/en/dbusage/parts-explosion-cte-sqlug...
I was able to make a query like this in PostgreSQL, but forgot the details of how I did it (though once you sit down, you get it eventually).
A graph database usually means you’re storing the graph nodes and edges as entities, so you can traverse the graph easily from any direction, and express different kinds of relationships.
I have had to run my recursive queries external to the database (MySQL, SQLite), this change looks to bring it into the database. Excellent news!
https://github.com/nikeee/advent-of-code-2019/blob/master/06...
How could this be improved with the new feature of SQLite?