Is there a programming language specifically designed for interacting with SQL databases?
Is there a programming language specifically designed for interacting with SQL databases that avoids the need for Object-Relational Mappers (ORMs) to solve impedance mismatch from the start?
If such a language exists, would it be a viable alternative to PHP or Go for a web backend project?
ORMs are one of the worst things ever created IMO. Sure they’re great to turn structured data storage into objects and methods that developers are used to, but every single one of them scales for crap and I can’t tell you the number of projects we have to go back and fix to be straight up raw SQL once it starts growing and becomes a bottleneck.
It's just a performance to development time trade off. Clearly the product was successful enough to demand coming back to improve the performance. Lots of software fails before it even reaches that point.
I'm curious under what condition an ORM impacts scaling at all.
ORMs merely generate a SQL query to run on the DB, then serialize the data it gets back, how your application svales should be unimpacted by using an ORM.
I'd assume if somehow it's impeding scaling then the query itself was structured poorly, or that particular ORM was very poor.
A good ORM should be able to generate the sql query in microseconds, the actual DB query time should be typically like 99% of the response time for your API, which the ORM has no bearing on.
The SQL queries I’ve seen almost every ORM create are highly inefficient compared to a good query designed by hand. That’s where I’ve always seen the delay get introduced. You end up spending lots of cycles on the query so the delay looks like it’s within the DB but when replaced by a custom query the bottleneck goes away. Quite often a quick fix is replacing the query with a store procedure or view and letting the devs work off of that.
The absolutely worst thing about them is they claim to be database engine agnostic. Surey the most basic stuff maybe, but make your queries a tad bit advanced and it stops working on different database engine. Also, how often do you switch to a database engine that is so much different from your existing one? I hate using Doctrine, stupid query builders make me develop twice as slow. On the other hand, Eloquent is kind of nice and has an easy way to write raw SQL queries.
Argh, your comment is such a pet peeve of mine, especially since my SQL knowledge is kinda arse (it's #1 of my todo list to learn): "just use raw SQL" is a terrible answer, because newbies now still don't know how to not use an ORM (and building classes is what they tend to know, so using a wrapper like Django or SQL Alchemy is ez pz).
How do I learn to use raw SQL, as a way to not use ORMs. Yes, learning SQL is step 1, but what is step 2? How am I going to do migrations, without having to manually run stuff, because manual work is faulty work. How am I going to track changes in my model, over time?
No matter how you tackle this, your front end likely communicates in json and your database in sql.
At the crux of it, your backend has the job of translating between the two without openly exposing the database to the front end (unless security truly doesn't matter for your app)
There's no easy way to get around the fact you simply just have to write logic to mediate between those two languages.
The best way I use to avoid mismatch problems between BE<->DB is I use Code First Entity Framework Core as my ORM, letting my EF Core spec act as the source if truth fir my db schema via automated EF migrations.
This means the only way you get a mismatch is due to merge conflicts not being resolved properly if 2 devs both mutate the db schema at the same time.
C#'s Linq is also the closest first class API I have seen that very closely mimics sql.
I genuinely find Linq queries on Entity Framework easier to write and read than sql.
Yeah Linq is truly unique in programming languages. The fact that I can write a where clause how I would in normal code and it just translates it into SQL is so much nicer than some DSL for filtering
100%, the extremely 1:1 way that c# translates into sql is prolly the closest to what OP wants, I've tried a variety of ORMs and EF Core us hands down the best I've used.
The fact it doubles as a DB Schema manager and migration engine is just icing on the cake. All my database related needs in one spot.
Have you considered raw queries (properly parametrized and escaped and all that)? You can’t beat the speed of getting exactly what you need with no overhead.
My #1 issue with raw sql is its just absolutely a nightmare to maintain.
I simply just can't easily, at a glance, do something as simple as "give me the list if every single chunk of code that touches this column on this table", which is like, 80% of my start points for debugging an error showing up on our backend.
"We sometimes get NULL being set on this column that should no longer be NULL if (other column) is getting set, can you investigate how that us happening?"
If you have an application that uses raw sql, simply just step 1 of "find all backend code that touches that column" is already 100x more effort than it should be, and that's even on a well maintained project.
If the sql is even slightly poorly maintained (and since you are tasking BE (some language other than sql) devs with maintaining SQL, it very often is very poorly maintained, often just shoved as raw magic strings in the middle of their code, so.etimes even generated dynamically.
At which point its just a fucking nightmare to figure out what the fuck is writing to that column.
With an ORM, the issue suddenly becomes as easy as clicking the "find references" button on the field for that column and, boom, all bits of code that touch that field in any way are now listed put for you, ez.
If you’re at the point where you need the performance boost from raw SQL over an ORM, you have solutions for these problems such as a well-maintained, centralized interface or store for SQL.
OP wasn’t asking for best principles, OP was asking for a language that replaces ORMs. That’s SQL directly in your code.
For example, you'd still write classes for your tables:
public class Users
{
public int Id { get; set; }
}
and then you'd just do
var query = $"select * from {(nameof(Users))} where {(nameof(Users.Id))} = 10;";
That let's you write raw sql about as close as it gets, while still having some degree of type-safety. You could drop a query like that into Dapper, and you're pretty close to just using raw sql.
There are lots of ways to find out what code touches a column. For example, if the code is deployed as stored procedures, you can easily query the text of all stored procedures for references to that column. If it's not deployed that way (maybe in a Git repo somewhere), it's still possible to search that text for the references.
But the problem you describe wouldn't be present if you had good documentation. If developers (front end, back end, and data alike) were able to create documentation that detailed what their code does, and you maintained a knowledge base or data governance platform (like Collibra, though even a wiki would do), you could simple click on the field name and immediately see every article or code reference that uses it as one of their attributes.
Good documentation is all I'm saying. It just usually doesn't exist because the bean counters don't prioritize time to create it, and the developers commonly don't want to (though they'll complain about the lack of it later) or aren't trained to do it effectively.
Everyone else has more experience than I, and I am not sure these are exactly the kinds of answers you are looking for...but the two things I have thought is using something like PL/SQL and stored procedures, so much of your backend logic is removed from the server and set into the database itself. Not exactly what you are looking for I think, and it has problems of its own.
Second, Prolog is a great query language (from what I am told) and capable of running a server. TerminusDB runs their server in prolog, and also postgres has a prolog implementation. It would be interesting to play with these things, but they may not exactly be what you are looking for.
I am not as familiar with RDBMs internals, but you could also build your server in the database. Right now, I am building a server client of sorts with Oxigraph. I have a store object that I am manipulating directly with rust code. It is an option. However its not going to be very flexible, and it does complicate the sanitization issues.
Also, prolog is a complete language, very capable of running the server. I don't know what kind of architecture you are thinking of and having the distinction between datalog on the database and prolog in the server might be problematic. Also, I may be projecting a little. I wish I could be using prolog. But alas.
As pixxelkick already said, you most likely need some kind of mapping anyway between backend sql and frontend json. If you would have a language designed for interacting with sql databases it would probably suck for everything else.
In java with jooq and its generator it works pretty well, actually. You get the database types as java types and have rather safe queries. Type support breaks down for large and complicated queries, though.