我的关系表中有4列:
在另一个名为lessons
和courses
的表中,有许多课程和课程都有唯一的ID。这个表是它们之间的联合表。基本上它会为唯一课程ID分配唯一的课程ID。但是......需要基于课程的课程内容。我的意思是,例如让我们看一下截图
盖子1是课程2的第一课,盖子3是课程2的第二课......依此类推。因此,如果我插入cid 2,盖子128,它当然必须是第三课。
现在,问题是,我想在插入时自动生成这个数字:
$q="INSERT INTO `courses-lessons` (`cid`, `lid`) VALUES (?,?)";
但不知道该怎么做。一些MySQL功能?或查询中的内容?
答案 0 :(得分:4)
如果您使用MyISAM引擎存储此表,则可以相对简单地完成此操作:您只需以这种方式定义字段:
cid INT NOT NULL,
course_based_id INT NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (cid, course_based_id)
然后,任何INSERT
都会根据course_based_id
自动为cid
分配新的(+1)值。这是一个Fiddle来说明这个概念。
您可以在MySQL documentation中找到有关它的更多信息。
不幸的是,InnoDB引擎中没有这样的机制。所以也许你可以逃避以下例程(这是一个伪代码,有一些细微差别):
1) lock table for writing;
2) @x = SELECT MAX(course_based_id) WHERE cid = %cid_to_be_inserted%;
3) INSERT (..., course_based_id) VALUES (..., @x + 1);
4) unlock table;
我建议检查this answer;它适用于PostgreSQL,而不是MySQL,但在一些细节中描述了一种可能的实现方式。
更新:以下是实施该行为的实际查询集的示例:
CREATE TABLE tx
(id INT NOT NULL, cid INT NOT NULL, lid INT NOT NULL,
course_based_id INT NOT NULL,
PRIMARY KEY (id),
UNIQUE KEY (cid, course_based_id)
);
LOCK TABLE tx WRITE, tx AS t READ;
INSERT INTO tx (id, cid, lid, course_based_id)
SELECT 2, 2, 1,
1 + COALESCE(
(SELECT MAX(course_based_id)
FROM tx AS t
WHERE cid = 2),
0);
INSERT INTO tx (id, cid, lid, course_based_id)
SELECT 3, 2, 3,
1 + COALESCE(
(SELECT MAX(course_based_id)
FROM tx AS t WHERE cid = 2),
0);
UNLOCK TABLES;
如您所见,没有直接计算下一个course_based_id
值,但我们在这里得到了序列。
答案 1 :(得分:2)
如果你想要引用完整性(外键)你正在使用InnoDB,那么(好的)MyISAM技巧不起作用。
您可以做的是在插入表格期间生成course_based_id
。
编写一个 - 不那么复杂 - 执行插入的过程,并且不允许其他代码插入到此表中 - 通过此过程进行激活。您还需要一个更新程序(如果您想在此course_based_id中存在空白,则需要一个删除程序)。
所以,而不是:
INSERT INTO courses_lessons
(cid, lid)
VALUES
( ?cid, ?lid ) ;
你将拥有,包含在存储过程中以捕获任何错误(重复等):
INSERT INTO courses_lessons
(cid, lid, course_based_id)
SELECT
?cid, ?lid,
1 + COALESCE( ( SELECT MAX(course_based_id)
FROM courses_lessons
WHERE cid = ?cid
), 0)
FROM
dual ;
对于此表,您实际上不需要id
列。 (cid, lid)
上的主键足以识别行。您还需要在(cid, course_based_id)
上添加唯一键:
ALTER TABLE courses_lessons
ADD CONSTRAINT UQ_cid_course_based_id
UNIQUE cid_course_based_id_UQ
(cid, course_based_id) ;