5 ms·
Things that don’t work well with MySQL’s FOREIGN KEY implementation
- Dachande663 3y agoI am probably in the minority and would get shouted at by a DBA of yore, but I use foreign keys for referential integrity and… that’s it. We use soft deletes for almost all rows, so the whole cascading side is less relevant for us than getting an error in test or even production because a missing relation has been used. Combined with using non-integer primary keys, it’s godsend.
- Svip 3y agoI remember working on a large database without foreign keys for a while. When asked why did not use foreign keys, I was told that they didn't like the opaqueness of CASCADE, which I could understand. I guess I did not give it much thought afterwards, until I later ended up in a shop, where the database did include foreign keys, but only with RESTRICT. It was eye-opening how useful foreign keys were, when they were just integrity checks.
- shlomi-noach 3y agoOP. I agree! RESTRICT is by far the best rule to use, and makes the most sense. Perhaps to balance my post a bit, and for what it's worth, I don't advocate for "don't ever use foreign keys" as a blanket statement. My experience was one where using foreign keys did not make sense. I do wish they were more operationally friendly.
- _a_a_a_ 3y agowhat does 'more operationally friendly' mean? TIA
- shlomi-noach 3y agoLike the issues I mention in my post: modifying the data type of a column that is used by a foreign key; otherwise the fact you can't run Online DDL on a table that participates in foreign key relationship ; that INSTANT does not support (yet?) adding/removing foreign key constraints ; that cascaded writes are not written the the binary logs. These are all things that the casual developer doesn't deal with when designing a schema and writes an app that INSERTs/DELETEs/UPDATEs to tables with foreign keys. But once there's a need for a change; once you wire 3rd party tools onto your database, that's where the operations hit a wall.
- _a_a_a_ 3y agoI didn't realise grep_it and you (shlomi-noach) were the same, apologies
- shlomi-noach 3y agoWe are not the same. My mistake for writing "OP".
- shlomi-noach 3y agoWhoops. I wrote "OP" when I really meant "Post author". I'm a bit rusty with HN notations.
- tomnipotent 3y agoeBay released a blog/paper over two decades ago talking about how they achieved scale in part by removing FK constraints from their database. It was vogue for the next decade when SAN/DAS IOPS were ~1-3k, and FK constraints could lead to more disk writes (like Postgres multixact).
- Phelinofist 3y agoWhat's wrong with non-integer primary keys?
- takethisdownplz 3y agobesides performance for using something that is not often tested by devs working in performance, bad support for locale collating and open you for bugs such as indexing on email but allowing application to store both upper and lower case etc.
- evilspammer 3y agoI would expect they're referring to UUIDs or something
- tomnipotent 3y agoYou can pack fewer of them into a page, which means more disk IO for things like index scans.
- gigatexal 3y agoI was a DBA for 5 years and we outlawed cascading anything be they updates or deletes. So you’re not doing anything wrong.
- ComputerGuru 3y agoThe last time I checked, MySQL still can’t do foreign keys with binary blobs. (I think it works with some very specific limitations but not enough to actually use in the real world.)
- AugustoCAS 3y agoI have the strong feeling I would never do this regardless of the DB engine for performance and storage reasons. I would try to hash the blob into a bigint and use that as the PK/FK. Out of curiosity, is there a scenario you can share in which using a binary blob as a PK/FK would be the best solution?
- ComputerGuru 3y agoI'm not talking huge blobs, just (fixed-size) 8- to 16-byte uuid-like fields. You can obviously marshal 8-byte fields to a bigint but you can't do that with 16-byte fields.
- ksec 3y agoI will take another rare opportunity of anything MySQL ends up being on HN, Considering [1] mySQL v5.x will EOL this year. And MySQL 8.0 with EOL in 2026. Does anyone knows if MySQL 9.0 will come anytime soon? [1] https://endoflife.software/applications/databases/mysql https://endoflife.software/applications/databases/mysql
- throwusawayus 3y agoonly oracle knows. and they don’t share answer yet, on this site or any other only public news so far is extremely brief twitter mention of future switch to separate LTS releases from feature releases big picture, hard to see what would motivate them to major re-invest in current mysql product model! amazon, planetscale, and co all profit off of oracle’s mysql server development efforts. and oracle does not get anything in return assume this why more and more mysql dev efforts go to saas-only product like “mysql heatwave”!
- wswope 3y agoJust to throw additional warnings on the pile, MySQL FKs are not ANSI SQL compliant and can be set up on non-unique columns, which can be a major pain when porting across DBs. https://dev.mysql.com/doc/refman/8.0/en/ansi-diff-foreign-keys.html https://dev.mysql.com/doc/refman/8.0/en/ansi-diff-foreign-ke...
- zerocrates 3y agoWhoa, I've never made a foreign key on a non-unique column, had no idea MySQL would allow that. I guess I've pretty much always done foreign keys pointing to primary keys, so they're definitely unique.
- majora2007 3y agoDid you know you can also have a BLOB as a primary key for a table? I found that in an app I just took over the other day. Was shocked.
- pphysch 3y ago> A FOREIGN KEY constraint that references a non-UNIQUE key is not standard SQL but rather an InnoDB extension. Anyone have any background on why this exists? For what purpose would you want a non-unique FK; what are the semantics of a FK that resolves to multiple different records?
- dragonwriter 3y agoIts a shortcut to support use of a denornalized schema where, in a properly normalized schema, there’d be abother table where the row was unique.
- dllthomas 3y agoAlways use a nornalized schema. The ability to see the future is invaluable in a database.
- gregw2 3y ago
- pjungwir 3y agoIt was interesting to hear this aside about the MySQL roadmap: > MySQL is pushing towards INSTANT DDL When I need MySQL these days I automatically go for MariaDB instead, but I guess they are going to diverge more and more. Does anyone more involved in the MySQL/MariaDB world have any thoughts about how they choose and the future of those two projects?
- lingqingm 3y ago[dead]
- frazerclement 3y agoNice article. Note that there's more than one 'MySQL FOREIGN KEY' implementation. MySQL Ndb Cluster also supports foreign keys with some differences wrt the InnoDB implementation : - NDB, therefore not limited to a single MySQL Server, shard etc - Not limited to references between tables in a single database - Supports NoAction deferred constraint checks - Cascaded changes Binlogged independently as part of RBR (Nice side effect of reducing replica apply time work) ... https://dev.mysql.com/blog-archive/foreign-keys-in-mysql-cluster/ https://dev.mysql.com/blog-archive/foreign-keys-in-mysql-clu... Some of the issues described wrt DDL limitations are shared. Many schemas seem to overuse foreign keys perhaps under the assumption that they are required for or accelerate joins?
- throwusawayus 3y agoinnodb supports cross-schema foreign keys, there’s no limitation to tables in a single database can be terrible in mysql 8 though due to metadata locks now extending across foreign key boundaries. this means alter in one schema can block things in other schema if foreign key across databases speaking of, am surprised that blog post author doesnt discuss the new mysql 8 metadata locking behavior, is new major problem with mysql foreign keys!
- frazerclement 3y agoYou are right about cross schema foreign keys being supported, my mistake.