Skip to content

Instantly share code, notes, and snippets.

@lafiosca
Created October 23, 2019 17:48
Show Gist options
  • Save lafiosca/c83cf42613fc8baa5c7ada45c25007eb to your computer and use it in GitHub Desktop.
Save lafiosca/c83cf42613fc8baa5c7ada45c25007eb to your computer and use it in GitHub Desktop.
MySQL: multiple foreign keys referencing same parent field, where one is or is not part of child table's primary key
CREATE TABLE `parent` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `child` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
`parent1Id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`parent2Id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`, `parent1Id`), -- parent field foreign key is part of child primary key
KEY `parent1Id` (`parent1Id`),
KEY `parent2Id` (`parent2Id`),
CONSTRAINT `child_ibfk_parent1Id` FOREIGN KEY (`parent1Id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `child_ibfk_parent2Id` FOREIGN KEY (`parent2Id`) REFERENCES `parent` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
CREATE TABLE `child2` (
`id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin NOT NULL DEFAULT '',
`parent1Id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
`parent2Id` char(36) CHARACTER SET utf8mb4 COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`), -- parent field foreign key is not part of child primary key
KEY `parent1Id` (`parent1Id`),
KEY `parent2Id` (`parent2Id`),
CONSTRAINT `child2_ibfk_parent1Id` FOREIGN KEY (`parent1Id`) REFERENCES `parent` (`id`) ON DELETE CASCADE ON UPDATE CASCADE,
CONSTRAINT `child2_ibfk_parent2Id` FOREIGN KEY (`parent2Id`) REFERENCES `parent` (`id`) ON DELETE SET NULL ON UPDATE CASCADE
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_unicode_ci;
INSERT INTO parent (id) VALUES ('a');
INSERT INTO parent (id) VALUES ('b');
INSERT INTO child (id, parent1Id, parent2Id) VALUES ('c', 'a', 'b');
UPDATE parent SET id = 'x' WHERE id = 'a'; -- SUCCEEDS
UPDATE parent SET id = 'y' WHERE id = 'b'; -- SUCCEEDS
INSERT INTO child (id, parent1Id, parent2Id) VALUES ('d', 'x', 'x');
UPDATE parent SET id = 'z' WHERE id = 'x'; -- FAILS
INSERT INTO parent (id) VALUES ('w');
INSERT INTO child2 (id, parent1Id, parent2Id) VALUES ('e', 'w', 'w');
UPDATE parent SET id = 'v' WHERE id = 'w'; -- SUCCEEDS
DROP TABLE child;
DROP TABLE child2;
DROP TABLE parent;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment