Đề xuất của tôi là tạo id
chung cột có auto_increment đầu tiên, để có khóa chính trong bảng. Sau đó, tạo một khóa duy nhất cho cả recipeId
và stepNumber
với nhau để bạn không có bất kỳ kết hợp trùng lặp nào của 2 trường này.
Để có thể thêm nhiều bước cho một công thức, bạn cần đảm bảo rằng không có recipeId
, stepNumber
hoặc instruction
được đặt thành tự động tăng dần. Cột duy nhất được đặt thành auto_increment vẫn là id
.
Vì vậy, lược đồ bảng cho 2 bảng này sẽ trông như thế nào (bỏ qua category
cột)
CREATE TABLE `recipies` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`name` varchar(30) NOT NULL DEFAULT '',
`category` enum('Salad','Dessert','Meat','Pastry') DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
CREATE TABLE `instructions` (
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
`recipeId` int(11) unsigned NOT NULL,
`stepNumber` int(11) NOT NULL DEFAULT '1',
`instruction` text NOT NULL,
PRIMARY KEY (`id`),
UNIQUE KEY `recipeId` (`recipeId`,`stepNumber`),
CONSTRAINT `instructions_ibfk_1` FOREIGN KEY (`recipeId`) REFERENCES `recipies` (`id`) ON DELETE CASCADE ON UPDATE NO ACTION
) ENGINE=InnoDB DEFAULT CHARSET=utf8;
Hãy thêm một bản ghi trong recipies
bảng đầu tiên
INSERT INTO `recipies` (`name`,`category`)
VALUES ('Pumpkin Pie','Pastry');
Sau đó, hãy thêm một hàng
INSERT INTO `instructions` (`recipeId`,`instruction`,`stepNumber`)
SELECT
1,
'You will need plenty of pumpkins!',
IFNULL(MAX(`stepNumber`),0)+1
FROM `instructions`
WHERE `recipeId`=1
- 1 sau
SELECT
và 1 trongWHERE
điều kiện cả hai đều tham chiếu đến hàng cóid=1
trongrecipies
bảng -
IFNULL(MAX(stepNumber),0)+1
sẽ chọn số bước cao nhất cho công thức đó (nếu công thức đó không tồn tại, nó sẽ chọn "0") +1
Đây là SQL fiddle nếu bạn muốn thấy nó hoạt động.
[CHỈNH SỬA]
Tôi chưa bao giờ cần sử dụng một tổ hợp cho khóa chính nhưng dường như sau đây hoạt động trên InnoDB với điều kiện bạn chưa có khóa chính trong bảng.
ALTER TABLE `instructions`
ADD PRIMARY KEY(`recipeId`,`stepNumber`)