Live data from Hacker News

We do not use foreign keys (2016)

github.com

11–20 of 337 posts

Re: We do not use foreign keys (2016)

#11
How about this: if your service gets as big as github, then maybe consider doing odd things to eke out more performance or shard or whatever.

Otherwise: use FK's to maintain stronger data integrity.

As hesk mentions below, in Postgres, you can do all kinds of table ALTERing if needs be.

Re: We do not use foreign keys (2016)

#12

How would a Rails app be impacted by this? How would you create one-to-many, or many-to-many relationships? I'm sorry if this question sounds silly, but I've never heard this line of reasoning before and I'm fascinated by it.

GitHub is a Rails app. [1] Rails does not create foreign keys by default, so most Rails apps are doing exactly this.

I think you may be missing the distinction between the database feature "foreign keys", and the general concept of an entry that refers to another entry. Rails does the latter, but not the former, unless you explicitly do it yourself.

(Maybe Rails has changed dramatically in the last few years, but up until at least Rails 4, this was the case)

1: Obviously it's also way more, but the main codebase is a Rails app, and has been forever. This thread is from 2016, so that was probably even more true then than now.

Re: We do not use foreign keys (2016)

#14
post #2

The main criticism seems to be that the FK relationship makes migrating the referenced table difficult. But why not remove the FK with ALTER TABLE before the migration, migrate, and add the FK back again (which will catch any missing primary keys), preferably inside a transaction?

>preferably inside a transaction? MySQL does not support transactional DDL, unfortunately.

That’s no longer true since MySQL8 https://dev.mysql.com/doc/refman/8.0/en/atomic-ddl.html

Re: We do not use foreign keys (2016)

#15

How would a Rails app be impacted by this? How would you create one-to-many, or many-to-many relationships? I'm sorry if this question sounds silly, but I've never heard this line of reasoning before and I'm fascinated by it.

The relationships are there and you join just the same, but the database doesn't have foreign key constraints.

Re: We do not use foreign keys (2016)

#16
post #2

The main criticism seems to be that the FK relationship makes migrating the referenced table difficult. But why not remove the FK with ALTER TABLE before the migration, migrate, and add the FK back again (which will catch any missing primary keys), preferably inside a transaction?

>preferably inside a transaction? MySQL does not support transactional DDL, unfortunately.

So then don't do it inside a transaction. It still wouldn't be any less safe than their current approach of just not using FKs at all

Re: We do not use foreign keys (2016)

#19

How would a Rails app be impacted by this? How would you create one-to-many, or many-to-many relationships? I'm sorry if this question sounds silly, but I've never heard this line of reasoning before and I'm fascinated by it.

They're not talking about whether or not a field is considered a foreign key to another table, but whether or not to define those keys in the database itself so that it also creates a constraint. Really the post is about having a constraint in the database, not the fact that the fields can be considered foreign keys.

Re: We do not use foreign keys (2016)

#20
post #5

When posts like these come up, I'd like to remind people that context matters when making technical decisions. What works for large companies with huge scale (GitHub, Google, Facebook) may not work for you. As a counter point to the linked issue, I operate a few small applications. Foreign-keys (and constraints in general) are great at ensuring that invalid data doesn't find its way into your database. Yes, they have…

As someone currently fighting a battle with an LoB application written without foreign-key constraints with hundreds of thousands of rows of corrupted data because of bugs in sprocs that assigned the wrong value to the wrong foreign key column because they were similarly named - THIS!

The reply in the GitHub thread we’re talking about makes it clear that they still perform FK validation - it’s just performed in the application code rather than the DBMS.

I note there is another alternative: deferred constraints - or just run a query to check for invalid rows at 3am every morning.

Post reply on HN