We Can Do Better Than SQL
edgedb.com
edgedb.com
SQL is messy because describing the underlying data relationships are messy. The orthogonality example is a great illustration of this. What exactly should the result be if there are multiple dept heads? Should the result rows be duplicated? It's not clear how edgeQl would handle either (their edgQl orthogonality examples were constructed to only have result per sub query), but it seems like they would be kept together as sets. In that case, the result set is no longer a table, it's a dataframe, which is a useful data structure but is also not what relational databases do.
> SELECT extract(day from timestamp '2001-02-16 20:38:40');
SQL is messy because all the syntax was decided on before there was a community that really understood what good syntax is. The 'from' in that extract does nothing and I can't easily identify if extract is a function or some sort of crazy parsing construct - what are the arguments? Is "day from timestamp '2001-02-16 20:38:40'" the argument? Are the arguments "day", "timestamp" and "'2001-02-16 20:38:40'"?
Are these annoyances crippling? Yes. Yes they are crippling. It should be possible for an amateur to quickly write an SQL validator as a starting project; relational algebra is not complicated. Any fool can write a validator for lisp. Relational algebra isn't that much more complicated - we don't have loops or flow control to contend with here.
Tidyverse's dplyr [0] implements the relational model for real dirty data and, as might be expected for something implemented this century, does a much better job than SQL. Not because the operations are that much different (although gather() & spread() are welcome additions) but through ingenious innovations like, as mentioned, functions having arguments instead of I-don't-even-know-what-that-is.
And the pipe operator which is legitimately ingenious. Great operator for data.
...why? SQL has been wildly paradigm-definingly useful for decades. It has driven hundreds of billions, perhaps trillions, of dollars of value. None of this hinges on the ability for an amateur to be able to write a validator for the language. It just seems like such a non-sequitur to me, such a strange thing to call out as a criticism.
SQL hasn't been wildly successful either because of or despite its syntax, it has been wildly successful because organizing data in the relational model and querying it declaratively is extremely powerful. The syntax is just not the interesting part. Any syntax that meets those criteria would do.
Here you got me thinking: do we even understand that now? There was quite a bit of contemplating about of semantics, data types and different kinds of abstractions in the programming languages for the last couple of generations already, but the general consensus about the syntax is that "nice syntax is nice, but it isn't really that important". Most modern languages loosely follow either something C-like or Algol-like, most people like what they are familiar with. There are sometimes claims that a good syntax should be successfully parsed by some relatively simple parser (which is totally not obvious, TBH, because while it is clear why C++ is a good counter-example, we don't really have that many good examples: classic LR-parsers or something like that are really not that powerful, and most real-world programming languages implement something very non-generic of their own). Some people claim that "good syntax is no syntax" (Lisp), and some say that Haskell has a good syntax (ikr). The bottom line being that this is just a matter of taste, unlike most of what we can say about types and data structures.
So, to summarize: I never actually heard a compelling general theory of good syntax.
This is completely offtopic, BTW, I agree that SQL is trash and it is even kinda funny that somebody tries to defend it like that, since for a long time it was sort of a textbook example of "why a language created with the idea to be used by non-technical people is a failure from the very beginning".
It's not that they didn't understand it. There are languages predating SQL that have better syntax.
But SQL was one of the so-called "4th generation programming languages", that were supposed to be operating at a much higher level. And because of that, there was the notion that, if they also have a more "natural" syntax, it would allow people who are not programmers to use them effectively. Hence why SQL was originally SEQUEL - Structured English Query Language. It was meant to be written by domain experts, not database experts.
Of course, that failed (like countless other similar attempts since then), and so now we're stuck with this syntax for no good reason whatsoever.
No, the relational model is beautiful and consistent! SQL is messy because the syntax is not consistent and elegantly composable. It could have those properties and still present the same underlying data relationships.
See Linq in C# as an example for how a more composable query syntax can expose the same data model.
For example in Linq you can chain arbitrary many select/join/where/group by in arbitrary order. In SQL you need nested subqueries to achieve the same which is a much more convoluted syntax.
WITH statements alleviate some of this issue by allowing you to write subqueries in any order.
What is beautiful and consistent is the relational algebra. The relation model relies on this formalism to model data by making some rather strong assumptions about how tuples and relations represent things and how relational operations are used to process them. And these assumptions are precisely what propagates to SQL and what some authors (see references in the article) consider controversial and messy. Then the question is whether and how these controversies can be fixed (or whether they are bugs or features).
A radically different approach to fix these controversies is to introduce a different formalism and different data model (as opposed to fixing only syntax) which is based on using functions. In other words, instead of using sets and set operations, we use in addition functions and function operations [1]. Here you can find an implementation of this approach:
https://github.com/prostodata/prosto Prosto is a data processing toolkit radically changing how data is processed by using both sets and functions and being a major alternative to map-reduce, join-groupby and other set-oriented approaches
[1] Concept-oriented model: Modeling and processing data using functions: https://www.researchgate.net/publication/337336089_Concept-o... -> Read introduction (two pages) for why having only sets is not enough and why functions are important
Already, we're introducing a weird inversion of syntax that, in my experience, trips up people learning it: data in SQL is stored as "rows" with "columns" inside "tables". More formally, we've got a hierarchical relationship where Tables > Rows > Columns, yet we write the query as Columns > Table > Rows.
There are far more consistent and beautiful querying languages than SQL: I would point to MongoDB's query language, which is less of a query language and more of a static javascript-interpretable library, but is still far easier to learn and more consistent than SQL. The same query in MongoDB: "db.users.find({ foo: "bar" });". How is this better? It embeds the operation in the statement ("find"); reading it hierarchically follows how the data is stored (Collection > Rows); the filtering operation is the same shape as the data being stored; and it naturally disallows most injection attacks.
I don't know MongoDB query language, but gah! that looks horrible. It uses three different syntaxes; dot notation, curlies/brackets and colon key value. Full of punctuation and doesn't read like english.
There is no distinction between noun "users" and verb "find". There's extraneous "db". does foo: "bar" mean equal or is it find() that determines the operator, maybe combo of both? how do I do other operations.
.Only if you are familiar with programing language that has that same syntax does any of it make sense. Otoh even educated non-programmers are gonna be able to read the SQL as SELECT "these things" FROM "this table" WHERE "these conditions are true".
seriuosly?
db.orders.aggregate([
{
$lookup:
{
from: "warehouses",
let: { order_item: "$item", order_qty: "$ordered" },
pipeline: [
{ $match:
{ $expr:
{ $and:
[
{ $eq: [ "$stock_item", "$$order_item" ] },
{ $gte: [ "$instock", "$$order_qty" ] }
]
}
}
},
{ $project: { stock_item: 0, _id: 0 } }
],
as: "stockdata"
}
}
])
VS SELECT *, stockdata
FROM orders
WHERE stockdata IN (SELECT warehouse, instock
FROM warehouses
WHERE stock_item= orders.item
AND instock >= orders.ordered );Not sure that is true. You can imagine having a smaller query language with clean semantics able to capture messy data relationships. Small functional expression languages come to mind. Where it lies on the spectrum from purely-table-form to can-hold-everything is a design choice.
Your query language doesn’t need to capture the underlying data model exactly. SQL is an example of this itself.
I’ve run into the orthogonality issue myself several times. You don’t need to drop SQL today, but for some data domains more expressive query models can work really well.
Are there really any SQL libraries in the traditional sense (i.e. reusable/composable SQL code with a well specified API)? SQL "libraries" typically focus on hiding the inconsistencies and the abhorrent syntax under the carpet.
And the user base is there, mostly because of the database engine properties and features. The query language itself is just a bad side-effect. And TFA does make a point that NoSQL abandoning the underlying RDBMS model is in fact a regression.
The article presents several examples where SQL's messiness cannot be plausibly attributed to underlying data relationship messiness.
Instead, perhaps a second format should be standardized, which is machine readable/writable, that more or less represents relational algebra + whatever extra features SQL supports. It can be clunky and verbose, as long as it's straight-forward and easily composable. It would effectively be like a compiler intermediate representation.
Once you have something like that, you can have as many front-ends as you want with whatever syntax you prefer.
Of course, getting all of the RDBMS vendors to agree to it is still a problem, and they'll probably all still include their own vendor-specific extensions and differences, because they want to lock you in to their system.
But at least maybe the open source ones could agree, which would still be quite beneficial.
Also that is only one of the things they are hoping to fix. It sounds like you're saying "We have 5 variants of SQL already so nobody is allowed to write any other database query languages ever. We must use SQL forever." which is stupid.
At least we don't have to change our whole data model or give up consistent data to try it!
You want flat result, aggregated result. Why does this have to be blamed on the data relationship and not SQL language itself?
For any graphical type of relationships, I find SQL utterly hard to express my queries properly. It feels like a assembly language at that point.
This is a common misunderstanding of what the relational in "relational database" means. It's not (primarily) about relationships, except insofar that relationships can be described using relations and queried using relational algebra. But the key concept is that of the mathematical relation, as per Wikipedia:
"In mathematics, an n-ary relation on n sets, is any subset of Cartesian product of the n sets (i.e., a collection of n-tuples)"
So the goal of relational db languages is to provide tools for querying these sets of sets. Joins, Unions, Selections (Restrictions), and Projections are some of the tools that are provided. SQL provides some of these, though often calls them confusing names.
For example, in SQL the "select" keyword begins the query statement, but selection proper (as per relational algebra, also called restriction) is actually what is expressed in the "where" clause. What comes after "select" in your query is technically "projection" (choosing which tuples/columns exist in the output). Many ORMs and similar tools get this messed up, because the authors of them know SQL, but not the relational algebra on which it is nominally based.
Aside from DDL (which I'm not sure how you would do without distinguishing between base relvars [tables], derived relvars [views], and other classes of relations), SQL doesn't particularly treat different kinds of relation differently beyond what is minimally necessary (you can't write, via insert or update, to a relation that isn't a relvar, for instance.)
Try Sparql.
What do you mean here? The difference between a table and a dataframe is that a dataframe is a construct held in memory, while a table is persisted storage written to a database.
Selecting columns before tables always felt weird to me. Doesn't it make more sense if you had a graphical view this way? (imagine boxes around the below items where you can drag lines to make connections between tables/inputs)
USERS
--user_id-- [data processing] => ...
GROUPS
In SQL that would be,SELECT * ,groups.* from users INNER JOIN groups ON users.user_id = groups.user_id
SQL is so messy and full of details that can be much better represented via dataflow diagrams.
Either way, queries need to be composed at runtime a lot of the time, so for many uses of SQL you can't just have the queries as blobs that you prepare ahead of time in some other tool - they must be objects you can work with programmatically.
The "Selection" is the set of predicates that restrict the resulting relation. Projection is choosing which tuples ("columns") to use in it.
The relational algebra has no "tables", this is, again, a SQL thing. It has relations (sets of sets) and operations on them. In SQL "tables" are one kind of relation, and views are another.
Obligatory XKCD https://xkcd.com/927/
SQL is an incredibly expressive and flexible way to read, store, and update data. It's ubiquitous, so the SQL skills I learned six jobs and three industries ago are still relevant and useful to me today. Relational Databases and SQL are heavy lifters that I often relay upon to build projects and get things done.
SQL got a bad rap in many ways due to security issues, databases in general, and "web-scale".
SQL as a language within other languages is a nightmare from a security standpoint, and if language integrated query was more common across languages earlier on then this wouldn't have been an issue.
Databases generally depend on normalization, but normalization comes with interesting scaling problems and how do you replicate normalized schemas. Thus denormalization became a thing, and then the emergence of NoSQL and document stores started to infect everywhere. The JOIN was a killer too, and then the discipline required to do sharding made it annoying to manage, so easier to manage solutions became a thing.
I'm looking at databases in a different light these days with more appreciation, but now the hot new thing is GraphQL makes things... interesting. I don't view GraphQL as a server-side solution, but a client solution to overcome the limits of HTTP/1.1. However GraphQL clients are exceptionally complicated, and I'm not sure they are worth it. The only problem is that to overcome them requires engineers "to know how to do things", but that is a hostile stance. People want to go fast and make progress, and GraphQL enables that.
GraphQL is, in no way, faster than any REST alternative in terms of implementation speed. If anything, it is slower, as you need to be extremely methodical with your API changes, as (same with REST I suppose) deprecating fields / entities, for mobile clients specifically, is a PITA unless your clients have really nicely built out forced upgrades.
What GraphQL _does_ give you, is type safety and extreme client flexibility . It is a better solution than REST in almost every scenario, other than the initial learning curve, which takes a couple weeks and then you know it forever.
Would I recommend some startup write a GraphQL API for their MVP? No, just get something working. Are you at a more medium-sized company looking to build out your much more permanent API? Then yes, you should probably strongly consider GraphQL.
GraphQL is a hammer, and now every project is a nail.
Anecdotal, of course, but the first thing all FE developers I've ever worked with do when they start/join a project is add/suggest GraphQL/Apollo.
Nobody considers how awful things look on the back-end when you need to cache or make magic happen to avoid thousands of N+1 queries.
I believe unfortunately it has become the only way many front-end developers learn to interact with any back-end, and now everyone's forced to use it regardless of its drawbacks.
Same with React. Facebook managed to get free training for all of their future hires. I hate the company but that was a genius move.
I'm using similar security tricks to you: read-only queries with a time limit, against SQLite rather than PostgreSQL.
More here: https://simonwillison.net/2018/Oct/4/datasette-ideas/ and https://github.com/simonw/datasette
I see very little value in using GraphQL, when you can just write SQL on the client!
We desperately need frameworks to better facilitate this, like Hasura or Django -- DB migrations, permissions, authentication, real-time subscriptions, Admin UI.
My most wanted feature is SQL type providers, like Rezoom.SQL - https://github.com/rspeele/Rezoom.SQL
Redis is also easier.
The key is what are you designing against. If you design against a DB, then you may find that scaling beyond a single host with gotchas. But, if you have the discipline to keep everything within a document, then you can scale up easier as the relationships between documents is more relaxed.
However, cross document indexing and what-not creates more problems, and that in and of itself is an interesting challenge.
It's true that in the 2000-2010 period many SQL implementations struggled to scale with growth in websites (many other parts of the webstack did too).
The question is what is it going to cost in either licensing solutions or engineering effort.
Perhaps the best querying language I've ever used is Q-SQL, integrated into kdb+/q. Unlike SQL, it's actually part of the language (q/k) and, most importantly, it's modular and more expressive than SQL.
If you're interested in how we can do a lot better than sending strings to remote databases using an inexpressive and non-turing complete language, check it out: https://code.kx.com/q4m3/9_Queries_q-sql/
Not only I prefer to work with SQL nowadays I also prefer SQL over any ORM in older codebases, ORMs are pretty useful for getting up to speed without caring about your persistence layer too much but after 17 years in this industry I've had my fair share of issues with ORMs to avoid them whenever I can.
Native SQL queries with placeholders for my parameters in their own files, loaded by my database driver to execute and return data is my go-to solution for data access, it's flexible, maintainable and readable if you treat SQL as your normal code (code reviews, quality standards, etc.).
Personally, I was lucky because I had great courses, even in highschool, regarding SQL including: How are rows working, what is normalization, how does it help with data and so on. So naturally I developed some feeling on how to handle database tables.
Linq in .net shows IMHO how queries can be expressed in a more consistent and composable syntax while still conforming to the relational model.
Lately I use nosql for very light data and otherwise our API outputs heavily cached and extremely simple data. Adding a database as a middleman wouldn’t make sense. Still fun, but I miss Postgres!
Me and my companion moved everything to stored procedures. Now every IT-department says that the product is VERY stable.
This piece reads like Joey being unable to open a carton of milk [1], "there's gotta be a better way!".
As for SQL it has its warts, but im pragmatic when it comes to programming languages, like for example C, JavaScript, its also "ugly" but its often the best option anyway.
Trying to implement business rules about data relations outside of the DB is a nightmare.
[1] We use dynamic SQL within stored procedures for pivots.
Why would you do that?
Also there are tools out there that provide that functionality. Found with a few seconds of searching. https://host.apexsql.com/sql-tools-source-control.aspx
So, when we interact with a relational DB we need some kind of layer to map between the world of relations in the DB and the world of objects in our program.
I'd love to see a "SQL-like" language that compiles down to SQL itself, much like Babel or TypeScript in the JavaScript world. I think the tricky thing is that there is no single SQL target.
What about common table expressions? Or custom defined functions?
with X as ( select... )
It's widely used for analysisit's alright, it's consistent enough, it's good
I'm reading about datalog and prolog more and more but sql is ok
To me relational algebra is the beauty queen, and SQL is the "beauty mark" that prevents it from reaching perfection.
1. Anyone striving to build a better SQL should make a comprehensive list of common (but difficult!) database tasks for OLTP and OLAP workloads. This will expose the weakness of their language. SQL has had 50 years and myriads of improvements to cover all these common cases. This is not a fair fight, so come prepared.
2. It's not enough to be just "better than SQL" to replace it. SQL has such a huge momentum that a new language needs to be absolutely better _and_ it should have many features that SQL cannot possibly have. My nice-to-have list would contain predictable performance, lock ordering, ownership relations (for easy data cleanup), and a standard low level language which the query optimizer would output.
Predictable performance - this will always be not only implementation-dependent but data-dependent as well. In order to know whether a join will be efficient or not, you need to know things like relative sizes of the tables, which is not necessarily a language problem. I have worked with SQL implementations that had extensions to let the user annotate joins with relative sizes on each side, but I don't think that's quite what you mean.
Lock ordering - again, good databases should have defined semantics (Postgres, for instance, does take locks in order when using ORDER BY), but I'll grant that this one could be stronger. That said, I think this is pretty niche. How often are you doing large multi-row transactions where lock order is a serious problem? If I have enough volume that deadlock is likely, I probably have enough volume that I want to be breaking up the process into a sharded or two-phase commit anyway.
Ownership relations - I think this is a DDL problem rather than a SQL problem.
Low-level language - I don't think you'll get a portable low-level language here (at least not for any definition of "low level" that's much lower than the SQL AST) because, again, the basics are implementation-dependent. What kind of scan is the base atom of a query? Well, it depends - is your database distributed? sharded? row-store-based? column-store-based? I do wish more open source database drivers would let you play with the AST in memory (Postgres has ways to print it out, but I don't think there's a good API). That would tend to solve the most significant problem raised in the article (composability) - plugging together SQL clauses automatically is hard, but plugging together subtrees can be much easier.
This immediately jumped out at me from the parent comment. It would be entirely possible to implement a query language where you specify a plan for your query. But then you’d immediately lose the “better than SQL” competition, because your complexity and maintainability problems would skyrocket.
I’ve had to deal with this problem as an Oracle DBA, and it’s a complete nightmare. It starts with a statistics refresh ruining a couple of execution plans, so you start specifying them manually with the plan manager. Then it gets worse over time, because stats refreshes become a big risk and you don’t want to do them anymore. Eventually you get to the point where you pretty much only run verified plans. Then your verified plans slowly degrade overtime, because the underlying cardinality of every table is constantly changing. You’ve replaced the query optimiser with yourself, which is not only tedious work, but it’s simply not possible to do the job as well as any mainstream DB engine could.
And before that there was ALPHA. From https://www.labouseur.com/courses/db/s2-Remembering-Codd-2.p... :
"Ted [Codd] also saw the potential of using predicate logic as a foundation for a database language. He discussed this possibility briefly in his 1969 and 1970 papers, and then, using the predicate logic idea as a basis, went on to describe in detail what was probably the very first relational language to be defined, Data Sublanguage ALPHA, in “A Data Base Sublanguage Founded on the Relational Calculus,” Proc. 1971 ACM SIGFIDET Workshop on Data Description, Access and Control, San Diego, Calif. (November 1971). ALPHA as such was never implemented, but it was extremely influential on certain other languages that were, including in particular the Ingres language QUEL and (to a lesser extent) SQL as well."
Here's an example from http://arwan.lecture.ub.ac.id/files/2013/10/4.-relationalcal... :
SQL:
SELECT DISTINCT F.Name
FROM FACULTY F
WHERE NOT EXISTS
(SELECT * FROM CLASS C
WHERE F.Id=C.InstructorId AND C.Year=2002)
Relational Calculus: {F.Name | FACULTY( F) AND NOT
(∃C ∈ CLASS( F.Id=C.InstructorId AND C.Year=2002))}there exists, in, for all
Speaking of negativity ;)
The article does nicely illustrate many of the well-known shortcomings of SQL. Chris Date and Hugh Darwen unsuccessfully tried to fix SQL with Tutorial D. Never heard of it? Exactly.
I often joke that SQL is the COBOL of the 21st century. HHOS. There's worse things...e.g. COBOL.
Actually it's very difficult to deny the empirically discernible utility of relational databases and SQL. SQLite, for example.
Well, just the D class of languages; Tutorial D is (as the name suggests) a pedagogy-focusses implementation of the D requirements, the intent was that there would be one or more Industrial Ds.
(Dataphor is a D—the first implemented, IIRC—and is successful enough that it's a still-living commercial product.)
"Accrington Stanley"
You know what we could do better at? Crappy explains from database engines. Crappy rate limiting capabilities. Poor feedback on keep cache pipelines fed during scans. Poor feedback on column size effects on reading stripes from disk and size alignments between the filesystem and database.
I use it daily in a business that is heavy on SPs and while I get by and am improving the jump from inner joins and selects to CTEs and the other wizardry is massive.
I want to be better at SQL but so many problems I hit up against and think “well that’s a 2 minute job in js/swift/php”
The thing about SQL is that it's the fastest way to read&write data in a relational database. Maybe writing the code is faster in js/swift/php, but the code will run faster in SQL. If you need to do something to 100M pieces of data you can do a lot worse than SQL.
If you "just learn SQL" without understanding the abstraction below it, it'll be difficult to be successful, much the same with anything else.
When you are crafting good SQL query (crafting is the right word as each non-trivial SQL query is a little puzzle that may take you few days to solve because of the constraints) you need to stay within the bounds of the this fast db world.
Whenever you are forced to open a cursor or use CTE for recursion or even have a full table scan you already left the fast land and landed in the world that all general purpose language inhibit, where you have to iterate and recurse and everything takes ages. And in that land any other language beats SQL because any other language has the syntax designed to make things easier in this world while SQL has the syntax that's just good enough for the fast world where operations are highly restricted and when it ventures into the slow world it's just a horrible mess.
The combined effect is a rather tortured language, as it has been extended over the years.
However, replacing it is equally problematic because of the huge installed base.
Support for this bytecode should be added to Postgres, MySQL etc, not some new database product. Projects should be able to mix old style SQL queries and queries written in the new language at will.
That's not how I remember it. What I recall is that SEQUEL was the result of looking at how databases and set theory could be connected.
https://en.wikipedia.org/wiki/Edgar_F._Codd
That had nothing whatsoever to do with COBOL or NATURAL.
Structured __English__ Query Language
see the original paper at https://web.archive.org/web/20070926212100/http://www.almaden.ibm.com/cs/people/chamberlin/sequel-1974.pdfI will cheer everyone who tries to displace SQL, because I do think it needs to be displaced but would also want to caution such people on the magnitude of the task ahead of them.
Why? What are better alternatives, really?
SQL is very hard to learn properly, with all of its gotchas and inconsistencies. There are running jokes for noobs truncating their tables due to forgetting a where clause. I’ve seen junior devs crying in tears and throwing their mice just because they needed to debug / optimise a complex query.
The mare existence of all the ORMs is a testament that people would opt to write (or use) insanely complex pieces of software just so they don’t have to deal with the lack of composition and ease of use.
All of those look to me as signs that something wrong with the core itself. We could do better.
If we settled for good enough in all cases we wouldn’t have Go or Rust, React or Postgres. In fact every software that we have is a product of someone thinking “this is hard/wasteful/unexpressive/etc, lets write an alternative”, SQL included.
This alternative looks quite promising. We can wait to see how they can handle the edge cases, but the core looks a lot simpler to deal with than regular SQL.
I don't understand why though? I've been using SQL (Postgres for the most part but with a smattering of MySQL thrown in) for around 8(?) years, which isn't much in the grand scheme of things but I have not had anything that couldn't be resolved. I've written small straightforward queries to over 200 loc and never had a problem understanding it if you read it slowly/broke it down into smaller queries.
In fact, ORMs have been a massive headache because I can think in SQL but not in whatever the creator of the ORM was thinking in. Those giant queries that I was talking about - there's no way to represent them in ORM form.
SQL works in a language agnostic way, you can explain analyze your SQL queries and run it through whatever medium you prefer. Typical experience with an ORM goes like so:
1. Lets use an ORM because it'll be easier
2. It's not actually easier and it's a complex mess now, but let's stick with it anyway
3. Figure out a way to log the queries that the ORM made up for you/printf it
4. Run that through EXPLAIN ANALYZE
5. Can't make the ORM do that, file a bug report that'll be buried
6. Use native query while you wait
7. Tech debt etc;
ORM can really get in the way when you want to express groupings, aggregates, and all kind of joins sprinkled with let's say stored procedures.
But this has nothing to do with the ORM itself. It's just a fact that many people don't understand/consider the tradeoffs before jump into acting on something.
Yes, fully agree on ORMs. They DO have one nice feature though: simple CRUD operations are way less verbose than constructing SQL statements.
What we lack is a better integration between the host language and the databse. Constructing a prepared statement from a string, setting parameters, executing, fetching rows from the result set and mapping back to fields... all is a major, repetitive PITA.
And yes, I find it easy to think in SQL and often wonder WTH an ORM is going to generate. Just recently I improved performance of an application by going from ORM to SQL; first I reduced number of round-trips (ORM/efcore first wants you to fetch an entity before you can update it), second, I batched updates into a single session/transaction. Win! :) [Oh, and don't get me started ranting about ORM and transactions.]
1. Lets use an ORM because it'll be easier
(skipping 2, because it's not really a mess; skipping 3, because they know that before getting to this point)
4. Run that through EXPLAIN ANALYZE
5. Can't make the ORM do that
6. Use native query
7. Profit
There's nothing wrong with having `Users.active.find(id)` where you want it and writing out the complex query as SQL where it gets complicated. They can live next to each other just fine and still improve your life.
Going extreme in any direction is going to cause problems. (whether 100% ORM, or SQL purity) It's fine to use different approaches where they're appropriate.
funnily enough, golang is a regression in practically every front compared to established ecosystems like Java and C#.
Isn't this the same for most shells including almost all linux distros? The CEO of red hat accidentally wiped his computer becuase he forgot a slash but we don't throw out a whole tool just because it included a footgun.
The same is true for SQL.
I was part of a similar attempt - building a better "SQL" and relational DB. This was roughly 8 years a go. You can have a look at our GitHub Projects or look at some further links and may be you get inspired :)
* http://bandilab.github.io/ - introduction to the bandicoot project
* https://www.infoq.com/presentations/Bandicoot/ - presentation of the Bandicoot language on
* https://github.com/ostap/comp - another interesting attempt, a query language based on a list comprehension
There's some neat stuff here and I hope the project well. I would love to see object/hierarchical result set support grow. SQL ORMs feel so kludgy.
once you reduce all that to object traversal all your options are lost, your only entry point is the entity and the only connections are direct paths
it's not the underlying query language, it's the flattening to object
SQL and it's implementations do not support nested relations. The parent is suggesting that e.g. nested relations would enable better ORM solutions.
Though when I reason about SQL, I think mostly in terms of functional operators over streams of data: projection, filtering, flat-map, join, fold/reduce. Obviously optimization means looking through streams and seeing tables to find indexes etc., but once you get to the execution plan, you're firmly in a concrete world of data flow and streams of tuples.
I didn't get on well with the example syntax in this write-up. It didn't mesh better with my mental model of relational algebra either at the logical or physical execution level - and the truth is you need a foot in both worlds to write good scalable SQL today.
Aside from the complexities of dynamic construction, my biggest problem with SQL is modal changes in query plans, owing to how declarative it is. It's a two-edged sword: the smart planner is great, up until it's stupid. And it usually turns stupid based on index statistics in production at random times.
Let's say you're building a CRUD app with search and filtering capabilities. Unless you are using an ORM (which has problems of its own), you might be tempted to build the SQL query string like this:
conditions = " AND ".join(filter_key + " = '" + filter_value + "'" for kilter_key, filter_value in filter.items())
order_by = column_name + " DESC"
query = "SELECT col1 FROM tablename WHERE " + conditions + " ORDER BY " + order_by
But this has multiple SQL injection vulnerabilities. Doing it correctly is not just a matter of using SQL parameters, because column names need to be escaped differently than string literals. Linters can't distinguish between correctly escaped queries and incorrectly escape queries in non-trivial cases. Also, the query will throw a syntax error if the number of filters is zero, since you can't have an empty WHERE clause.I don't think a new query language solves this problem.
jOOQ or SQLAlchemy look like SQL (and you don't even have to squint your eyes very much) and solve the problems you mention.
What I am wishing for is for the language to be more like JSON, something that matches closely to commonly found structures in programming languanges (like lists, objects, numbers, strings and booleans), and that the database can support natively.
IMO this is in the article mentioned as 'poor system cohesion':
> poor system cohesion — SQL does not integrate well enough with application languages and protocols
----
> I don't think a new query language solves this problem.
LINQ ?
The "English-like" syntax means that what is actually happening is obscured (so many misunderstandings of what "selection" is, for example), and it means that composing multiple operations gets very awkward and hard to read and in fact many things that the relational algebra itself permits are not really expressable.
And renaming core concepts means people means people get confused. They don't understand what the "relation" in relational is, and think it's about relationships. They think SQL is all about tables, when tables are just one way of representing predicates. Etc. etc.
The relational model is a very elegant method for presenting facts about the world and then the relational algebra is a nice functional programming style system for slicing and dicing those facts into information in basically arbitrary and recomposable ways.
SQL has obscured that. It's awful.
I would dispute this. The antecedents of NoSQL were the parallel programming models of HPC. They weren’t specifically excluding SQL, and NoSQL was a term that was invented after the fact.
Can you elaborate on what you are thinking of? As a refresh, here's when and how the (current usage at least) of NoSQL was introduced: https://subscription.packtpub.com/book/big_data_and_business... in 2009.
> As Oskarsson had described, the meeting was about open source, distributed, non-relational databases, for anyone who had "… run into limitations with traditional relational databases…," with the aim of "… figuring out why these newfangled Dynamo clones and BigTables have become so popular lately."
I was using MongoDB at the time (we became one of their first paying customers -- they didn't even want to take money for support at first!) and HPC wasn't in the air. So please elaborate.
http://2009.drupalcamp.at/sessions/chx-session.html as far as I can remember this was my first MongoDB talk. It's been a long time ago.
The functional style that MapReduce derives from had been used in parallel computing models, e.g. the scatter/compute/gather model of MPI, and in turn this was adopted by Hadoop, CouchDB, MongoDB and others.
A big part was document oriented databases like CouchDB and MongoDB made more sense for a lot of web based use cases, where in the end you’re serving a page of content. Building a relational model often little sense for the web and makes managing the content harder; that a lot of websites can be built with a static site generator highlights that.
I acknowledge that these are real issues, and commend the authors for attempting to address them. However, these issues rarely cause any real friction for me - I generally find SQL among the most ergonomic languages I use (regardless of dialect).
Many people are saying SQL isn't that hard to learn but as someone who is new to SQL, I disagree.
It takes a max of 15 minutes to understand basic JavaScript/Go/Python primitives and write a program. SQL on the other hand seems much more complex. I might as well be reading Haskell or Lisp. At least those languages are consistent.
SQL does not feel like a language where I can learn a few primitives really quickly and compose them together.
Having tried both SQL and the approach of using a programming language + framework of the day, I prefer SQL for data manipulation. It's far easier to troubleshoot, scale, hand-over or maintain in the long run.
Basic SQL can be learnt just as quickly, if not quicker, I'd say, as it is close to english in comparison with other languages. IMO the hardest parts are stuff like pivots and cursors, along with performance problems in complex queries.
I personally wrote my first few queries within 30 minutes of starting to learn it.[1] Of course it wasn't particularily good SQL, but workable enough.
[1]Basically got an apprenticeship and was almost instantly told to write some queries.
SELECT <columns> FROM <table> WHERE <column> = <value>
"Has anyone fixed these problems elsewhere?"
Then:
>The NoSQL movement was born, in part, out of the frustration with the perceived stagnation and inadequacy of SQL databases. Unfortunately, in the pursuit of ditching SQL, the NoSQL approaches also abandoned the relational model and other good parts of RDBMSes.
Yeah that's what I was thinking, they really don't fix the issues listed, just have chosen to solve other problems, but not in a "going to fix SQL" kind of way.
I'm a little bit young, but isn't this a bit of a revisionist take, by the author?
I thought that Amazon, Google, FB et al moved away from relational databases because the sharding logic they needed to build on top of these databases was approaching the complexity of a RDBMS. They didn't need strong consistency or support for complex queries, on the kind of data they were storing at scale, and so made compromises in those areas while engineering their purpose-built alternatives (Dynamo, BigTable, Cassandra).
It's not that SQL didn't work, but that the persistence layer was too strong and therefore too slow for their very particular needs. It's like comparing a minivan/suv (mysql/postgres) to a drag racer (nosql databases). You don't want to drive your kids to soccer practice in a two-seater with no airbags, and a 5* crash safety rating isn't as important to the pink-slippers as horsepower and 0-60.
Or am I missing something?
Note that these companies did not move away from relational DBs until long after the "NoSQL is Web Scale" video. Yes, Google invented Big Table to help power search (and others), but their revenue system, AdWords, didn't move off MySQL until like 2015. And last I checked, Facebook is still a heavy user of MySQL with sharding.
The original NoSQL software had two major value adds: you didn't have to learn a new language, and were faster (typically via disabling fsync -- the DBA equivalent of running with scissors). If you knew SQL or an ORM already, you were really just hoping mongoDB was faster magically.
These days you can even just tune pgsql to support kv store formats: https://www.postgresql.org/docs/9.1/hstore.html. Yes, you'll have to pay someone to know how to DBA pgsql, or pay AWS to pay someone, but I'm comfortable paying that price.
Not all of those services can scale horizontally. Concurrency control most especially, but other things which assert global invariants are often too expensive. Most NoSQL systems remove some of these features in order to scale horizontally. But the problems they solved remain, and need new solutions. This has two effects: it forces clients to do more which hopefully means doing less complex stuff (you can write mega expensive computations in SQL where the nested loops might offend you in handwritten code); and it means higher risk of bugs and more engineering effort for correctness (e.g. transactions in application, eventual consistency, reimplementation of transaction log in queuing systems, etc.).
In transport analogies, RDBMS is like a lift helicopter, NoSQL is like a fleet of container ships. Or RDBMS is like a car, and NoSQL is like a train network. NoSQL is inflexible and needs lots of extra attention at the edges, while RDBMS needs a careful operator and doesn't work well beyond a certain scale unless you give everyone (or subgroups) their own instance (which could be sharding, it can work).
And if you don't have a really big problem, NoSQL is probably the wrong choice, not because it's fast with few safety checks, it's because most of them do very little for you, they can just do a lot of that scaled out.
If you're not scaling out, stuffing JSON into Postgres will give you a better experience even if you hate relational algebra.
Surprisingly, Spanner has tables with columns and you can run SQL on top of it.
Products support SQL because everyone knows it and it works, regardless if it isn't perfect. Trying to create a new version of SQL is ruining your capability to have millions of trained users that already know how to use your product.
First, people realized that schemas (just like static types) are extraordinarily important for robust software.
Second, NoSQL lost to SQL over the long run in pretty much all dimensions: query language, performance, scalability, concision, etc...
As a result, not only is NoSQL on the way out, but SQL databases have actually become better at supporting NoSQL features than any NoSQL database.
SQL didn't just win, it absorbed its opponent and became even better as a result. Never underestimate the versatility and adaptiveness of a technology.
Do you mean billion dollar companies?
Don't get me wrong, wouldn't go near the popular NoSQL databases I've used in the past again, but I sure wish I invented them.
maybe EdgeQL can have the same success by demonstrating improvements that can be added to SQL databases.
Null handling isn't intuitive in the beginning, but it makes it harder to let missing data go unnoticed.
The expression / table thing can be solved like we solved it in OctoSQL[0], and I think others have solved it in a similar way. Whenever you have more than a single scalar value in expression position, just create a tuple, or tuple of tuples out of it, which does act like a single value.
Instead of "SELECT ... FROM ... WHERE ..."
I would change it to: "FROM ... WHERE ... SELECT ..."
And you get the idea...
Area of curiousity at the moment as I too agree that SQL is a poor fit, even if the better DSL inputs eventually get reduced to SQL command text and parameter arrays.
Absolutely!
WITH
april := <datetime>'2020-04-01T00:00+00',
NewCustomers := (
SELECT Customer
FILTER
NOT EXISTS (
SELECT .orders
FILTER .date < april
)
),
AprilCustomers := (
SELECT Customer
FILTER
datetime_truncate(.orders.date, 'months') = april
),
NewAprilCustomers := (
SELECT AprilCustomers
FILTER AprilCustomers IN NewCustomers
)
SELECT
(count(NewAprilCustomers) / count(AprilCustomers)) * 100;
This assumes the following schema: type Order_ {
property date -> datetime;
}
type Customer {
multi link orders -> Order_;
} select sum( case when prev_cust.cust_id is null then 1 else 0 end) / sum( april_cust_count ) as pc_new_cust
from (
/* get unique customers in April */
select distinct cust_id,
1 as april_cust_count
from orders
where order_date between date '2020-04-01' and date '2020-04-30'
) as april_cust
left join
(
/* get customers with a transaction prior to April */
select distinct cust_id
from orders
where order_date < date '2020-04-01'
) as prev_cust
on april_cust.cust_id =
prev_cust.cust_id
Apologies for the lack of code formatting... I find that when SQL is written with a nice formatting (e.g. Nested sub queries with tabs) it reads a whole lot better.My team gets by with a very small subset of PostgreSQL functionality day to day because most of the stuff we're doing with our database is just not that complicated. Simple lookups, writes, joins when our applications interact with the database. Simple joins, grouping, aggregation when we personally interact with the database.
We are not confronted with the full complexity of PostgresQL every day. And on, the flip side, the database itself gives us killer functionality in the form of constraints and transactions. It offers a lot more, but this is all we care about an overwhelming majority of the time.
I am curious how you see it. Is there a compelling reason for a team like mine to leave their comfort zone to work with your new database? Does the new query language really solve any problems for Joe Sixpack, developer?
A) Not being able to express relational semantics.
In general, every programming language replacing its predecessor allowed to express about the same semantics, even if it wasn't natural to the new language.
One can write imperative Java/C++ even if the language doesn't like it, and successful functional languages allow escape hatches for mutable objects.
The various NoSQL languages typically fail this hard.
B) Not offering enough of an improvement.
Minor improvement isn't worth the 'yet another query language' burden. EdgeQL doesn't fall into A, but it may fall into B.
NULL is an annoyance, but not big enough to justify another language. Throwing an exception instead is a very double-edged sword. The author needs to show far more improvement to justify a new language (I'd have liked to see more examples of composability for instance).
Then the language is blamed for not performing well or yielding different results than expected.
Some points in this article are valid but I think the main issue is the general notion sql would be like javascript or c#. It is not, it is very different and needs a deep understanding, including the works of the underlying dbms, to perform well.
I guess i'm just not a fan of throwing new languages and tools at problems we identify, which seems to be a trend nowadays.
The tasks needed to actually take over where SQL has left off seem absolutely monumental though. I can't help but think it will never get there, just like every other attempted query language out there.
In my opinion, there are two things that can make SQL 100% better, which wouldn't be a new language, but rather an update to the language standard:
1) algebraic data types, allowing us to get rid of terrible ternary null logic and more closely model real world data domains.
2) a really well thought out date/time API, along the lines of JSR310.
Having worked with MongoDB for 5+ years now back to PostgreSQL, I do like SQL so much more than a custom query language. I would wish JSON would be better integrated in SQL, it kind of feels like an addon not the core. Otherwise SQL is a fine language.
Also I can leverage 20y of SQL.
https://edgedb.com/docs/datamodel/scalars/json#type::std::js...
SELECT to_json('{"hello": "world"}');
it would be
SELECT {"hello": "world"};
This is trouble for the example for calculating the average number of reviews across movies:
SELECT math::mean(
Movie {
description,
number_of_reviews := count(.reviews)
}.number_of_reviews
);
Never mind, they are not sets:> Strictly speaking, EdgeQL sets are multisets, as they do not require the elements to be unique.
The relational model is firmly based on the idea of a relation as a "set of tuples", and a major criticism of SQL has been that it views data as an ordered sequence of tuples.
So I'm skeptical of the claim that EdgeQL is really based on the relational model.
(Not clear whether multisets are ordered - wondering about window functions etc...)
1. Elimination of duplicates from every projection is prohibitively expensive.
2. Sometimes you actually _want_ duplicates to show up without injecting a synthetic key into every projection.
3. There's DISTINCT.
But (as I haven't read of their blog posts) I am a bit more reluctant about the whole thing when they describe it as an ORM.
Can we leave the ORM and take the query language and implement this as a Postgres extension?
But if you can define a new query language that can be implemented by existing relational DBs, you might actually have a shot at displacing SQL.
Do we really need to do better than SQL? I don't think so and i also don't think that the chosen new syntax is better.
At the end of the day, most critical is not the language but understanding how it works to optimize indezes etc. If you are only able to write simple SQL because you are not good in SQL/Databases, you will not optimize your Database independently from the language.
If you are good in SQL/Databases, you (or at least i) do not care about syntax details; You just look it up, and get acquainted to your specific underlying Database.
Do we really need to do better than C? I don't think so and i also don't think that the chosen new syntax is better.
At the end of the day, most critical is not the language but understanding how it works to optimize assembly etc. If you are only able to write simple C because you are not good in C/algorithms, you will not optimize your algorithms independently from the language.
If you are good in C/algorithms, you (or at least i) do not care about syntax details; You just look it up, and get acquainted to your specific underlying microarchitecture.
Also it does state 'we can do better than sql' and i do have a certain amount of practical experience to state my personal opinion that i do not think that their approach is actually better than sql.
They did show quite avg examples; Examples which are leading me to assume certain points like where they would like to replace sql.
e.g. result = dframe.select(*[f.col(colname).alias(f"{colname}_old") for colname in dframe.columns]).join(other_df, 'joincolumn', type='outer')
and so forth.
It is of course a declarative language, but more than that it does what a good language should do: explain in both directions.
Languages need to tell the machine what to do, and to tell the person reading the code what it was the original author was supposed to be doing. Many bugs happen when the two don’t match up, and the maintainer is often not the person who wrote the original code.
Well written and handwritten SQL is some of the least commented code I’ve seen because it doesn’t need comments — it is self explanatory.
But yeah, as long as you know what the underlying tables look like and what they enforce, then SQL is really easy to maintain and understand.
By reading the queries it generates it's quick to pick up how the SQL works! Another big advantage is that you can always pull the data into R and have a ton of general purpose tools available.
dplyr is aimed at data analysis though, so may be other use-cases for edge db?
1. A cleaner universal more natural syntax for analytics: I love writing python as it is to me such a cleaner syntax than C or Java. We could do the same for SQL and make something that feels more natural. Turning a common query like
> SELECT count(*), TO_CHAR(created_at, 'YYYY-MM-DD') FROM Accounts GROUP BY TO_CHAR(created_at, 'YYYY-MM-DD') ORDER BY TO_CHAR(created_at, 'YYYY-MM-DD');
into something much more natural like
> count by Day(Accounts.created_at)
2. A Visual SQL: for analytics it's so much faster to query and explore visually. Building queries visually means you don't make common typo or syntax or structure errors, joins happen smoothly, you can browse the data as you build, you don't need to google for syntax (what's that date function again?), and it works across dialects and databases. We've built and launched this a few months ago at Chartio https://chartio.com/blog/why-we-made-sql-visual-and-how-we-f...
In pseudocode:
newtype id = int
names = dict<id,string>()
balances = dict<id,int>()
credit_scores = dict<id,float>()
function broke_customers():
return balances.filter(balance => balance < 0).keys()
function exploitable_customers():
bs = balances.filter(balance => balance < 0)
cs = credit_score.filter(score => score > 100)
return bs.intersect(cs).keys()
In the end, most queries are "just" set theory ... and having a very thin disc io layer allows to use the host language to process queried data on the fly.It's very basic ... and does not address performant views, clustering, migration, etc ... but it's simple ... and does work well as demonstrated by the ECS systems in game development (which are an application of the concept).
(Sidenote: that's some messed up pseudocode ... I've been working with C#, Python and Haskell lately :-) )
I hope the writer reads http://www.learndatalogtoday.org/
In Clojure there are multiple databases that you can query by API, SQL and datalog
Doh, that's not what this discussion was about. It's an old wound that won't heal. :-)
All the modern SQL databases are unbelievably powerful.
table = (SELECT column | scalar expression FROM graph | table WHERE ..GROUP BY ... HAVING... ORDER BY...)
So in SQL, each scope is a table and that is the main primitive.
More metrics would be needed to criticize SQL orthogonality, instead of providing only one example of subqueries as scalar expressions, when they more generally produce tables.
Actually, SQL use the same query syntax for scalars and for tables and that could be seen as good orthogonality.
Very few people truly understand CMS-es, and therefore very few people truly understand Wordpress. I would be suspicious of any “Wordpress replacement” that didn’t come from someone with many, many years in the field.
As a front-end programmer for 7 years I feel I have a fine understanding about how a relational database and its queries can support my usecase. I understand the basics well enough to advice the backenders. Anyway, SQL or any Object oriented abstraction on top of it gives me migraine.
Let the critics criticize. Most people mistake pragmatism (SQL) for sound solutions anyway. I do feel there is also a need for graphical editors. Yet it is much better to build a graphical editor that compiles to something with comprehensible syntax.
Good luck
I never understood the need to rebuild a SQL-like solution bc SQL seems like the right answer already?
Between inner joins and SPs, what else could you possibly need for data?
It just looks like line noise compared to SQL, or whitespace significant languages.
While in calculus you declaratively describe the set of data you want and let the system figure out how to get it, in the algebra you describe how to construct the set you want.
With that in mind SELECT ... WHERE ... is calculus, UNION and JOIN, etc. are algebra.
I like SQL, though.
EdgeQL is the query language, EdgeDB is the engine. The latter does query optimisation. In theory EdgeQL could become popular with another engine.
I knew the basics but I took a weekend to catch up on some more advance use cases and I can really resonate with this article. Unsurprisingly I came down to a conclusion that SQL is just a bad language, no matter how you look at it. It throws away every code flow standard in favor of their own nonsensical flavor. Where normal synchronous programs go top-to-bottom SQL is a complete spaghetti of flow and logic.
Just take a look at the most basic syntax: `SELECT person.name FROM person` The variable is defined at the end of the program which is just absolutely silly, what if the program is 100 lines long; do I need to start reading from the bottom? SQL must be the reason mouse scroll wheels were invented.
As an alternative take a look at view based systems: `for person in people: yield person.name` — isn't it infinitely more understandable and readable?
Unfortunately it seems SQL is here to stay as most people would rather work with this mess rather than invest some time to adopt something better.
I wonder, why Datalog is not very popular for databases as a query language? Is it because of performance optimization? Could anyone provide some insights?
The post has weird self faults in its complaints - lack of consistency, and poor system cohesion.
Lack of consistency isn't with the SQL standard, it's with the implementation (this is recognize this later in the post too). Like browsers and the HTML spec - everyone implements the standard SLIGHTLY but non-trivially differently.
poor system cohesion - Being able to integrate/inter-op with every other language literally means poor system cohesion. They're mutually exclusive ideas. This is is why ORMs exist, so there is strong cohesion with a given language.
I'm sad because there's so much work put in here by extremely smart people, but this is a tool looking for a problem. SQL has its shortcomings for sure, but simply replacing it with a slightly cleaner language is not the answer. The benefits do not outweigh the huge amounts of drawbacks that would be required to adopt something like this.
I don't know much about EdgeDB and hopefully there's a lot more benefit I'm not aware of, but purely on the post itself, too many drawbacks.
I wonder if we started from scratch today would we end up with something like SQL.
This is a marketing article.
As long as there's nothing valuable in the technology itself why would I bother changing things?
You're assuming there's nothing valuable. I'd say there is. Whether that's enough to displace SQL I really doubt.
Like, duh. WTF should NULL be equal to?
Anytime I see people making this kind of argument about "doing better than SQL" I can immediately tell they are pretty much fucked in the head.
Good luck, edgedb peeps. You haven't got a clue.
In programming languages, NULL tends to be equal to itself. Why couldn't it be the same way in SQL?
NULL is undefined. It can't be equal or unequal to anything, including itself, for reasons that should be obvious.
The counter is: Why hasn't anyone yet?
SQL is easy. Data is hard.
So you decided to create yet another incompatible "SQL"?
And quoting MySQL's broken handling of a division by zero as a reference. Seriously?
Love it or hate it, sql is a standard and there is a ton of knowledge (stackoverflow answers, books, tutorials) and tooling (query builders, orms). This is either hopelessly naive, or hopelessly arrogant.
> Swift, Rust, Kotlin, Go, just to name a few, are great examples in the advancement of engineer ergonomics and productivity.
golang is definitely not an advancement in engineering ergonomics. It can't be grouped with the other mentioned languages.
EdgeQL is an explicit attempt to make not a new version of SQL, but a new language. It's about evolution, which is, again, explicitly noted. Saying "evolution is not needed" or "I don't want/need evolution" is strange to me. At the same time, giving constructive feedback is useful, as always.
But for most people out there who simply want to poke at their business data, SQL, or this article's stated solution - EdgeQL are all pains in the wrong places. If you are making the life of engineers a bit easier, then you have to think of the millions of My/Pg SQL installations.
If you want to make the larger audiences' life easier (the business people who need insights), then you need to think outside of SQL altogether.
It’s heresy to criticize SQL these days or even suggest that DBs could be easier and more robust. I envision a future DB language that offers perfect ease and safety with queries the way Rust has shown us that the memory unsafeness of C was voluntary all along.