News for hackers. Stuff that matters.
Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @10:29AM (#22945922)
I never realized this before but many excellent developers struggle with SQL beyond simple SELECT statements. I have a colleague who is by all accounts a deeply technical person but one day he confessed to me that he didn't really grok SQL and that he'd rather work with a "real" procedural programming language to just store and retrieve data.

Part of it may be due to the fact SQL isn't really a programming language but a declarative DSL for manipulating sets and tables. Things like GROUP BYs and PARTITION BYs (window functions) that come naturally to mathematical types/functional programmers are less intuitive to procedural programmers.

I suspect this was what attracted developers to noSQL databases like Mongo in the first place -- it's more attuned to a programmatic mindset.

(this is not universally true of course -- many programmers have no issues with SQL at all.)

Re:Things I wished more developers knew about databases by brightball on Wednesday April 22, 2020 @11:29AM (#22946587)
I firmly believe that every developer should spend 2-3 weeks early in their career working with nothing but SQL. It will pay huge dividends for the rest of it.

IMO a lot of the issue is that developers for many years using Java or PHP, were using SQL to handle everything. The application language was a pass through later between the client and the database.

Your goal was to accomplish as much as possible in a single query and then to simply return the results of that query to the interface. That meant formatting numbers or currency in your SQL. Optimizing inserts or updates to be handled in a single query. Grouping, counting, left/inner joins, having statements to filter on aggregate results. More than 1 or 2 queries for the primary area of the screen was both a rare and foreign experience.

And then ORMs started to slowly integrate themselves into the flow of various frameworks to automate the repetitive things around CRUD tasks. Then to address scaling & bloat problems we saw an uptick in REST APIs, microservices that further made those ORMs the norm...and then many developers started actively trying to stay within those API constraints to an almost religious degree which led to a nested payload becoming acceptable fueling the whole "NoSQL" situation, along with the idea that it was somehow better to repeat the same data thousands of times over.

A whole lot of people pushed back against this and eventually, it mostly ran its course. I've often seen resistance to SQL to be driven by fear of SQL more so than anything else. As soon as people get a basic comfort level with SQL, it become almost automatic.

Re:Things I wished more developers knew about databases by TremendousJudge on Wednesday April 22, 2020 @12:01PM (#22946984)
> The application language was a pass through later between the client and the database.

This style of doing things resulted in spaghetti style unmanageable databases, filled with an unknowable number of triggers and procedures, all written in PL/SQL (which is much, much worse than either Java or PHP). The reason why ORMs started to become popular is that you can write your application without filling your DB with arcane and inscrutable logic

Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @02:43PM (#22948815)
There's a middle way which is very powerful: SQL views (just SQL queries; no triggers or procedures)

Here's a powerful mindset trick: think of SQL views as an sort of a REST API, but whose access language is SQL and not HTTP, and that returns data in a table rather than JSON (hierarchical).

I once tried to build a REST API to a database, and someone told me I already had a battle-tested and highly performant API that outperformed REST at scale -- it's called SQL. A SQL view is a dynamic lens into the underlying tables, so even if the underlying tables/schemas were to change, your consumers don't care as long as they can access the SQL View.

SQL views are also composable: you can build SQL views on top of other SQL views, and any changes made in the base views are propagated throughout. Need to add/transform a field? Do it in the view. Need pull in auxiliary data? Bring it in through a JOIN in the view. I've built many systems by composing SQL views and they're very maintainable and very flexible. They're kind of like function compositions but on tabular data.

The rule of thumb is: always access a database through a view, never the underlying raw tables. In computer science, a great many maintainability issues are alleviated through a layer of abstraction/indirection, and SQL views provide exactly that.

This centralization of the core logic becomes especially powerful if the database is accessed from multiple consumers (webapps, analytics backends, Tableau, ML tools, etc.) The "API" remains consistent throughout.

Re:Things I wished more developers knew about databases by jwdunne on Wednesday April 22, 2020 @03:35PM (#22949331)
This is a very interesting comment!

Two questions:

Do you have any example code that shows how this works? I get what you’re saying intuitively but example code will help me bring it to table.

What about cross cutting concerns? I’ve found stored procedures to be a performant solution here. By version controlling them, and limiting to pure functions, I found them quite maintainable. Would you instead just define a new view, or extend an existing one, or refactor into a separate view that’s then joined into the existing views?

I haven’t delved as far as views, admittedly. One app featured a bit of complicated logic and eschewing the ORM in favour of raw SQL helped (instead of getting tangled up in Demeter chains). Despite new developers, who have used purely ORM for years, shitting their pants at the raw SQL, both of us who worked on it felt it was the right call. We feel much better about leveraging more of the database in new projects.

In fact, when we took our experience to a Django project, my colleague wrote a Manager method in such a way that an ORM favouring developer questioned because it looked too much like SQL. But it was the obvious implementation to us after using raw SQL. And, after benchmarking, the most performant.

Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @04:03PM (#22949599)
Briefly,

1. Let me try with a simple example. Suppose you have a fact table A with fields (ItemID, Item, Amt) where Amt is in USD. Rule of thumb is: don't expose A to the consumer; instead write a SQL View V_A and expose that instead:

  CREATE VIEW V_A AS SELECT ItemID, Item, Amt FROM A
Then suppose a European counterpart wants to use the same API but needs the amounts to be in Euros. You can write another view: (in practice the conversion 0.92 shouldn't be a static number, this is just for illustration)

  CREATE VIEW V_A_EURO AS SELECT ItemID, Item, Amt * 0.92 AS AmtEUR FROM V_A
Expose this to the Europeans. You can keep stacking views on top of other views. Your U.S. consumers will always see the data through the lens of V_A and your European consumers will always see it through V_A_Euro.

Suppose the underlying table A now changes. There's been a merger and the company now stops reporting currencies in USD, and everything is now in British Pounds so your DBA adds a field AmtGBP and starts populating that field instead. Amt still contains historical data, but moving forward the data in Amt will be NULLs; AmtGBP is the new internal baseline currency. From a VIEW perspective, all you have to do is:

  ALTER VIEW V_A AS SELECT ItemID, Item, ISNULL(Amt, AmtGBP * 1.23) AS Amt FROM A
Your V_A and V_A_EURO consumers (could be Tableau, Excel, other SQL views, etc.) will still happily receive data per usual, unaware of the internal changes (the British are coming!) that have occurred. Contract kept.

  Table A <- View V_A <- View V_A_Euro
2. Cross cutting concerns come in many forms so not sure if I can address. Stored Procedures are definitely an acceptable abstraction -- they accept parameters and can return tabular results just like VIEWs. They do however work in a procedural manner (like subroutines) and can produce side effects, which is sometimes necessary to accomplish very specific tasks. VIEWs on the other hand are more similar to pure functions (unless random number generation is involved) with no side effects. Because views are dynamic, they flex with your data and VIEW definitions.
Re:Things I wished more developers knew about databases by Izkata on Thursday April 23, 2020 @12:20AM (#22952768)
There's another step that could be added there, too: After the ALTER VIEW, V could be slowly incrementally updated over however long you need to back-populate AmtGBP, and the views will continue to just work the whole time. Once done, V_A can be simplified to remove the ISNULL and Amt, then Amt dropped from V. That way you don't get build-up of cruft over the years, and the experience isn't interrupted for the migration.

(Possibly a bad idea for currency conversion for various reasons, but just wanted to mention it since this type of migration may be just right for other data)

Re:Things I wished more developers knew about databases by jwdunne on Thursday April 23, 2020 @09:20AM (#22955603)
Is there anything you recommend for handling SQL definitions in version control, development and production envs?

For production, I created a command on the app that loads the stored procedures into the DB idempotently on each deployment/configuration. This won’t work if the app server scales but allowed us to store stored procs in VC.

For development, we ran the command on each page load as a sort of hacky “live reload”. It didn’t work well (which highlighted the issue with scalability in production) because Postgres, fairly, doesn’t like parallel redefinitions of the same stored proc.

I’m not sure how best to automate this. For production, seems like a case of running a command once per DB server.

And in development, using a fs watcher that loads changes in.

But I don’t know, this is new territory for us and I couldn’t find anything out there to manage it within the context of a web framework. Perhaps I’m searching for the wrong thing.

Re:Things I wished more developers knew about databases by skdv on Friday April 24, 2020 @02:53AM (#22965345)
Web frameworks like Rails/Django use the idea of migrations to make changes to the database. The idea is that you have a set of migration scripts like: migrations/1765_create_table_users.sql migrations/2891_store_procedure_x.sql migrations/5892_change_store_procedure_x.sql

(.sql/.rb/.py, it doesn't matter).

And you have a "migrations" table in your database that contains the numbers of the migrations that have been run:

  select * from migrations;
      version
  ----------------
   1765
   2891
Every time you deploy to production automatically check which scripts in your db/migrations folder don't exist in the migrations table and run them. (In the current example, you'd run the 5892_change_store_procedure_x.sql that hasn't been run yet).

How to do with functions/procedures?

You commit the function definitions in a functions folder to your version system like:

  db/functions/report_x.sql
  CREATE or REPLACE function report_x() returns ...
When you change this file, nothing happens, you need to create a migration to re-run this code once. In rails migrations would be:

  class UpdateReportXFun < ActiveRecord::Migration[5.2]
    def up
      execute File.read(
        Rails.root.join('db','functions','report_x.sql')
      )
    end
  end
Re:Things I wished more developers knew about databases by jwdunne on Friday April 24, 2020 @03:08AM (#22965425)
Yeah, I’m aware of that, thank you. I was wondering if there was a way with a faster feedback loop and allowed for bug fixes without creating a new migration.
Re:Things I wished more developers knew about databases by skdv on Friday April 24, 2020 @04:25AM (#22965798)
You don't need to write the migration until you're done. It's possible to have a very tight feedback loop in any case.

I'm doing a lot of work in a Rails codebase where I edit views/functions/procedures all the time. My setup is quite usable.

My current setup: I edit those .sql files and run them with psql in my local while developing (without writing any migration yet).

I have some like this running on one screen to make sure the modified files are executed by psql immediately as I change them (you could use `guard` too):

  find ~/projectx/db/functions -type f -name "*.sql" | entr -d -p psql db_name -f /_
and I edit the db/functions/*.sql files freely, adding things, changing behaviour of functions and they are updated on the fly. (I can run tests -or try things in the browser- to verify my changes work as I expect).

--

Once I finish and I know everything is great, I just add the migration. The migration is simply an indicator of which files I've modified and to specify the right order to run them (which is useful if they are dependencies), like:

  # migration
  def up
    execute File.read(function1_sql_file)
    execute File.read(function2_sql_file)
  end
I could have an alias that automates generating that migration but it's just 4 lines...

[ I'm also using pgTAP to write tests for functions, it's quite nice :) ]

Re:Things I wished more developers knew about databases by jwdunne on Friday April 24, 2020 @01:20PM (#22970579)
Oh wow, now I see what you mean. Thank you! That’s work great. I wasn’t aware of ‘entr’ either, that’s exactly what I had in mind!

I’ll have a look at pgTAP too. Naturally we want to test in CI, I can see this working really well. I did look at myTAP too, since we have a few MySQL instances.

Re:Things I wished more developers knew about databases by cgh on Wednesday April 22, 2020 @04:39PM (#22949944)
Agreed, and a good example of this is implementing search. You can define a view on top of your searchable entities that includes the urls to the entities, as well as searchable metadata (entity descriptions or whatever). So when you add new searchable items, you just update the view to include them and the code to select from the view doesn't change.
Re:Things I wished more developers knew about databases by deckard1 on Wednesday April 22, 2020 @06:40PM (#22951000)
> highly performant API that outperformed REST at scale -- it's called SQL

You are conflating many disparate things here.

SQL is a language (DSL) for accessing data. REST is a protocol and a data transport method (one could surmise a way to do REST without HTTP, but when reasonable people refer to REST they mean HTTP (over TCP (over IP (etc.)))).

Even REST is not an API. You can't do anything with a GET or a POST without other abstractions built on top of that. So I don't understand how anyone could make performance claims beyond something like "HTTP is slow" and "binary transport is faster", with regards to SQL vs. REST/HTTP.

SQL does not define how you receive your data. Databases have different methods of sending SQL and responding to SQL. Oracle, MSSQL, MySQL, etc.

> This centralization of the core logic becomes especially powerful if the database is accessed from multiple consumers

That's the entire point of an API. Any API. REST APIs, even.

Re:Things I wished more developers knew about databases by cryptonector on Wednesday April 22, 2020 @05:49PM (#22950543)
Not only that, but VIEWs can have INSTEAD OF triggers, which then lets you build powerful abstractions in SQL.
Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @06:10PM (#22950741)
Amazing. I didn't know it was possible to write to a VIEW.
Re:Things I wished more developers knew about databases by cryptonector on Wednesday April 22, 2020 @06:53PM (#22951086)
Changes everything no?
Re:Things I wished more developers knew about databases by hobs on Thursday April 23, 2020 @11:40AM (#22957171)
Right, and this is normal except that people take it too far, I love to find 10(!) depth nested views hiding table valued functions and scalar functions everywhere - you cant reason about the rat's nest created.

If you want to make simple views that expose useful nouns I am down with it, but I have seen it taken too far too many times.

Re:Things I wished more developers knew about databases by MaxBarraclough on Thursday April 23, 2020 @12:53PM (#22958028)
What do you make of tools like LoopBack which automatically map REST to SQL (without you having to write code for each mapping)? https://loopback.io/doc/en/lb4/Database-connectors.html
Re:Things I wished more developers knew about databases by wenc on Thursday April 23, 2020 @01:46PM (#22958659)
Postgres has something similar called pgREST too. I think I would only adopt these kinds of interfaces if the consumer insists on accessing the data through a REST interface.

If you are building something from scratch, or your consumers don't have a hard requirement for going through REST, I would go directly to the database view.

Re:Things I wished more developers knew about databases by projektfu on Wednesday April 22, 2020 @06:58PM (#22951128)
Are you also promoting CQRS?
Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @07:17PM (#22951233)
Not really. CQRS adds too much complexity in many cases.
Re:Things I wished more developers knew about databases by coliveira on Wednesday April 22, 2020 @12:58PM (#22947646)
This is trying to avoid the reality that the data is in a database. A database is not just a flat storage area that can be poked by code from outside. It has a lot of relationships and integrity constraints that need to be maintained by the DB itself, and all this is expressed in SQL/stored procs. Trying to avoid this is basically removing the power of a DB and converting it into just an expensive and cumbersome storage area.
Re:Things I wished more developers knew about databases by breischl on Wednesday April 22, 2020 @01:50PM (#22948251)
But now you're filling your application with arcane and inscrutable logic, with an extra layer of abstraction via the ORM to make it even less scrutable.

I think one should view a SQL DB like a microservice. Instead of REST endpoints (or gRPC or whatever), create stored procedures. These define a strong contract with your DB, the capabilities that it provides to your app(s). Now you know what the query and insert patterns are, and can tweak the table layout under the covers without screwing up your application code.

Of course you can abuse this into a spaghetti monolith, just like you can evolve a microservice into a spaghetti monolith, but you shouldn't. There's no technology that will prevent you from making poor architectural decisions, you just have to not go down those dark paths.

Re:Things I wished more developers knew about databases by wenc on Wednesday April 22, 2020 @03:05PM (#22949026)
> Instead of REST endpoints (or gRPC or whatever), create

> stored procedures. These define a strong contract with your DB

Exactly. It took me years to grasp this, but when I did my code became much simpler.

A REST API (that returns JSON) has to contort a tabular data structure into a loosely-typed hierarchical data structure (JSON) which has to be read back, reconstructed and in many instances type-checked (e.g. DATETIMEs are not native to JSON, nuanced datatypes like DECIMAL(18,3) are lost).

Whereas a SQL interface returns data in its native tabular format with all the correct types.

Re:Things I wished more developers knew about databases by LouisSayers on Wednesday April 22, 2020 @08:27PM (#22951626)
I remember people I used to work with arguing against stored procedures for two main reasons.

1) Version Control - I guess a lot of the stored procedures were being put straight into the DB without recording a history of the changes. These days you could easily do this using DB migrations I guess.

2) Testing - is unit testing a thing for Stored Procedures? I guess again, you might be able to do this from code as well programatically adding a stored procedure, running a bunch of tests and removing it again.

I do wonder - what do people generally do in practice for overcoming these objections? Does anyone have any other objections around using stored procedures?

Re:Things I wished more developers knew about databases by breischl on Thursday April 23, 2020 @02:33PM (#22959333)
1) I find this kinda funny. Why are you worried about this in SQL but not for other code? It's not like it's hard to chuck Python, JS, Ruby, ASP, etc code straight into prod, you just don't do that because it's stupid. Don't do it for SQL either. If you really want to, build out user permissions that only allow your CICD system to change them.

2) TBH we never built anything complex enough to need this, and I would tend to think that if you do need this you're probably overcomplicating your DB. But you could probably do something that creates a temp DB, populates example data, and then runs tests.

Re:Things I wished more developers knew about databases by Ma8ee on Thursday April 23, 2020 @04:40AM (#22953953)
I'm using Red-gate tools for all of the above. They are covering source control and unit testing and a lot more, but only for SQL Server.

My previous employer used some homespun systems for the same. A bit clunky, but easier to do than most people thinks.

Re:Things I wished more developers knew about databases by pjmlp on Saturday April 25, 2020 @04:30AM (#22976621)
Both Oracle and SQL Server do support versioning tools and unit tests for their stored procedures.

You also have graphical debuggers for them.

Re:Things I wished more developers knew about databases by karatestomp on Wednesday April 22, 2020 @12:29PM (#22947334)
But going too far the other way is how you end up with performance 100-1000x worse than it should be. Which is an actual thing that happens quite often in the wild. Also often ends up heavily dependent on some ORM or framework, making rewrites or multi-client DB access dangerous and painful.
Re:Things I wished more developers knew about databases by eternauta3k on Wednesday April 22, 2020 @12:43PM (#22947491)
You can create pretty complex SQL queries with SqlAlchemy's ORM, without going back and forth to the DB.
Re:Things I wished more developers knew about databases by jayd16 on Wednesday April 22, 2020 @12:51PM (#22947577)
This is the exact fear of SQL that's being talked about. You can make a mess of anything but its not hard to have a well maintained relational DB with minimal cruft.
Re:Things I wished more developers knew about databases by jtdev on Wednesday April 22, 2020 @01:17PM (#22947889)
In my observations, ORM use has a perspicuous relationship to piles of arcane spaghetti code.

Not to mention, 50%+ of ORM managed DB schemas that I've observed don't have proper constraints, indexes, relationships, etc. Because the developers using the ORM think it's a magical tool that makes understanding SQL and relational databases optional.

Re:Things I wished more developers knew about databases by oftenwrong on Wednesday April 22, 2020 @06:55PM (#22951096)
When you give an object the power to access to the db, you invariably end up with db access everywhere you can pass that object.
Re:Things I wished more developers knew about databases by harikb on Wednesday April 22, 2020 @12:34PM (#22947381)
There is an entire world between ORM and PL/SQL. Programmatically constructing SQL statements is also a thing. Just because someone writes SQL does not mean SQL needs to be spread through out code or that we need to have lot of logic in PL/SQL. Of course, there will be cases where a store procedure is desired (any kind of validation that cannot be expressed as fkeys, canonicalization of some core data components etc). I worked on DBs writing SQL for several years with only minimal code as stored procedures.

Of course the database vendor and culture also plays a role. We were primarily a mysql/postgresql shop

Re:Things I wished more developers knew about databases by resu_nimda on Wednesday April 22, 2020 @01:37PM (#22948094)
How did you minimize roundtrips between server and DB, or did you find that they were not a big concern?

I'm working on a project with a Postgres database, and as it gets more complex I'm moving more stuff into stored procedures, pretty much wherever a single action requires multiple statements in series (e.g. check if this thing exists, check a value, get the id of some other thing, on success update another table).

Of course I would prefer to leave as much of it in the middle tier as possible because the ergonomics are better there but I don't want to sacrifice performance.

Re:Things I wished more developers knew about databases by monocasa on Wednesday April 22, 2020 @01:57PM (#22948324)
I think they're saying that you profile your changes on an individual query.

Yeah, if all of your queries are slow, you've got more work to do, but that doesn't change the overall process of optimization.

Re:Things I wished more developers knew about databases by pjmlp on Saturday April 25, 2020 @04:26AM (#22976610)
Given how strong typed PL/SQL is, based on Ada, graphical tooling like SQL Developer exists, I wonder why it is much worse than either Java or PHP.

High performance SQL code should stay on the database, instead of doing wire round trips.

Re:Things I wished more developers knew about databases by randomdata on Thursday April 23, 2020 @01:48AM (#22953180)
> I firmly believe that every developer should spend 2-3 weeks early in their career working with nothing but SQL. It will pay huge dividends for the rest of it.

That pretty much describes my career, except it was more than 2-3 weeks. I agree there is value in being familiar with the ins and outs of SQL, but...

> As soon as people get a basic comfort level with SQL, it become almost automatic.

I don't know about that so much. I find that as soon as I need to write something much more complex than a simple select statement I am all but guaranteed to get caught by SQLs many gotchas. Eventually you realize the mistake, and that experience provides the knowledge to know how to correct it, but a good language helps guide you away from being trapped by those mistakes in the first place.

SQL is not a good language. It was clever for its time, but we've learned a lot about language theory in the many decades since. It is a travesty that we haven't put more effort into designing a modern database query language. To use SQL in 2020 is like writing software in COBOL when you could be writing software in Rust. Where is the declarative query language equivalent of Rust, Haskell, etc.?

The NoSQL movement was supposed to be about improving on query languages, but sadly it soon turned into "NotRelational" instead, which killed off any momentum away from SQL that was built.

Re:Things I wished more developers knew about databases by petrocrat on Wednesday April 29, 2020 @07:15PM (#23025718)
>Where is the declarative query language equivalent of Rust, Haskell, etc.?

Maybe Cypher from Neo4j?

Re:Things I wished more developers knew about databases by SkyPuncher on Wednesday April 22, 2020 @08:16PM (#22951554)
> I firmly believe that every developer should spend 2-3 weeks early in their career working with nothing but SQL. It will pay huge dividends for the rest of it.

I did this (actually for longer), but it always washes away.

One challenge for me is I don't see an incentive to learn complex SQL setups unless absolutely necessary. Since I tend to work at startups, development velocity is way more important than optimized codebases. I'd rather write the "dumb" solution that nearly every engineer can grok than the "elegant" solution that goes above people's heads.

That aggregate function, yes, I know I can do it 100% in SQL. However, it's much easier for me to selectively pull parts into memory and modify them with language tools I work with everyday. When the junior needs to modify that function, they can do it with tools they're most familiar with.

Re:Things I wished more developers knew about databases by lhorie on Wednesday April 22, 2020 @01:08PM (#22947783)
With the whole shelter-at-home thing, I had a chance to work on a simple app for my kids. One of the corollaries of "simple" was avoiding an ORM.

Implementing logic is single SQL queries can definitely be a bit challenging, but I thought it was also quite rewarding and liberating - Raw SQL is incredibly powerful!

Re:Things I wished more developers knew about databases by beckingz on Wednesday April 22, 2020 @02:30PM (#22948678)
At first I missed for loops.

Then I was empowered and did not miss for loops.

Now I still miss for loops.

Re:Things I wished more developers knew about databases by techbio on Wednesday April 22, 2020 @12:55PM (#22947617)
I have a side-project to solve Kakuro puzzles with SQL logic, not because it's useful, but because it seemed possible and distinctively challenging.

I'll show off the POC if I ever get around to smoothing the rough edges.

Re:Things I wished more developers knew about databases by Matrixik on Wednesday April 22, 2020 @02:07PM (#22948435)
Here is one nice example: https://sivers.org/pg
Re:Things I wished more developers knew about databases by dominotw on Wednesday April 22, 2020 @11:40AM (#22946728)
> I firmly believe that every developer should spend 2-3 weeks early in their career working with nothing but SQL. It will pay huge dividends for the rest of it.

i did tons of sql couple of years ago on a reporting team. Now I do android dev fulltime and don't remember any SQL beyond basics, highly doubt it will all come back to me if i tried.

Re:Things I wished more developers knew about databases by baq on Wednesday April 22, 2020 @12:58PM (#22947654)
it doesn't matter, you'll google the details. many people aren't aware that sql isn't just a stupid way of filtering tables and can do things server-side that you'd spend hours implementing and testing on the application side with worse performance in the end most of the time.
Re:Things I wished more developers knew about databases by crazygringo on Wednesday April 22, 2020 @11:26AM (#22946547)
SQL is very much like CSS to me.

It's declarative, the primitives seem entirely non-intuitive, it often takes a lot of fiddling to get what you want, the behind-the-scenes execution is mostly a black box, and while it's supposed to work the same on different implementations (of browsers/databases), there are tons of little gotcha quirks.

All in all, they're both entirely different skill sets from traditional programming, and also where experience counts for a ton more than just normal logical thinking.

Re:Things I wished more developers knew about databases by acdha on Wednesday April 22, 2020 @02:03PM (#22948389)
> It's declarative, the primitives seem entirely non-intuitive, it often takes a lot of fiddling to get what you want, the behind-the-scenes execution is mostly a black box, and while it's supposed to work the same on different implementations (of browsers/databases), there are tons of little gotcha quirks.

My reaction to that is that it's similar in a different way: everyone needs to use it but many developers don't take it seriously, avoid learning how it works, and then complain that it's unintuitive (i.e. not something they had already known) and hard to use because they're basically just poking randomly until they get close enough to what they want.

It's true that not every implementation is the same but … where else is that not true? This is also true of operating systems, filesystems, every library implementing a standard format (“Why doesn't this PDF open in …”), etc. I would have trouble supporting the belief that databases are an outlier in this regard.

Re:Things I wished more developers knew about databases by fools on Wednesday April 22, 2020 @04:30PM (#22949838)
If I write a C program, especially with the appropriate compiler warnings enabled, or some filesystem code, there is a high chance that it will work across platforms with no further coding necessary. Anecdotally, the same cannot be said for CSS or SQL.

It doesn't matter much for SQL, because I always know what database I'm using, but for CSS, it's a massive pain.

Re:Things I wished more developers knew about databases by acdha on Wednesday April 22, 2020 @04:47PM (#22950016)
That's a charming belief about C which is only true if you work on the same operating system, processor, and don't do anything complicated. If those are not true, as I've experienced many times over the years, you will learn otherwise about things like differences in floating point behaviour, memory allocation and access patterns, which filesystem and/or locking semantics, etc.

In other words, it's about as true as it is for CSS and SQL, where that kind of simple use is also stable.

Re:Things I wished more developers knew about databases by fools on Wednesday April 22, 2020 @04:49PM (#22950034)
Yes, I write fairly boring applications. But the point is that C is mostly cross-platform for those boring applications, whereas the the "cross-platformness" of CSS and SQL fall apart for even the simplest of tasks.
Re:Things I wished more developers knew about databases by acdha on Wednesday April 22, 2020 @04:52PM (#22950072)
Again, I think you're viewing this through the lens of relative experience. I have seen tons of C code which required substantial fixes to work portably (bonus points when this was exploitable) and I have plenty of CSS and SQL which hasn't had to be touched in years.
Re:Things I wished more developers knew about databases by taffer on Wednesday April 22, 2020 @12:08PM (#22947073)
When you look at SQL from a logical/set-based perspective, it is by no means unintuitive. Basically, all you do is join all the tables you need and then filter out everything you don't need and maybe do an aggregation here and there.
Re:Things I wished more developers knew about databases by crazygringo on Wednesday April 22, 2020 @12:41PM (#22947467)
How about the following:

- When to use JOIN vs a subquery?

- When is a subquery actually a correlated subquery? Will this destroy your performance? Or is it a critical feature?

- Should you put constraints in the JOIN or in the WHERE? Will the distinction drastically affect performance?

- When do you use WHERE vs HAVING?

- Is the NULL from the join because no joined row was found, or because the joined row had a NULL value itself?

Etc. etc. The basic concepts are simple, but the implementation details quickly become very complex, particularly when you're ensuring high performance with indices, and making sure the query uses the indices.

And all of the questions I pose above have clear answers... but the answers certainly aren't obvious from SQL basic concepts.

And also, while JOIN seems like it ought to be intuitive, in real life it seems like it's like pointers in C -- some people get it pretty quickly, other people struggle forever.

Re:Things I wished more developers knew about databases by jayd16 on Wednesday April 22, 2020 @01:03PM (#22947719)
Like everything else, write it the simple/elegant way then profile it and tweak if you have to.

Once you're at the point where you have to worry about these things, tuning the SQL is still probably much less complex than writing the query in your app language or figuring out how a NOSQL db can do these joins.

Re:Things I wished more developers knew about databases by izacus on Wednesday April 22, 2020 @01:23PM (#22947953)
In reality it rarely works this way - there's plenty of systems which are falling apart due to "death of thousand cuts" type issues. You run a profiler and most of the queries are slow and there's no one obvious part to optimize - because developers over the years ignored basic optimizations and there are inefficiencies everywhere.

E.g., for a quick practice run, try optimizing Wordpress without making it a static page via caching - how many queries will you have to optimize and how much of a codebase rewrite will it be to make it significantly more performant?

Re:Things I wished more developers knew about databases by jatone on Wednesday April 22, 2020 @03:08PM (#22949051)
in reality it does work that way.

the problem you describe is completely different and its more a measure of system health in its entirety of the DB. it can be easier to fix or harder depending on the precise cause. but that's a standard debugging skill which isn't strictly in the DBA skillset.

Re:Things I wished more developers knew about databases by james-mcelwain on Wednesday April 22, 2020 @09:50PM (#22952089)
This is my experience especially with ORMs. It's really hard to optimize when your "top query time" list is just a list of your most frequently called methods, where there's no single obvious pathological case, but lots of little inefficiencies.
Re:Things I wished more developers knew about databases by taffer on Wednesday April 22, 2020 @01:08PM (#22947780)
> The basic concepts are simple, but the implementation details quickly become very complex

True, but those kinds of questions come up in every language: Should I use an array or a dictionary? Should people have references to projects or should projects have references to people or both? Is money a float, an int, a decimal or should I write my own money class? Should I memoize the results? Is it thread-safe?

As you can see, this could go on forever, pretty much for any language.

Re:Things I wished more developers knew about databases by UncleMeat on Wednesday April 22, 2020 @01:49PM (#22948233)
They do. And language designers seek to smooth the edges and develop ways to encourage devs to write clear and intuitive code. When a language says "well, these are hairy questions that you should just figure out" we tend to criticize those languages unless they have clear reasons for that decision. It should be obvious that something is thread-compatible. "Well, if you model it in pi-calculus it is easy" is a crappy way of handling criticism.

"Its easy if you think about it mathematically" is not enough.

Re:Things I wished more developers knew about databases by taffer on Wednesday April 22, 2020 @02:12PM (#22948485)
In which language is it obvious not to put money into a float? In which language is it obvious if I want a synchronizedSortedMap or an arrayList?

There are simply things you have to learn to use a technology. If you want to write Java, you need to know what a variable is, what a for loop is and what Inheritance/Interfaces are. Likewise, in the case of SQL, it means you need to know concepts like normalization, ACID and joins. Just poking around until the code works won't do it.

Re:Things I wished more developers knew about databases by UncleMeat on Wednesday April 22, 2020 @02:22PM (#22948590)
No language is perfect. But surely you'd agree that there is a spectrum here. In C++ you have to think "should this be a pointer or a reference" all the time. In most modern languages, you never do. And although there are clear methods to write C++ well, it is rightly criticized for being overly complex and unintuitive. For example, std::set is ordered. That's a basic mismatch with expectations. Sure, you can just check the docs. But how much code would be more efficient if they had just spent a bit of time making things easier to work with?
Re:Things I wished more developers knew about databases by ahane on Thursday April 23, 2020 @07:02AM (#22954649)
I found the jooq blog (not affiliated) excellent for understanding the concepts of SQL properly.

This article is a great starting point:

https://blog.jooq.org/2016/03/17/10-easy-steps-to-a-complete...

there are many other articles worth reading on there

Re:Things I wished more developers knew about databases by polygotdomain on Wednesday April 22, 2020 @02:01PM (#22948365)
You need to spend time working with the language and understanding how the set based operations used in SQL work. Declarative languages means you can express things in multiple ways and get the same results. This is an incredibly important aspect of SQL

>the basic concepts are simple, but the implementation details quickly become very complex

This is no different than programming. Assuming that SQL doesn't have complexity because you can only SELECT, INSERT, UPDATE or DELETE is going to have you banging your head against the wall. Tackle the complexity in SQL like you'd tackle the complexity in your programming language of choice; read the docs, work through examples, and read how other people solve the problem. There's ton out there for SQL

>When do you use WHERE vs HAVING?

HAVINGs allow you to add a condition to an aggregate function. So SUM(myColumn) > 5 would be something you put in a HAVING clause. Honestly, this is pretty clear cut.

>Should you put constraints in the JOIN or in the WHERE? Will the distinction drastically affect performance?

The first thing to understand is a condition in a join versus a where might return a different result set, specifically on anything other than an INNER join. The impact to performance will depend on the rest of your query, your data, and your index coverage. For simple cases, there is likely no difference. For complex ones, there may be an impact

> Is the NULL from the join because no joined row was found, or because the joined row had a NULL value itself?

An inner join shouldn't produce a null. That's why it's an inner join, as the data needs to exist in both places. If you want to "test" whether a join found a row, look at the field you were joining to and see if it's a non-null value. Nulls won't join to Nulls unless you've change some settings in most RDBMS. If you're looking at other fields to determine the presence of a row from a join, make sure you're looking at a non-nullable field.

>When to use JOIN vs a subquery?

A better way to phrase this would be when to just join the table, vs writing a sub query and joining to that. When is a question of the complexity of the query and performance characteristics, and that can't be answered in the abstract. The most important thing is that in a large number of cases you can do both, and knowing how to express things in both ways is powerful.

>And all of the questions I pose above have clear answers

No they don't. Any time you're wondering about how different SQL impacts performance, there's absolutely a huge "it depends" angle on it, because how you've structured the tables, index coverage, and the volume of data, can have a significant impact. This is why DBAs still have jobs, because the database is an incredibly complex system. You seem to be complaining that SQL shouldn't be complex, yet are not willing to accept that it is more complex that you've assumed it to be. It's complex. You don't need to know everything if your just a dev, but don't just assume it's simple.

>while JOIN seems like it ought to be intuitive

I'd check the diagram here -> https://stackoverflow.com/questions/13997365/sql-joins-as-ve... Half those joins aren't needed as you can re-order a right join into a left join. For 95% of development Inner joins and left joins are all you need. The other 5% is an outer join and that's mainly needed in report writing, not app development.

Re:Things I wished more developers knew about databases by Drakar1903 on Wednesday April 22, 2020 @01:45PM (#22948188)
I will be very glad if you actually answer these questions, in a separate comment. I'm driven to write this by nothing but the desire to know.
Re:Things I wished more developers knew about databases by yen223 on Thursday April 23, 2020 @02:16AM (#22953301)
The answer to the performance-related ones is simple. It always depends on the your query, your indexes, and your data. The same query can produce wildly different query plans if you have different data (or even if you have the same data, but the engine decided to sample different rows!)

Best thing you can do is to learn how to read EXPLAIN ANALYZE results.

Re:Things I wished more developers knew about databases by barrkel on Thursday April 23, 2020 @09:13AM (#22955527)
> - When to use JOIN vs a subquery?

Normally, subqueries return a single value whereas joins can result in n rows of output for 1 row being joined on, and you can access all the columns of those n rows. There are ways to make use of more than one value (e.g. (tuple) IN (subquery)) but if you want to SELECT more than one value, you need to join.

Depending on the database, it might be slower to do a correlated subquery than a join though (MySQL especially).

> - When is a subquery actually a correlated subquery? Will this destroy your performance? Or is it a critical feature?

A subquery is a correlated subquery when it references symbols from the outer query. That means it needs to be evaluated once per row, and can't be evaluated once at the start of query execution. It can destroy performance if it needs to be evaluated too often - if it's in your 'where' clause and is evaluated over too many rows, e.g. it's mixed in with a boolean expression that can't be short cut.

> - Should you put constraints in the JOIN or in the WHERE? Will the distinction drastically affect performance?

Conventionally, you should put equi-join constraints (equality expressions with foreign / primary keys in other tables) in the JOIN clause and other constraints in the WHERE clause. For inner joins, it doesn't make a difference where you put the predicate, semantically. There is a semantic difference for outer joins though (left join, right join, full outer join): failure to join results in a tuple worth of null values from one or both sides (left/right vs full), rather than eliminating the row.

Where the semantics aren't different, performance should not be affected. Of course the database engine might be stupid, but a fundamental requirement of a reasonable query planner is in determining (a) join order and (b) which indexes to use for the combination of join predicate and where predicate. No query planner worth its salt won't consider using the where clause along with the ON clause on the JOIN when fetching rows in the joined table.

> - When do you use WHERE vs HAVING?

WHERE is before GROUP BY and filters the rows that enter aggregation (if any), HAVING comes after GROUP BY and filters the aggregated rows. If you use a derived table (a nested query with a table alias), then you can use WHERE instead of HAVING for no semantic difference, but derived tables may execute differently (MySQL will generally materialize them, PostgreSQL will see through them).

> - Is the NULL from the join because no joined row was found, or because the joined row had a NULL value itself?

If the column is nullable, and you used an outer join, you can't tell. Normally you check for the primary key or some other non-nullable column to discover if a join failed (most often used in anti-join, when you want to find all rows that don't have corresponding rows in the join).

Re:Things I wished more developers knew about databases by outworlder on Wednesday April 22, 2020 @02:06PM (#22948419)
I had way less trouble in college with relational algebra, compared with SQL. SQL is by no means intuitive. Projection, which is what you do last, comes first in the select statement. Then there are all the join types.

Relational algebra, which is what SQL is ultimately based on, is much more elegant.

Re:Things I wished more developers knew about databases by alexbanks on Wednesday April 22, 2020 @12:15PM (#22947160)
And with CSS, basically all you do is tell the browser how things look.
Re:Things I wished more developers knew about databases by paulryanrogers on Wednesday April 22, 2020 @01:42PM (#22948147)
Conceptually yes. The devil is in the details: tables, flexbox, grid, div-soup, inconsistent naming, etc.
Re:Things I wished more developers knew about databases by alexbanks on Thursday April 23, 2020 @04:48PM (#22961174)
Sure. Conceptually is fine. But I'm pointing out how ridiculous it is to water down CSS/SQL to "Basically just _____". Nothing is hard by that logic.
Re:Things I wished more developers knew about databases by 411111111111111 on Wednesday April 22, 2020 @12:32PM (#22947366)
SQL can do a lot more though.

Triggers, functions, procedures, access control.....

Re:Things I wished more developers knew about databases by astura on Wednesday April 22, 2020 @01:01PM (#22947685)
Plus indices, views, synonyms, constraints, and the entire concept of data normalization...
Re:Things I wished more developers knew about databases by beckingz on Wednesday April 22, 2020 @02:35PM (#22948733)
Turing complete!
Re:Things I wished more developers knew about databases by izacus on Wednesday April 22, 2020 @01:21PM (#22947928)
This is... one of the best comparisons I've seen and sums up the reason why I dislike SQL as well (although I know how to use it).

Sometimes it really feels like you're trying to give instructions to someone via chat which gets Google translated to chinese, japanese and russian on the way - it's this very lossy communication channel where you need to tweak the language "just so" to get maximum performance. I think it's no wonder that newer DB designes opted for more direct and tailored APIs.

Re:Things I wished more developers knew about databases by jacques_chester on Wednesday April 22, 2020 @01:58PM (#22948336)
Databases are quite transparent about what they do. The impression of "just so"-ness is a property of the observer, not the system.
Re:Things I wished more developers knew about databases by cat199 on Wednesday April 22, 2020 @04:46PM (#22950011)
> it often takes a lot of fiddling to get what you want

and yet, for any nontrivial operations, opting for a few simple K:V stores instead means one basically ends up implementing an unrolled SQL engine processing loop to do the application-specific select statements you would otherwise need.

there's a reason SQLite took over from dbm files ...

Re:Things I wished more developers knew about databases by karmakaze on Wednesday April 22, 2020 @09:08PM (#22951842)
The main difference is that with CSS you can have unintended interactions.

With SQL you get unintended query plans, but it always returns the same rows (if it doesn't time out).

Re:Things I wished more developers knew about databases by mike22 on Thursday April 23, 2020 @05:18PM (#22961561)
I’ve been casually trying to knock into the black box of MySQL’s internals with no success yet. I have queries that do GROUP BYs across multiple unindexed columns in frequently large tables, so it ends up with temp tables on disk and filesort. Can someone point to the source code for processing this kind of GROUP BY situation?
Re:Things I wished more developers knew about databases by Ididntdothis on Wednesday April 22, 2020 @11:26AM (#22946551)
SQL feels to me like bash or regular expressions. You can do amazing things if you do it full time. But if you do it only a few times per month or year you quickly forget all the subtleties and it gets hard to understand even the stuff you wrote half a year ago. I guess in the end things have become so complex that as a dev you can’t be good at everything. I often wish there were dedicated database guys but if you have one usually that person is sysadmin and won’t help much with coding against the database.
Re:Things I wished more developers knew about databases by rurp on Wednesday April 22, 2020 @12:40PM (#22947445)
This echos my experience. I've written some complicated SQL queries, but I do it rarely enough that I always have to re-learn a lot of it.

There have been a number of instances where I have had to look something up seemingly for the first time, found a good Stack Overflow answer, and then chuckled to myself because I had already upvoted that exact answer at some point in the past. SQL queries are a pretty common source of this, along with uncommon git and terminal commands.

Re:Things I wished more developers knew about databases by Ididntdothis on Wednesday April 22, 2020 @12:59PM (#22947657)
Very true about git. I would add C++ to that lis. Done full time it’s super powerful. But later or with less experience you look at the code and think “WTF?” .
Re:Things I wished more developers knew about databases by tcgv on Saturday April 25, 2020 @08:11PM (#22982883)
I tend to disagree, since I find SQL orders of magnitude more intuitive than regular expressions, having no problem picking it up once every couple of months without requiring to fallback on books or cheat sheets for implementing the majority of queries. Sure, every now and then we have to optimize a query or implement a complex data extraction pattern forcing us to study how to do it, but for me this is unusual.

The key aspect of SQL that makes it easy for me is readability. Once you know the basics you can understand what a query is doing just by looking at it. Regular expressions notation on the other hand are really though to read, and indeed I keep always forgetting its syntax.

Re:Things I wished more developers knew about databases by Noumenon72 on Wednesday April 22, 2020 @08:32PM (#22951655)
Common table expressions were all I needed to write <a href="https://modern-sql.com/use-case/literate-sql">literate SQL</a> and make it perfectly readable when I come back. But I was doing it almost full time so I wasn't forgetting much either.
Re:Things I wished more developers knew about databases by corey_moncure on Wednesday April 22, 2020 @11:07AM (#22946339)
I'm an SQL hater in remediation.

In a given week I might work with all of the following: SQL, C#, Python, JS (Kendo, Vue, React), XSL, bash, and more. I'm a quick learner and I pick things up fast, always have, I've got a deadline and I don't have the time or capacity to fully internalize the minutiae of all the technologies I have to work with. In other words I depend on the tools to show me the options at my disposal and construct syntactically correct expressions.

What I really dislike about SQL is common to most systems I dislike, where the tools aren't discoverable to me. In SQL it boils down to the fundamental syntactical requirement to put the SELECT clause before the FROM clause. So I have to build up my statement in this weird spiral pattern where I change something deeper in before I know what I can SELECT in the first place. The ability to give tables shorthand names with MS-SQL, i.e.

`left join [dbo].[sometable] st`

...is very helpful but I gather this isn't common to all dialects. Working with XML in SQL is a nightmare as the tool cannot tell you whether you can do obvious things like pass an sql:variable into nodes() until you actually query the server. (spoiler: you can't.)

I vastly prefer the functional programming approach to working with data e.g. C#'s lambda style linq. The tool shows me all the pieces I have to work with, and all I have to do is piece them together the right way.

Re:Things I wished more developers knew about databases by Viliam1234 on Wednesday April 22, 2020 @03:14PM (#22949110)
Reading SQL is like reading German, where the last word in a long sentence determines the meaning of the entire sentence.

An SQL statement starts with "select ABC.XYZ", but you have no idea what it means, because only one screen later it is written that "ABC" is actually an alias for "T_ACCOUNT_BUSINESS_CREDITS" or something. The logical order would be "from ... where ... select ...".

Imagine a programming language designed like SQL. It would look approximately like this:

  function foo(a) {
    return s;
    b = join(a);
    s = concatenate("[", b, "]");
    by the way, a is list of strings, b is string, s is string;
    also, function "join" is imported from "lists", and "concatenate" is imported from "string" module;
    actually, don't return the result, just tell me how many characters it would have;
  }
Re:Things I wished more developers knew about databases by karmakaze on Wednesday April 22, 2020 @09:17PM (#22951877)
I don't know why people think this. After much thought, it's because they read chronologically which isn't how SQL works. It doesn't 'execute' in the written sequence.

The entire statement is a logical one like a mathematical equation. You wouldn't think that the meaning of (a + b) * (c + d) implies that (a + b) has to be done first. Maybe in some computer languages it may like early C compilers.

Given that: "select ABC.XYZ" is perfectly well formed, it's like a forward reference declaration where ABC is the alias for a table-like thing and XYZ is the alias for the column-like thing. I mostly read my SQL inside-out, starting with uncorrelated subqueries.

Another pet peeve: using the keyword INNER or OUTER is just noise.

Re:Things I wished more developers knew about databases by Izkata on Thursday April 23, 2020 @01:11AM (#22953014)
> Imagine a programming language designed like SQL.

Okay:

  const { ABC, XYZ } = source_table.get(id = 5);
Oh, wait...
Re:Things I wished more developers knew about databases by throwaway_pdp09 on Wednesday April 22, 2020 @02:29PM (#22948667)
> In SQL it boils down to the fundamental syntactical requirement to put the SELECT clause before the FROM clause

No offence but if you are at the level of struggling with the syntax then you should not be using SQL until you have more experience. There have been plenty of well-founded critiques of the crappy syntax of SQL, but it's not ultimately that hard. There are worse things you'll have to cope with such as the implications of 3-valued logic that comes with nulls.

The giving-tables-alias-names feature has been standard probably since the very first standard was released. In some cases such as self-joins, it is necessary.

If I can give you a piece of advice, arrange things using the 'with' clause and learn to break things down as simple as possible at each step. Let the optimiser sort things out for you. If performance is poor, look at the query plan. Also understand you don't have to write everything in one huge statement. Spool intermediate results off to temp tables if that helps (not @tables but #tables - @tables have problems with them).

As for the XML, I guess that may be better handled outside the DB. IMO XML should never be made part of SQL. Good luck.

Re:Things I wished more developers knew about databases by hobs on Thursday April 23, 2020 @11:46AM (#22957235)
I would not throw someone at CTEs who is using SQL Server - just use temp tables for each component you would be CTE-ing, CTE's dont get any benefit from re-use except from a code perspective, whereas composing your sets into temp tables will often get you exactly what you want, individual sets that you can re-use throughout your code.
Re:Things I wished more developers knew about databases by throwaway_pdp09 on Thursday April 23, 2020 @12:03PM (#22957405)
Very good point indeed. I'll add to that, that you can trivially examine temporary tables wheres CTEs don't have that transparency. Thanks!

Edit: I'm going to clarify this. It is a mistake to throw CTEs at a beginner but to be clear, CTEs have very important advantages over the using temp tables to hold intermediate results. It comes down to efficiency.

MSSQL only optimises within a single statement; it does not optimise across statements, so if you have a several queries comprising a single CTE, the optimiser has plenty to get its teeth into and may produce a much more efficient query plan.

Also a query plan of a complex CTE can (depending on what you're doing) end up being a straightforward pipeline where one result feeds into another into another and finally gets spat out at the end. That can be very efficient. If you use temp tables you spool intermediate results (which may be large), re-read, spool into another temp table etc. If you're working with a large data set that can use up a lot of memory, and if it's large enough that it has to spill to disk... oh dear.

So for beginners, yes, as you get more expertise, CTEs are the way to go (depending, of course, on various factors)

(Conversely, temp tables do have a definite cardinality, whereas queries in a CTE are estimates and can be badly out leading to very poor query plans. So temp tables can work to your advantage here).

Re:Things I wished more developers knew about databases by contingencies on Thursday April 23, 2020 @04:21AM (#22953847)
May I propose, for your long expression of frustration, a simple fix. Don't use left join. Instead select x.x,x.y,y.x,y.z from x,y where x.x=y.z and ...;

This is the same operation but without the screwup syntax. The whole notion of left join style syntax is an abomination and - excepting for those who have internalized it to the detriment of normal discourse - represents needless cognitive load.

Re:Things I wished more developers knew about databases by pbowyer on Wednesday April 22, 2020 @11:14AM (#22946410)
I like SQL when I'm not writing reporting queries. GROUP BYs bite me (With MySQL 8 I end up reaching for the ANY_VALUE() function), and I end up with more subqueries than I feel I should need.

When working with time-indexed data I feel I'm forcing the database to do something it doesn't want to. E.g. if I want to answer the query "How many sales are there per day this month?" and I want an entry for every day in the month, even when there were zero sales. Or another query asking "Which days didn't have sales?" and listing the days. I haven't found a way to do this in-database. I end up answering in code based on the data I fetch.

Definitely feel it's me not SQL, but not found the answer.

Re:Things I wished more developers knew about databases by EvanAnderson on Wednesday April 22, 2020 @11:34AM (#22946656)
Your example is a fun one and not too hard to do.

Thinking about the intersection of sets is important for grokking what you're trying to do in that example (and with SQL in general). For me, at least, SQL suddenly made a lot of sense when the idea that I was working with intersections and subsets of sets.

In your example you have (1) a set of all dates in a range, and (2) a set of sales totals for days that had sales. Set 1 could be a "numbers table" or generated with something like "generate_series()" in PostgreSQL. Set 2 is made by summarizing the data in a sales table by date using "GROUP BY" and "SUM".

Then you're just looking at JOIN'ing those sets and COAELSCE'ing the NULL returned from days when there are no sales into 0.

Re:Things I wished more developers knew about databases by pbowyer on Wednesday April 22, 2020 @11:42AM (#22946752)
> Set 1 could be a "numbers table" or generated with something like "generate_series()"

I've done it this way when doing it per-minute or per-hour - i.e. for 60 minutes or 24 hours; fixed, constant ranges. I picked this example because (to me at least) it's more difficult :)

Calendar months have different lengths, so something would have to tell it which month to use (and account for leap years). But say you wanted the last 60, 90 or 120 days? I suppose you could first create a temporary table to be the "numbers table", custom made for the range you want to fetch - is there an alternative?

Re:Things I wished more developers knew about databases by Amezarak on Wednesday April 22, 2020 @11:54AM (#22946905)
I have done this many times. My preferred solution was to create a recursive CTE beginning with the desired start date and ending with the desired end date. I often based these on MIN and MAX subqueries, but obviously you could also pick arbitrary dates.

You can use days, months, weeks, years, or whatever you wanted as the "increment" in the CTE using the DATEADD function. Then (for nulls) you simply LEFT JOIN your CTE with the desired date part (aggregated) of your table. This gives you your first answer, and a simply filter will get you your second answer.

It's also common for people to just create all these date tables beforehand as actual, materialized tables. In my opinion, this is less elegant (what happens in 2101?! Somebody had better remember to add to the table!) but it naturally works just as well and probably saves some perf.

Re:Things I wished more developers knew about databases by EvanAnderson on Wednesday April 22, 2020 @11:50AM (#22946849)
In many databases you would create a function to fill the role of that "numbers table" and, effectively, map that function onto rows. That function can express whatever "richness" you need (i.e. civil calendar month, phase of the moon, etc... >smile<) that might not be easily expressed as a series.
Re:Things I wished more developers knew about databases by will_pseudonym on Wednesday April 22, 2020 @11:53AM (#22946892)
There are date functions in most SQL packages which can create the limiting factors you're looking for, just as in procedural languages. Once you have the list of dates you're interested in, the problem becomes simple.
Re:Things I wished more developers knew about databases by will_pseudonym on Wednesday April 22, 2020 @11:48AM (#22946818)
I learned SQL working in Access. There wasn't anything like generate_series(), and I remember having to do things like above by having a start and end date, cross joined with a table of nonnegative integers I made, and creating a field which added an integer to the start date, subject to being no greater than the end date.
Re:Things I wished more developers knew about databases by JamesSwift on Wednesday April 22, 2020 @11:31AM (#22946618)
The answer is likely that your storage schema is incorrect. You have things stored in OLTP (i.e. app database) but trying to read it as OLAP (i.e. reporting database). Once you reimagine the data in the OLAP style then these kinds of queries are simplistic.

EDIT: specifically for your example, in an OLAP style you would generate a Times table and then foreign key the sales table to it based on the date. Then you can easily query against that Times table as the filter/bucket for your queries.

Re:Things I wished more developers knew about databases by pbowyer on Wednesday April 22, 2020 @11:45AM (#22946784)
Yes, agreed. It was designed for OLTP not OLAP, and I have to get my mindset into that.

For days as my example has, would the Time table be generated for say 1970-2050? Given months are of different lengths and there are leap years, I'm assuming this is needed, rather than storing a single year.

Re:Things I wished more developers knew about databases by JamesSwift on Wednesday April 22, 2020 @12:35PM (#22947393)
Yes, the time table is a pregenerated set of all possible moments in time for whatever resolution you care about. So, for example, if you cared about day resolution it might be

  date_key | year_num | month_num | day_num | quarter_num | week_num | month_name | month_name_short
  ...
  20200101   2020       1           1         1             1          january      jan
  20200102   2020       1           2         1             1          january      jan
  ...
  20200401   2020       4           1         2             14         april        apr
  ...
You would FK on the `date_key` and add as many columns as you need to support querying against the dimension. I also like to add a proper `datetime` representation of the date so I can easily do a date range query.
Re:Things I wished more developers knew about databases by jacques_chester on Wednesday April 22, 2020 @02:02PM (#22948375)
I found Kimball's book to be interesting and helpful.

I think the Kimball approach gets bogged down in temporal evolution (Slowly Changing Dimension type 1? 2? 3? 4? 5?), but that's more about the underlying absence of meaningful bitemporalism than the dimensional schema approach per se.

Re:Things I wished more developers knew about databases by mulmen on Wednesday April 22, 2020 @06:53PM (#22951082)
For anything other than the absolute simplest case you should have two databases. One for OLTP (the application(s)) and one for OLAP (the reporting).

If your reporting queries are hard or complex it's because you did a bad job architecting the reporting tables. Reporting queries should almost always be the simplest form of query if you designed your warehouse properly.

Days with sales is easy with a simple SUM or COUNT and GROUP BY.

Days without sales is easy if you think about this dimensionally.

  SELECT dim_days.day_of_month,
    COUNT(fact_orders.order_id)
  /*
    Select from dim_days first because you want every day.
  */
  FROM dim_days
  /*
    Outer join to the fact table to pull in the data you have and add that to your dates.
  */
  LEFT JOIN fact_orders
    ON dim_days.calendar_day = fact_orders.order_day
  /*
    Filter results by the desired range.
  */
  WHERE dim_days.month = 4
    AND dim_days.year = 2020
  GROUP BY dim_days.day_of_month;
As I continue to say:

"SQL is easy. Data is hard."

Re:Things I wished more developers knew about databases by alexilliamson on Wednesday April 22, 2020 @11:57AM (#22946940)
You can (IMO) pretty succinctly enumerate all the days in a month with a recursive CTE. The example in the following link does it for weekdays, but it's the same idea: https://www.sqlservertutorial.net/sql-server-basics/sql-serv...
Re:Things I wished more developers knew about databases by sk5t on Wednesday April 22, 2020 @11:26AM (#22946553)
A more functional mindset can definitely help here. Think of your "sales per day" model in terms of starting with a sequence of days--startingDay up to startingDay + n--as the input to a function that maps to an aggregate of that day's activity.

Aggregate functions in SQL are IMHO quite awesome once you develop a comfort level to stop worrying about them per se. I wouldn't like to try to get Excel to tell me--or write the code to do manually--something like "show me the standard deviation in units sold by day of week over the last ten summers."

Re:Things I wished more developers knew about databases by pbowyer on Wednesday April 22, 2020 @11:46AM (#22946799)
I find thinking about analytic queries like these as map/filter/reduce easier than thinking in terms of the SQL!
Re:Things I wished more developers knew about databases by taffer on Wednesday April 22, 2020 @12:31PM (#22947358)
SQL and functional programming constructs are actually quite similar:

SELECT -> map

FROM -> stream

JOIN -> flatMap

WHERE -> filter

GROUP BY -> collect

ORDER BY -> sorted

https://blog.jooq.org/2015/08/13/common-sql-clauses-and-thei...

Re:Things I wished more developers knew about databases by karmakaze on Wednesday April 22, 2020 @09:21PM (#22951905)
I don't see how JOIN is like flatMap. It's a subset of a cross-product. It's more like do-notation:

  x <- ..
  y <- ..
  return (x, y)
Re:Things I wished more developers knew about databases by taffer on Thursday April 23, 2020 @04:15AM (#22953825)
> I don't see how JOIN is like flatMap

This is explained in the blog post I linked, including an example.

Re:Things I wished more developers knew about databases by karmakaze on Thursday April 23, 2020 @03:38PM (#22960229)
It's really flatMap/map from the link:

  List<Integer> s1 = Stream.of(1, 2);
  Supplier<Stream<String>> s2 = ()->Stream.of("A", "B");

  s1.flatMap(v1 -> s2.get()
                   .map(v2 -> tuple(v1, v2)))
    .forEach(System.out::println);
That's just a nested loop.
Re:Things I wished more developers knew about databases by EvanAnderson on Wednesday April 22, 2020 @12:05PM (#22947036)
Some of the most fun I've ever had coding has been creating "complex" SQL queries. The syntax is something that can only be overcome with memorization, but it becomes second-nature fairly quickly.

Until I started thinking about SQL as manipulating sets it never "clicked". Once it did, though, a whole world of applications filled with mismatched procedural thinking mapped on to SQL was revealed to me, and my own work became much easier.

Re:Things I wished more developers knew about databases by eropple on Wednesday April 22, 2020 @02:13PM (#22948503)
Despite our industry's habit of treating mathy whiteboard things as indicative of one's "programming talent", real application of type, set, and graph theory are not tested nearly as much as they end up being in practice, and I think that developers' reticence to get deep into SQL is symptomatic of the weaknesses there.
Re:Things I wished more developers knew about databases by resu_nimda on Wednesday April 22, 2020 @01:00PM (#22947676)
The first time I accidentally typed "select 8 from users..." and, instead of an error, it returned a column called "8" with a bunch of rows with the value "8", my mind was blown.
Re:Things I wished more developers knew about databases by randomdata on Thursday April 23, 2020 @01:12AM (#22953016)
> I suspect this was what attracted developers to noSQL databases like Mongo in the first place -- it's more attuned to a programmatic mindset.

I suspect it was mostly because the tree-like structures people were trying to represent are an absolute pain to work with when you have to shove them into two dimensional rows and columns. I doubt SQL itself had much to do with it as ORMs were already all the rage when Mongo emerged. But ORMs only slightly improve on papering over the data structure impedance mismatch. Most of the pain points present with using SQL directly remain in ORMs when it comes to this problem.

With Mongo you can just throw the tree at it and it will happily store it and nicely give it back again. Which eventually leads to its own set of problems due to how it handles said tree internally, but that's why it has fallen out of favour and SQL databases are the new hotness again.

You'll notice the frontrunners in the NoSQL movement of the time weren't relational databases with a different query language. They all took different approaches to dealing with data itself. Sometimes, humorously, they even maintained SQL as the query language. NoSQL didn't come to mean "No SQL" at all, but rather "Not Relational".

As an aside, while it might go a bit outside the spirit of SQL and introduces its own challenges, I remain somewhat amazed that we haven't seen a standard way emerge to query tree-like structures to better reflect the needs of a fairly common use case. You can kind of get there in unconventional ways, like using json_agg in Postgres, but that all seems pretty hacky.

Re:Things I wished more developers knew about databases by yen223 on Thursday April 23, 2020 @02:23AM (#22953338)
I couldn't agree more. I think people underestimate how much complexity got introduced thanks to the object-relational mismatch.

It would be really nice if there were databases that attempted to expose a data interface that is more tree-friendly. That's why I'm keeping an eye out on projects like EdgeDB and DGraph, and even Hasura.

Re:Things I wished more developers knew about databases by bpyne on Wednesday April 22, 2020 @02:42PM (#22948803)
I think you're onto something with the observation about what type of developers take to SQL. We have a spectrum in which people think more like how the processor operates to people who think more in classes of problems and their solutions.

We run into problems when someone with a proclivity to one side meets a problem best solved by thinking on the other side of the spectrum. An example is a young dev in my organization who was given requirements for a new app that required a data store. Not being comfortable with SQL or relational databases, he chose a document store. It wasn't a good fit. Very quickly requirements expanded and caused his code to balloon into a mess of nested loops with lots of if-checks. Performance has progressively decayed as well. A simple multi-table join with filtering would have knocked off 2/3 of the code.

Re:Things I wished more developers knew about databases by kyllo on Wednesday April 22, 2020 @12:31PM (#22947363)
TFA isn't even about SQL the language at all though, it's about the scalability and reliability characteristics of databases, especially in a distributed environment.
Re:Things I wished more developers knew about databases by MaxBarraclough on Wednesday April 22, 2020 @10:43AM (#22946069)
> I suspect this was what attracted developers to noSQL databases like Mongo in the first place -- it's more attuned to a programmatic mindset.

Well, it's more attuned to the dynamically typed mindset, sure. Programmers who understand the value of static type systems should understand the value of relational schemas.

Re:Things I wished more developers knew about databases by andybak on Wednesday April 22, 2020 @11:25AM (#22946538)
I disagree. There's more to relationships that typing. I'm very pro-dynamic languages and still chafe at static typing but the wonder of the relational model fits nicely with my liking for declarative and functional approaches.

(EDIT - and as another data point I dislike SQL's syntax. The semantics are bearable but the syntax just makes my brain melt)

Re:Things I wished more developers knew about databases by MaxBarraclough on Wednesday April 22, 2020 @11:42AM (#22946753)
They're not identical concepts, but both relational schemas and statically typed programming languages provide assurances about basic structure. Mongo, and Python, offer no such assurances, and leave it to the developer to get it right.

Agree that SQL's syntax is rather bad.

Re:Things I wished more developers knew about databases by MaBeuLux88 on Wednesday April 22, 2020 @12:35PM (#22947391)
MongoDB supports Schema Validation since MongoDB 3.2 (Dec. 2015) and JSON Schema since MongoDB 3.6 (Nov. 2017) so MongoDB can enforce types strictly if you want to at the collection level. NoSQL doesn't mean NoSchema or NoTypes. https://docs.mongodb.com/manual/core/schema-validation/#json...
Re:Things I wished more developers knew about databases by MaxBarraclough on Wednesday April 22, 2020 @01:05PM (#22947747)
So they bolted it on eventually then. The relational databases went the other way and bolted-on schemaless data [0] [1]. We can still compare the schema-based and schemaless approaches.

[0] https://www.postgresql.org/docs/10/datatype-json.html

[1] https://docs.microsoft.com/en-us/sql/t-sql/functions/json-qu...

Re:Things I wished more developers knew about databases by andybak on Thursday April 23, 2020 @06:15AM (#22954425)
> both relational schemas and statically typed programming languages provide assurances about basic structure.

Yes I get that but I was trying to make the point that there's more to the relational model than just assurances. It offers a richly entwined semantic structure and an elegant route to reducing duplication and the risk on inconsistency that comes with it. None of this is in tension with dynamic typing.

(Also - dynamic languages aren't just for sloppy thinkers and cowboy coders. There's actual value that is lost in moving to static typing even if you think the trade-off is well worth it)

Re:Things I wished more developers knew about databases by hknd on Wednesday April 22, 2020 @11:02AM (#22946275)
I used to write SQL at Google/FB, and I did and still do struggle with it.

I think it's because I usually touch SQL like once a month and by the time I need it I already forgot everything :shrug:

Re:Things I wished more developers knew about databases by gwbas1c on Wednesday April 22, 2020 @11:17AM (#22946455)
Part of the issue is that a complicated database can handle the same SQL query many different ways based on indexes and other configurations.

This kind of "magic" isn't always clear when programmers are mostly used to working with data structures and procedural code.

The other problem, IMO, is that programming languages are very poor at bridging the difference between the SQL domain and the language domain. We really need plugins for compilers because ORM libraries often are harder to learn than the database itself.

Re:Things I wished more developers knew about databases by takeda on Wednesday April 22, 2020 @12:53PM (#22947594)
> The other problem, IMO, is that programming languages are very poor at bridging the difference between the SQL domain and the language domain. We really need plugins for compilers because ORM libraries often are harder to learn than the database itself.

Actually in past year I discovered that JetBrains IDEs (in my case PyCharm) have nice feature that seems like not everyone is aware. It is due to their integration with DataGrip. If you configure the IDE to connect to your database, it will start looking for SQL in your strings, it will then do code highlighting, autocomplete table names and fields. If you use refactoring it will understand SQL, if you refactor database it will produce migration statements. It appears to solve all the issues that ORM supposed to solve, and you still have full control since SQL didn't need to be abstracted from you.

Edit: this video shows how it works in action (forwarded to a relevant part): https://youtu.be/_FlpiNno088?t=2868

Re:Things I wished more developers knew about databases by treis on Wednesday April 22, 2020 @11:31AM (#22946616)
>This kind of "magic" isn't always clear when programmers are mostly used to working with data structures and procedural code.

My problem is that it is like some sort of black magic to me. If I write a complex query I have no idea if what is spit back to me is actually what I want. The only way is seeding lots of records and then manually checking that each filter and calculation is doing what I want.

In code complex things can be broken down into more simple items. Then I can reason about and test those building blocks into something I understand and am confident that is working as intended.

Re:Things I wished more developers knew about databases by frosted-flakes on Wednesday April 22, 2020 @12:11PM (#22947106)
Yes, SQL's biggest fault is that it's not very composable. Complex queries end up being long and repetitive, and the order of the parts of a query is totally unintuitive (it should go something like: FROM, GROUP BY, SELECT, ORDER BY rather than SELECT, FROM, GROUP BY, ORDER BY, which makes autocompletion hard).
Re:Things I wished more developers knew about databases by takeda on Wednesday April 22, 2020 @12:43PM (#22947498)
QUEL[1] was like that, but thanks to Oracle SQL won.

[1] https://en.wikipedia.org/wiki/QUEL_query_languages

Re:Things I wished more developers knew about databases by setr on Wednesday April 22, 2020 @01:22PM (#22947941)
One thing I never understood is that the SQL language, and its alternatives, share the same theoretical IR -- the relational algebra -- it shouldn't be that difficult to implement for postgres/mysql alternative relational languages like QUEL or Datalog. Or even just a simplified SQL with a sane, consistent syntax.

I know PG has a bunch of procedural-language alternatives, but afaik, no relational-language alternatives.

At the same time, I'd also expect it to not be that difficult to transpile from say mysql to postgres, yet there's very little in that space, at least in open source (there is however many ORMS that map to either mysql or postgres..)

Both of which, amongst the procedural-languages, you'd find a hundred transpilers (JS->C) and VM-languages (Clojure,Scala,etc on jvm) implemented even by bored/curious students. Which makes my suspicion that there's no technical blocker, just a cultural one.

That is, QUEL losing to SQL, such that you can't find any implementation, is an absurd concept -- it should be available on postgres (perhaps requiring some special starting keyword) -- but somehow it is not.

Re:Things I wished more developers knew about databases by mulmen on Wednesday April 22, 2020 @07:15PM (#22951217)
The original query language for Postgres95 was QUEL.

libpq refers to PostQUEL.

Ingres became Post-Ingres which became POSTGRES which became Postgres95 which became PostgreSQL.

https://www.postgresql.org/docs/12/history.html

Re:Things I wished more developers knew about databases by ratww on Wednesday April 22, 2020 @01:14PM (#22947852)
CTEs can help a bit with composition (and readability)
Re:Things I wished more developers knew about databases by goostavos on Wednesday April 22, 2020 @12:06PM (#22947047)
>programming languages are very poor at bridging the difference between the SQL domain and the language domain

Depends a lot on the language. I've lost countless hours to things like JOOQ trying to figure out how to get it to do what I want, or express the query in its quirky not-quite-right DSL, plus dealing with mappings, pojos, auto-generation, and so on.

However, on the other hand, in a dynamic language with just enough support to move the result of your queries into a map of key/value, I feel no friction at all. I'm using little more than a simple jdbc wrapper in Clojure and even after months on the project, I'm still just continuously stoked with seamless the whole thing is.

Re:Things I wished more developers knew about databases by oftenwrong on Wednesday April 22, 2020 @01:58PM (#22948330)
jOOQ can be used in a less-type-safe way. For example, `fetchMaps` [1] does more-or-less what you describe.

However, I have found it worthwhile to learn to use the more advanced features you mention. Extending type safety to queries is incredibly useful. Consider cases when developers are making code and schema changes concurrently that overlap.

[1] https://www.jooq.org/javadoc/latest/org.jooq/org/jooq/Result...

Re:Things I wished more developers knew about databases by Scarbutt on Wednesday April 22, 2020 @04:28PM (#22949826)
SQL (at least in Postgres) is already type safe.
Re:Things I wished more developers knew about databases by oftenwrong on Wednesday April 22, 2020 @06:06PM (#22950711)
jOOQ can effectively extend the type system of Java to the construction of ad-hoc queries by way of code generation. jOOQ generates Java classes that correspond to the database schema, which can be used in its query building DSL.

For example, if I have a `timestamp with time zone` column in PostgreSQL, that is represented in the generated code. I will be prevented from inserting a Java `String` into that column - I will have to provide an `OffsetDateTime`. (This is how it would be in a typical configuration - it is flexible enough to do pretty much anything).

Another example, let's say I reference some column in a query in one of my feature branches. Meanwhile, somebody has dropped that column on the master branch. When I rebase my feature branch onto master, my build will fail.

Re:Things I wished more developers knew about databases by pjscott on Wednesday April 22, 2020 @05:45PM (#22950520)
The thing that really worries me when I'm writing SQL is the possibility that the query planner will get frisky and choose some disastrously slow join order, but only once in a while. I've run into way too many hard-to-reproduce performance issues like this.

Having the database automatically figure out how to run a query is a great feature, but most of the time I'd happily just write explicit nested loops for the sake of predictability.

Re:Things I wished more developers knew about databases by gwbas1c on Sunday April 26, 2020 @10:38PM (#22992381)
(I could be wrong,) but I thought one of the points of stored procedures was that the query plan is precompiled?
Re:Things I wished more developers knew about databases by txcwpalpha on Wednesday April 22, 2020 @11:50AM (#22946855)
When I was in undergrad I was part of program that was heavily programming focused, but was actually part of the business school. Several of the classes I took were heavily SQL focused, with at least one class that had every single assignment requiring extensive designing database schemas and writing SQL. Now, years later, I still think that those classes were some of the most valuable to my career as a programmer.

What's interesting to me is that apparently the CS program at my university hardly did anything with SQL, and I notice too that most programmers I meet "in the wild" are lacking in SQL skills, as you mentioned. It's led to some interesting interview situations where I really struggle with any questions about algorithms (my college courses didn't cover algorithms at all) while the interviewer will tell me that I have the best SQL skills of anyone they interviewed.

Speaking with others that went to other universities, I've heard that it's similar elsewhere for the "business/programming" to include SQL classes but eschew algorithms, while CS programs will ignore SQL but focus heavily on algorithms. It seems to me like both programs could benefit from meeting in the middle a bit.

Re:Things I wished more developers knew about databases by carlps on Wednesday April 22, 2020 @12:32PM (#22947370)
I have a very similar background. My degrees are in Business Computer Systems and we had SQL hammered into us. We learned how to program with Java and .NET, but all from a very high level. It wasn't until a couple years into my career after school that I started learning DS+A fundamentals on my own. It blew my mind. I agree that there should be more of a mid-point available.
Re:Things I wished more developers knew about databases by pjc50 on Wednesday April 22, 2020 @11:20AM (#22946481)
This is partly why I love LINQ: it's a more C# flavoured way of expressing queries. And it works on objects as well as databases.

Most ORMs are bad for queries (pull over all the objects and look at their properties!), but LINQ will actually turn your code into SQL under the hood with some remarkable machinery.

Re:Things I wished more developers knew about databases by fernandotakai on Wednesday April 22, 2020 @12:35PM (#22947397)
>Most ORMs are bad for queries (pull over all the objects and look at their properties!)

i would change that to ORMs CAN be bad for queries. most ORMs are super configurable and can be changed only to pull specific stuff.

i would argue that most ORMs are a plus to productivity because for most of cases, you just need simple querying (select * from, simple updates, simple deletes).

also, if you really need the power of raw sql you an just use that -- and even then, for most advanced ORMs (django's, for example) exposes a LOT of really advanced sql stuff in python, which, for a lot of developers, is a lot more expressive.

Re:Things I wished more developers knew about databases by uhoh-itsmaciek on Wednesday April 22, 2020 @12:07PM (#22947062)
Which ORMs are bad for queries? Most popular ORMs these days expose most of sql in a language-specific DSL (and some allow you to splice in bits of raw sql in a semi-structured way as an escape hatch). Sure, you still need to learn to "think in sql", to use these effectively, but the ORM has not been the problem for a long time in most languages.
Re:Things I wished more developers knew about databases by ratww on Wednesday April 22, 2020 @01:28PM (#22948019)
ActiveRecord, Rails ORM was the poster child of ORMs for a while, and is completely abysmal for non-trivial left joins, non-trivial aggregations and some subqueries.

Of course using raw SQL is possible but might force you into converting other parts of the code into raw SQL. There is Arel, but it's just a more verbose SQL in quasi-AST form.

On the other hand, I never had much problems with LINQ or Hibernate.

Re:Things I wished more developers knew about databases by andybak on Wednesday April 22, 2020 @11:23AM (#22946514)
Not doubting there are bad ORMs but none of the ones I've dived into is quite that bad (SQL Alchemy and Django's ORM).

I sometimes wonder if the debate about ORM is mainly driven by some traumatic horror witnessed at some point in every developer's career. If we judged programming languages by the same metric... Oh... Actually we kind often do that too!

Re:Things I wished more developers knew about databases by fimdomeio on Wednesday April 22, 2020 @10:55AM (#22946183)
I struggle with lack of experience with SQL by always being told that I should always use an ORM or I would regret it in the future when I would change database technology. I'm in the future now and spend a lot of time debbuging the ORM and the sql statements it produces, when I could split that work in half by not using the orm at all. Would also have a lot more experience with sql so there would probably be less bugs in the first place.
Re:Things I wished more developers knew about databases by btilly on Wednesday April 22, 2020 @11:22AM (#22946506)
If you're writing a CRUD application, an ORM saves a lot of headaches.

If you're doing complex reporting queries, an ORM is strictly worse. And yes, I've seen developers, architects, and authors of ORMs that believed otherwise. They are wrong.

As an example, very, very few ORMs can make the distinction between

    SELECT ...
    FROM foo
      LEFT JOIN bar
        ON foo.id = bar.foo_id
          AND bar.category_id = 5
      LEFT JOIN baz
        ON bar.id = baz.bar_id
    ...
and

    SELECT ...
    FROM foo
      LEFT JOIN bar
        ON foo.id = bar.foo_id
      LEFT JOIN baz
        ON bar.id = baz.bar_id
          AND bar.category_id = 5
    ...
(And if you get into things like analytic queries, just forget about it.)
Re:Things I wished more developers knew about databases by jakearmitage on Wednesday April 22, 2020 @11:33AM (#22946647)
Curious, what is the difference here?
Re:Things I wished more developers knew about databases by saltcured on Wednesday April 22, 2020 @01:09PM (#22947792)
The extra "AND expr" in the join clause makes it more strict, which means the outer join can produce more nulls in the joined tuple. In a sequence like A left join B left join C, moving the extra join filter between the two joins is the difference between getting tuples like (a..., null..., null...) vs (a..., b..., null...).
Re:Things I wished more developers knew about databases by gtsteve on Wednesday April 22, 2020 @12:36PM (#22947404)
I believe they may have intended to write this query with INNER JOINs instead of LEFT JOINs.

If so, the result of the query would be identical but the second one would likely have performance problems given the category_id filter is not being applied at the point where bar is joined. A clever database engine might find an optimisation but I wouldn't count on it.

This illustrates the subtle problem that ORMs can introduce - all logical tests pass but issues emerge over time. I found that typically every ORM based problem was resolved by rewriting it using SQL.

I used to use ORMs extensively, but my philosophy now is that you can make simple queries by using a query generator (i.e. connection.GetByID("MyTable", 100)) and complex queries have to be written by hand. I would not choose to use an ORM again.

Re:Things I wished more developers knew about databases by btilly on Wednesday April 22, 2020 @12:42PM (#22947481)
No, left joins were intended here. They mean different things.

With inner joins the semantics are the same. If the performance is different, the database query optimizer is broken.

Re:Things I wished more developers knew about databases by gtsteve on Thursday April 23, 2020 @07:10AM (#22954709)
I see, apologies.

However, I'm reasonably certain we'd see poor performance with that query on MySQL 5.7, but I don't think it's got as good an optimiser as Postgres for example.

Re:Things I wished more developers knew about databases by btilly on Thursday April 23, 2020 @05:06PM (#22961429)
I can't say that MySQL doesn't perform poorly. But if so, then their optimizer is more broken than I though.

Even SQLite figures this one out and does it right.

Re:Things I wished more developers knew about databases by btilly on Wednesday April 22, 2020 @12:41PM (#22947456)
The difference is whether the condition on bar is a filter is on the join from bar or baz.
Re:Things I wished more developers knew about databases by magicalhippo on Friday April 24, 2020 @09:41AM (#22967813)
In the first case, if for a given row bar.category_id <> 5 then there's no match and hence null will be returned for any value from bar. Thus there will be no match in baz either (assuming the id columns are non-null).

In the second case, the first join will always return a row from bar for a given foo_id if it exists, but the second join does not return values from baz for rows where bar.category_id <> 5.

Re:Things I wished more developers knew about databases by sk5t on Wednesday April 22, 2020 @01:43PM (#22948169)
Swapping out database platforms is pretty deep into YAGNI territory for most. Unless you know you are selling an on-prem software product to some customers who will demand MSSQL and others who will demand Oracle, or whatever, this "swap databases" justification for scrupulously using an ORM is not well grounded in reality.
Re:Things I wished more developers knew about databases by oftenwrong on Wednesday April 22, 2020 @07:01PM (#22951141)
Switching out the db under a long-in-the-tooth application is going to painful, no matter what. An ORM will not save you.
Re:Things I wished more developers knew about databases by meddlepal on Wednesday April 22, 2020 @10:59AM (#22946240)
From my experience it's just unfamiliarity with the SQL language. I've spent thousands of hours writing PHP, Java, Scala, Kotlin, Python and Go and doing fairly complex things with them since I started programming.

SQL maybe a few hundred hours? And off and on again rather than constantly so I don't always remember beyond the basics. The concepts make sense to me but the language always feels foreign.

Re:Things I wished more developers knew about databases by bryanrasmussen on Wednesday April 22, 2020 @01:47PM (#22948216)
I'm pretty sure I would be good at SQL if I devoted time to it, because I've worked in other declarative DSLs and generally outperformed other programmers using them, but basically every place I've ever worked at that used SQL extensively had already employed SQL experts that just handled the problems on that level so that it didn't seem worthwhile bothering with it.
Re:Things I wished more developers knew about databases by coliveira on Wednesday April 22, 2020 @12:51PM (#22947576)
In the minds of many developers, SQL is not a "real programming language". That's why they don't see the value of spending the time learning it. Many also believe that SQL is something that they should better avoid, using an ORM, and let it be handled by libraries written by "experts". All of this contributes to developers not having a firm grasp of SQL.
Re:Things I wished more developers knew about databases by mey on Wednesday April 22, 2020 @12:54PM (#22947609)
Yet they are unwittingly willing to learn a different DSL, the ORM's DSL.
Re:Things I wished more developers knew about databases by forgingahead on Wednesday April 22, 2020 @01:12PM (#22947828)
I don't think it's as elaborate as you're saying -- the clearest road into a productive job for many years has been "join a fast growing tech company who uses <cool_framework> to do the magic, so the tech team is always building more business logic". When you've been working with (eg:) ActiveRecord and Ruby on your database data, direct SQL just doesn't come up until you're trying to wrangle more efficiency in your queries or do more complicated joins.

It certainly makes sense for all developers to learn more SQL! But it just hasn't been part of the daily work requirement for many.

As for the attraction of noSQL databases, I think perhaps it's more of a new-hotness trend rather than a serious technical decision. NoSQL has its place, but like most of this kind of tooling, it's often applied incorrectly because of a lack of thinking through the business logic.

Re:Things I wished more developers knew about databases by vnorilo on Wednesday April 22, 2020 @11:06AM (#22946333)
I agree that this is in part why nosql became popular. I'm quite experienced with systems programming but databases were never central to my interests.

So when I needed one for my personal stuff, I went with CouchDB, because it's just a very nice RESTful API around a data structure I understand well.

Re:Things I wished more developers knew about databases by MathCodeLove on Wednesday April 22, 2020 @01:19PM (#22947915)
As a programmer who is admittedly attracted to Mongo, a large part of it is simply its ease of integration. I'd happily spend more time familiarizing myself with SQL if it were less of a pain to integrate into my projects.

The first time ever using Mongo I had a cloud cluster connected and working in about 10 minutes after signing up. Trying to integrate SQLite took me around 1.5 hours before it was functional. To this day I have yet to set up a real cloud SQL database because the one time I tried it with PostreSQL I just couldnt get it to work.

Re:Things I wished more developers knew about databases by izacus on Wednesday April 22, 2020 @01:24PM (#22947969)
Is initial integration cost really the most important metric you look at when designing a system that will probably run for years and will have to be maintained and scaled?
Re:Things I wished more developers knew about databases by fendy3002 on Wednesday April 22, 2020 @08:40PM (#22951708)
However most of the time we'll only deal with simple queries such as select where and join. More complex example is just group by and simple aggregation such as max min count.

People struggling with sql because they usually don't know easier way to query that they resulting to use more complex query. For example `select where id in` and `case when` are both powerful query that many don't know or under utilized.

With `select where in` for example, we can do object mapping / join on application level instead db level.

Re:Things I wished more developers knew about databases by slifin on Wednesday April 22, 2020 @01:07PM (#22947775)
SQL definitely solves a lot of performance issues for typical users who think they can do better

but throwing strings over the wire, trying to get as much as possible without crossing cardinalities and ignoring the n query problem makes SQL at scale disastrous

Devs always get one of these things wrong and not being able to use my programming language in the query makes some things hard to express

Datalog and Datomic are definitely worth learning https://youtu.be/Pz_NvY1kw6I

Re:Things I wished more developers knew about databases by nsomaru on Wednesday April 22, 2020 @01:29PM (#22948031)
could you clarify what throwing strings over the wire and crossing cardinalities means in this context?
Re:Things I wished more developers knew about databases by homami on Wednesday April 22, 2020 @04:25PM (#22949792)
I find SQL INSERT statement not intuitive. I can understand why SQL requires me to declare the field names and then the values of a new row that I am inserting; but it would've been a huge time saver if SQL had a key-value dictionary-like syntax:

    INSERT INTO "my_table"
       "col1": value1,
       "col2": value2,
       ...
Re:Things I wished more developers knew about databases by castorp on Wednesday April 22, 2020 @05:28PM (#22950385)
And when you need to insert more than one row, you repeat the column name over and over again for each row - not a good idea either.
Re:Things I wished more developers knew about databases by rspeele on Thursday April 23, 2020 @01:56PM (#22958783)
Single-row inserts are super common in both application code and in interactive usage of SQL, so I think that it is worth it to have a syntax for them that reduces this common error. Especially when a table has many columns of the same type (like booleans). E.g.

insert into Permissions(UserId, Create, Read, Update, Delete, Share, ForceUnlock, LaunchNukes) values (12345, 1, 1, 0, 1, 0, 0, 1);

When I wrote my (now unmaintained) statically typed SQL dialect for F#, which compiles to underlying SQLite/Postgres/MSSQL, I added a single-row insert with Field=Value because it's nice to have and took no more than 30 minutes to do. It's only a tweak to the parser after all -- you just parse it to the same AST used to represent the `INSERT ... VALUES` clause and all later stages of the compilation do not need to know about it.

https://rspeele.gitbooks.io/rezoom-sql/doc/Language/InsertSt...

Re:Things I wished more developers knew about databases by magicalhippo on Friday April 24, 2020 @09:55AM (#22967952)
The DB we use at work (SQLAnywhere) supports inserting from select, and using auto column name matching, so for a table with columns (name, en1, en2) you could have

    INSERT INTO tbl WITH AUTO NAME
    SELECT 'foo' AS name, 1 AS en1, 0 AS en2;
Not nearly as neat as the direct key=value syntax but...
Re:Things I wished more developers knew about databases by PZ81JUXJE7uJ on Wednesday April 22, 2020 @04:32PM (#22949865)
MySQL supports a insert/set statement:

    INSERT INTO tbl SET a = 1, b = 2;
Re:Things I wished more developers knew about databases by castorp on Wednesday April 22, 2020 @05:28PM (#22950387)
How does that look like with a multi-row insert?
Re:Things I wished more developers knew about databases by pjmlp on Saturday April 25, 2020 @04:24AM (#22976603)
It depends pretty much on the quality of one's degree.

Thankfully we had one semester course on databases, all the respective layers, got to implement B+Tree indexes in C, and a GUI application using Oracle's Forms their 90's Visual Basic variant, but using PL/SQL instead.

Re:Things I wished more developers knew about databases by josephorjoe on Wednesday April 22, 2020 @02:43PM (#22948821)
When I first encountered SQL, my immediate reaction was to start writing my own lightweight ORM (two days later I learned ORMs were a thing that already existed) because I took one look at that syntax and decided it was insane to work with directly.

I definitely don't think in SQL.

That said, I like working w SQL databases -- just please give me a battle tested ORM...

Re:Things I wished more developers knew about databases by markus_zhang on Wednesday April 22, 2020 @09:21PM (#22951902)
Does it mean that my years of job of analyst writing SQL queries might be a valuable treasure if I were to apply for some dev job?
Re:Things I wished more developers knew about databases by echlebek on Wednesday April 22, 2020 @06:01PM (#22950647)
SQL really is a programming language though. It's just not imperative.
Re:Things I wished more developers knew about databases by rspeele on Thursday April 23, 2020 @03:48PM (#22960343)
Developers do not want to deal with data in 2D tables all the time. The expressive power SQL offers for manipulating these 2D tables is pretty good, but it can't compare to the ease of working with data not confined to that shape, which is what devs are used to from "real" languages - whether imperative, pure functional, or whatever.

In my mind the best example of this is grouping.

Just like most languages now have "Map" and "Filter" functions in their standard libraries, many now also have some form of "GroupBy" function for working with lists and objects in memory. Invariably the meaning of this is that it takes:

  1. A list of Xs

  2. A key function from an X to a Y, where Ys can be tested for equality
And spits out:

A list of pairs (Y, Xs), each pair containing:

  1. A key value Y

  2. A list of Xs from the input list matching that key
That list-of-(keys and sublists) can then be fed into whatever .Map(), .Filter(), etc. you want to use next. It is perfectly good for simple aggregates like "give me the total salary we're paying each department", but it's also great for stuff like "give me the 3 highest-paid employees within each department". It just makes sense - map over your groups, sorting each sub-list by salary descending and taking the first 3. Nice clean pure functional stuff.

By contrast in SQL, the first problem is super easy - group by department, select sum(salary). The second problem trips a lot of people up because suddenly you aren't really using GROUP BY anymore, even though the thing you're doing is still a "grouping" task. I think the main way to do it is to use ROW_NUMBER() OVER (PARTITION BY DepartmentId ORDER BY Salary DESC) to get a ranking number for each employee then select only those with ranking <= 3. Why do I think that's worse?

1. If you were to describe to a person what you're trying to accomplish, the first step would be the same for problems 1 and 2 - get the employees for each department. But the queries in SQL are not alike and do not appear to share the same first step.

2. There needed to be dedicated extra language syntax to do this, instead of having one function (not even special syntax) that gives you the essence of grouping - which other functions then aggregate/massage further into whatever you need. This makes it harder to learn and harder to pick the right tool for a given query job.

3. Locality is almost fundamental to programming. I like writing the inner dept.OrderByDescending(e => e.Salary).Take(3) in the real programming language, because I can think locally to "this department's employees" and even down to "this employee's salary". In SQL, you're a mile above the data tying things together with push pins and string by ID, row number, etc. You rarely get to think locally.

4. In the same vein as above, structured data maps better to how I think. When I write data code, the metaphors in my head involve places and containers - drawers, shelves, moving things around. I am organizing the objects into boxes, going into each box, and picking my top 3. I am not marking each object with a number then going over them all as a big set and tossing out the ones with numbers greater than 3.

5. When I get my result from this query, I will probably want to work with it in the nested-list form, even if only to display it with merged cells for the the department (so I don't repeat every department name 3 times). Funny enough, if not using an ORM, I'll end up using my language's GroupBy to massage the flat rows back into this form.

Despite all this I want even less to do with NoSQL. I don't want to chuck blobs of JSON into the DB and end up with duplicate data, orphan data, ill-defined schemas, data that's only efficiently queryable one way, etc. I really do want to store my data in a relational form, and a normalized one where possible. I am happy with my tables. I just would love to query them in a LINQ-like language that is capable of representing and manipulating nested data structures -- and returning them to my application as such.