2

我的关系表中有 4 列:

  1. ID
  2. CID - 课程编号
  3. LID - 相关课程唯一 ID
  4. course_based_id - 下面的解释

lessons在另一个名为and的表中有一堆具有唯一 ID 的课程和课程courses。这个表就是它们之间的关联表。基本上,它将唯一的课程 ID 分配给唯一的课程 ID。但是.. 需要基于课程的课程 ID。我的意思是,例如让我们看一下屏幕截图中的第一行和第二行

在此处输入图像描述

盖子 1 是课程 2 的第一课,盖子 3 是课程 2 的第二课......等等。因此,如果我插入 cid 2,盖子 128,它必须是课程 2 的第三课。

现在,问题是,我想在插入时自动生成这个数字:

$q="INSERT INTO `courses-lessons` (`cid`, `lid`) VALUES (?,?)";

但不知道该怎么做。一些MySQL功能?或内部查询?

4

2 回答 2

4

如果您使用 MyISAM 引擎来存储此表,这可以相对容易地完成:您只需以这种方式定义字段:

cid INT NOT NULL,
course_based_id INT NOT NULL AUTO_INCREMENT,
...
PRIMARY KEY (cid, course_based_id)

然后 any将自动为基于INSERT分配一个新的(+1)值。这是一个说明这个概念的小提琴。course_based_idcid

您可以在MySQL 文档中找到有关它的更多信息。

不幸的是,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;

我建议检查这个答案;它适用于 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值,但我们在这里得到了序列。

于 2012-09-05T22:10:30.490 回答
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) ;
于 2012-09-05T22:36:41.570 回答