Đề 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
SELECTvà 1 trongWHEREđiều kiện cả hai đều tham chiếu đến hàng cóid=1trongrecipiesbảng -
IFNULL(MAX(stepNumber),0)+1sẽ 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`)