News for hackers. Stuff that matters.
Re:Do you really need foreign keys? by erik_seaberg on Thursday December 21, 2023 @12:58PM (#38724011)
Whenever anyone talks about “the application,” I immediately ask “what about all the other applications?” I promise you that you will find customer service and accounting and biz dev have also built stuff that uses the database to get their jobs done (probably not with the same ORM or even the same language) unless you have taken draconian measures to prevent them.
Re:Do you really need foreign keys? by dasil003 on Thursday December 21, 2023 @03:28PM (#38726410)
Interesting that this whole thread makes no distinction between read and write access, as those are dramatically different use cases. Read access is by far the more necessary, and is usually solved relative easily by saving snapshots to a data warehouse. This is no panacea as data can still easily be misinterpreted or replicated and used out of context in violation of expected production data lifecycle by the team that owns the source-of-truth, but in many cases it's trivial and minimizes coordination overhead.

Write access on the other hand is a different story. IMO restricting write access of a database to a single application is table stakes for scaling complex applications. Sure there are other approaches such as writing all your logic in the database via constraints and stored procedures and making the DBA a god-like figure, but these approaches have fallen out of favor as they've proven less scalable compared to wrapping a DB with a service that has exclusive write access. The latter arrangement allows many constraints to be enforced in a horizontally scalable and more legible layer, while still leveraging the DB to prevent races with a better menu of tradeoffs.

Of course this requires thoughtful service and interface design by competent technical domain experts, which is easier said than done, but the alternative allows the overall system cohesion to degrade to where no one understands the system well enough to make any changes without risking major incidents. At that point, the agency of system builders and maintainers is replaced by care and feeding of the unknowable system to not upset the status quo, accompanied with increasingly byzantine hacks and workarounds to enable any business changes.

Re:Do you really need foreign keys? by JackFr on Thursday December 21, 2023 @04:10PM (#38727005)
Indeed - I immediately thought of hypothetical system (similar to many systems I’ve worked on) where SELECTS are 100x more common than INSERTS which are 100x more common than DELETES.

The 5x speed up on delete performance is a useless optimization.

Re:Do you really need foreign keys? by pmontra on Thursday December 21, 2023 @04:56PM (#38727597)
The no foreign keys advice tastes of 2005/2010 when the lack of support in some frameworks (Rails included) prompted developers to dismiss them as unnecessary. This piece of advice at least quantifies the terms of the tradeoff.

Regarding the correct "saving snapshots to a data warehouse", if there are one million web apps in the world, how many of them have the scale to noticeably benefit from either doing without foreign keys or from a data warehouse? I've been using many of them like everybody else but they are totally irrelevant to the long tail of apps and developers.

By the way, a good DBA can make miracles for the performances of most databases in that long tail. A few days of work are worth the cost especially if the team pays attention and learn the lesson. The best remark I got about a DB of mine was a "not bad for being only a developer". The DBA version was better.

Re:Do you really need foreign keys? by dasil003 on Thursday December 21, 2023 @06:57PM (#38728910)
> Regarding the correct "saving snapshots to a data warehouse", if there are one million web apps in the world, how many of them have the scale to noticeably benefit from either doing without foreign keys or from a data warehouse?

Yes I agree. This advice was assuming you have scale that necessitates multiple services, at which point you'll want to be able to query against data from multiple sources. I'm with you that the vast majority of teams (finger in the air: less than 20 full-time engineers working on a typical web app) are probably better off with a monolith and single database. At this point a read replica is a low effort way to safely provide access to a wide range of stakeholders.

Re:Do you really need foreign keys? by ttfkam on Thursday December 21, 2023 @05:34PM (#38728059)
If I recall correctly, "no foreign keys" hit its stride back in early PHP days when MySQL didn't support them properly. Rather than cop to the fact that MySQL just implemented them badly, MySQL AB went on a dev PR run telling folks that foreign keys weren't actually useful and just slowed a system down.

Once MySQL implemented them less horribly, the PR push finally started to die down. I will never forgive them for that, and decades later where Oracle controls MySQL (and arguably is doing a better job), I still hold a grudge against MySQL that I have to actively suppress when the contract demands it.

Re:Do you really need foreign keys? by pmontra on Friday December 22, 2023 @02:00AM (#38731685)
Nobody with a Computer Science or especially a Software Engineering degree should have felt for it but I know a number of good developers with a more varied background. Some of them inevitably became team leaders etc. By varied backgrounds I mean Philosophy, Agricultural Sciences, Graphic Design. Some of them know very well how a database work, some admit to never have learned SQL, go figure all the theory and the rationale behind some technologies. Give them some blog posts that make the job done without foreign keys and they won't even know what a foreign key is until it's 2015 and people started to move to PostgreSQL.
Re:Do you really need foreign keys? by ttfkam on Friday December 22, 2023 @01:13PM (#38736847)
My degree is in literature. (I'm that dev who also writes docs, makes presentations, and serves as tech lead.) I still know that foreign key constraints should be the default. I even often have to remind those with CS and CE degrees that DBs aren't just dumb bit buckets and that database schemas are critical business logic.

    Bad programmers worry about the code. Good programmers worry about data structures and their relationships. – Linus Torvalds
Re:Do you really need foreign keys? by mavelikara on Thursday December 21, 2023 @01:29PM (#38724545)
+1. When I started in the industry, it was common for more experienced developers to drill the “data outlives the application that generated it” principle into you. Somewhere in the transition to NoSQL and back we lost this.
Re:Do you really need foreign keys? by Pet_Ant on Thursday December 21, 2023 @02:00PM (#38725091)
The _data_ yes, the _database_ no. The data will get migrated to different solutions at different times. I've lost track of how often I've been porting MySQL to SQL Server, SQL Server to Postgres, Postgres to Mongo, Mongo to cloud etc.

EDIT: fixed capitalization of "PostGres"

Re:Do you really need foreign keys? by winnebago on Thursday December 21, 2023 @02:40PM (#38725677)
This really depends on the size of your data set. If you have a large database (TBs+) it's likely to be very long-lived due the effort/hardware resources a migration requires - especially if you want to improve the schema when migrating.
Re:Do you really need foreign keys? by blowski on Thursday December 21, 2023 @05:37PM (#38728094)
I’ve seen a database migration project outlive application rewrites, multiple changes in CTO, and the company being acquired.
Re:Do you really need foreign keys? by jhardy54 on Thursday December 21, 2023 @02:58PM (#38725969)
Friendly suggestion: the conventional capitalization is either Postgres or PostgreSQL.
Re:Do you really need foreign keys? by da_chicken on Thursday December 21, 2023 @04:29PM (#38727237)
It wasn't the transition to NoSQL. It was the transition to web APIs. Now the application that can access the database has a universal shim in place that deals with the messy business of taking requests and applying them to the data store.

Now there's typically three applications that need DB access:

1. The application it was built for.

2. The read-only reporting and visualization tools.

3. The web API.

Re:Do you really need foreign keys? by SkyPuncher on Thursday December 21, 2023 @03:03PM (#38726048)
Context is key.

If you have an established business or startup, data will outlive the application. However, you need a product that lives long enough for either data or application to matter.

In the startup world, that means making decisions that help you ship now, at the expense of debt/costs down the road.

Re:Do you really need foreign keys? by mavelikara on Thursday December 21, 2023 @06:28PM (#38728617)
IME, Foreign Keys do not slow down development velocity, after you factor out the upfront time investment it takes to understand them, normal forms, and other RDBMS concepts. Other posters in this thread have argued that they take CPU cycles during program execution - which is factual correct.
Re:Do you really need foreign keys? by arrowleaf on Thursday December 21, 2023 @01:11PM (#38724223)
My assumption (with modern applications!) is that nothing but the role directly owning the data will access the data. The development and DBA teams will likely have a role they can assume after performing a carefully-audited breakglass procedure to use in an emergency (rare) or to fulfill audit tasks. At least in my org this is a well-known problem with legacy applications sharing databases. Limit access to the database to a single role, used by a single application, and you absolve so many issues.
Re:Do you really need foreign keys? by chasil on Thursday December 21, 2023 @03:58PM (#38726849)
When your data has outlived several generations of front-end technologies (mine started with Powerbuilder), you will find that ownership of the data does not control the evolution of how it will be used with what replaces past clients.

One particularly interesting Oracle problem is:

  ORA-00060: deadlock detected while waiting for resource 
Tom Kyte's book, Expert One-on-One Oracle, describes the primary culprit:

"Oracle considers deadlocks to be so rare, so unusual, that it creates a trace file on the server each and every time one does occur... The number one cause of deadlocks in the Oracle database, in my experience, is un-indexed foreign keys."

For another perspective, add to this a default setting in every SQLite database:

  $ sqlite3 verynew.db
  SQLite version 3.34.1 2021-01-20 14:10:07
  Enter ".help" for usage hints.
  sqlite> .dump
  PRAGMA foreign_keys=OFF;
  BEGIN TRANSACTION;
  COMMIT;
Foreign keys can cause interesting problems, and SQLite specifically prefers to avoid them.
Re:Do you really need foreign keys? by jbmsf on Thursday December 21, 2023 @03:26PM (#38726394)
100%.
Re:Do you really need foreign keys? by pixl97 on Thursday December 21, 2023 @05:04PM (#38727691)
>Limit access to the database to a single role, used by a single application, and you absolve so many issues.

This kinda sounds like "Get rid of 90% of the usefulness of having a database"

Of course, maybe you mean make the same data the DB has available via API, or make other users of the data read only.

Re:Do you really need foreign keys? by arrowleaf on Thursday December 21, 2023 @06:20PM (#38728514)
Yes, if you have downstream services that need to make use of your data, you would provide an API. That way you can manage the number of connections, how the queries are formed, any sort of encoding/decoding, authorization, caching, etc. Definitely not limited to read-only.
Re:Do you really need foreign keys? by goostavos on Thursday December 21, 2023 @01:02PM (#38724070)
I would argue that if you have completely different contexts / business lines / concerns (customer service, accounting, biz dev) all directly accessing the same database you have far, far larger architectural concerns that FK will ever hope to address.
Re:Do you really need foreign keys? by eddd-ddde on Thursday December 21, 2023 @01:26PM (#38724491)
I strongly believe the opposite. Your business IS your database. How do you handle access to the data without access to the data?

It is inevitable that 2 "organizations" will at some point need access to the same data. You could just have each of them decide how they interact with it. It doesn't matter how they do it because the database itself makes sure invariants are kept true (such as FKs).

What's the alternative?

Re:Do you really need foreign keys? by arrowleaf on Thursday December 21, 2023 @01:30PM (#38724560)
Have a single application clearly owning the data. All access to the data is done through that application. Why would you _want_ multiple applications deciding how to handle data in a common store? What about access authorization to sensitive data?
Re:Do you really need foreign keys? by eddd-ddde on Thursday December 21, 2023 @01:38PM (#38724736)
Because that single application already exists, in my case its postgres.

Pgweb is one of my interfaces, admin dashboard for free, and I am sure the changes I make there are as valid as changes through any other interface.

I can implement a website as a SSR app that talks directly to the db. Maybe tomorrow I decide I need to work on a web scraper that will use python, instead of adding more API endpoints to allow the scraper to talk to the database, I just talk to the database...

The database is that "single appplication", no need to write custom endpoints for every operation when SQL is good enough.

It's all a spectrum of course, today you can even go as far as to use something like pg_graphql and you don't even need to write a REST api yourself.

Edit: I forgot to answer the last section, but postgres can totally handle autorization with RLS for instance, allowing users to only see their own data, or maybe data marked as public, etc.

Re:Do you really need foreign keys? by jrumbut on Thursday December 21, 2023 @02:26PM (#38725486)
> Because that single application already exists, in my case its postgres.

This is exactly what postgres was designed for! Tens of thousands of hours of work over decades to solve the problem of relational database management. That's why we call it an RDBMS!

Which isn't to say you shouldn't make your own API ever. There are a lot of situations where you don't want things to connect directly to postgres.

But you shouldn't be afraid of having multiple systems connect to postgres. It has incredibly mature and robust features to accommodate that use case. It's the expected use case.

Re:Do you really need foreign keys? by DasIch on Thursday December 21, 2023 @02:26PM (#38725482)
If you operate at the scale where you consider the performance implications of foreign keys, you probably are not ok with anyone accessing the database or running just any query against it.

It is not realistic that you can trust everyone who needs to access the data with access to the database as they might easily cause problems with poorly written queries.

Additionally you may want invariants maintained, that the database cannot maintain but an application in front of it can.

Also for historical data or analytical queries postgres is not ideal either, so you probably want to move the data into some OLAP database or datalake.

> I can implement a website as a SSR app that talks directly to the db. Maybe tomorrow I decide I need to work on a web scraper that will use python, instead of adding more API endpoints to allow the scraper to talk to the database, I just talk to the database...

If the website and the scraper are just parts of the same application, it makes sense to do this but if they are genuinely different applications. I would use different databases here.

Re:Do you really need foreign keys? by Akronymus on Thursday December 21, 2023 @03:05PM (#38726082)
> If you operate at the scale where you consider the performance implications of foreign keys, you probably are not ok with anyone accessing the database or running just any query against it.

I used to work on an application where ALL database accesses were via stored procedures. Genuinly the best dev experience, to me, so far.

Re:Do you really need foreign keys? by JackFr on Thursday December 21, 2023 @04:33PM (#38727287)
> I used to work on an application where ALL database accesses were via stored procedures. Genuinly the best dev experience, to me, so far.

I found such an environment to be simply terrible.

In general, I think stored procs certainly have their place, but if ALL access is through stored procs, you better have a schema that’s basically set in stone otherwise dev will turn into a nightmare.

Re:Do you really need foreign keys? by butlerm on Thursday December 21, 2023 @02:40PM (#38725686)
Large ERP systems do that sort of thing as a matter of course and have for decades now. It does require careful planning and design. I mean AR / AP / scheduling / manufacturing / inventory and so on.

The main downside of splitting everything into isolated databases is that it makes it approximately impossible to generate reports that require joining across databases. Not without writing new and relatively complex application code to do what used to require a simple SQL query to accomplish anyway.

Of course if you have the sort of business with scalability problems that require abandoning or restructuring your database on a regular basis, then placing that kind of data in a shared database is probably not such a great idea.

It should also be said that common web APIs as a programming technique are much harder to use and implement reliably due to the data marshalling and extra error handling code required than just about any system of queries or stored procedures against a conventional database. The need to page is perverse, for example.

That does not mean that sort of tight coupling is appropriate in many cases, but it is (typically) much easier to implement. Web APIs could use standard support for two phase commit and internally paged queries that preserve some semblance of consistency. The problem is that stateless architecture makes that sort of thing virtually impossible. Who knows which rows will disappear when you query for page two because the positions of all of your records have just shifted? Or which parts of a distributed transaction will still be there if anything goes wrong?

Re:Do you really need foreign keys? by winnebago on Thursday December 21, 2023 @03:09PM (#38726129)
Different business units often want aggregate, filter, join and transform data in different ways - sometimes in ways that are hard to anticipate.

In general, the closer to the persistence layer you can perform those transformations, the better they will scale. If you pull the transform into the app layer, you need to move and serialize more data. If you pull the transformation into a constellation of apps, you need to move and serialize a constellation of data.

(edit: formatting)

Re:Do you really need foreign keys? by Pet_Ant on Thursday December 21, 2023 @01:58PM (#38725068)
> probably not with the same ORM or even the same language

I mean, they shouldn't? Like you've just identified a bug: another application can access your database. If another department needs your data, they should request an endpoint that you control. You should be using an "application database"[1] not an "integration database"[2].

[1] https://martinfowler.com/bliki/ApplicationDatabase.html [2] https://martinfowler.com/bliki/IntegrationDatabase.html

Re:Do you really need foreign keys? by epicfeedback on Thursday December 21, 2023 @02:12PM (#38725254)
They are you. You is they. It’s one company with one goal — keep companying.

The idea that ever “department” should access every other department’s data through some bespoke interface that the latter department maintains might work at some corporate behemoth, but at almost all other scales is absurd.

Re:Do you really need foreign keys? by ch4s3 on Thursday December 21, 2023 @02:38PM (#38725650)
This would be a total waste of effort when you need to be building a product and iterating. I hate articles like this because they do a poor job contextualizing the tradeoffs and when it might be appropriate to do the weird exceptional thing.

IMHO if you have a performance critical case when foreign keys are in the way, load THAT data into an in memory DB on a recurring basis and server time sensitive requests from there.

Re:Do you really need foreign keys? by GoblinSlayer on Friday December 22, 2023 @05:24AM (#38732844)
Foreign keys are slow on delete, not on read. If you have a popular table, say, users, and all other tables refer to it, then deleting a user locks the database for time proportional to the number of foreign keys - good old linear scaling.
Re:Do you really need foreign keys? by bhaak on Friday December 22, 2023 @06:59AM (#38733330)
It doesn't lock the database, it only locks the rows of the tables that have foreign keys to the popular tables and are referencing the user you are deleting.

Rightly so because when deleting the user the database needs to do work to keep the referential integrity. Either it nulls the user_id, delete the rows, or it throws an error.

Re:Do you really need foreign keys? by ch4s3 on Friday December 22, 2023 @11:23PM (#38741613)
Sorry I should have specified read/write and side that you can read from something in memory that is consistent after some short delay.
Re:Do you really need foreign keys? by bborud on Friday December 22, 2023 @06:52AM (#38733292)
If people use the database as an integration layer, IMNSHO, they deserve what they get. Database is implementation - not integration interface.