MySQL自动生成以下号码

时间:2012-09-05 22:06:25

标签: php mysql sql

我的关系表中有4列:

  1. ID
  2. CID - 课程ID
  3. LID - 相关课程唯一ID
  4. course_based_id - 以下说明
  5. 在另一个名为lessonscourses的表中,有许多课程和课程都有唯一的ID。这个表是它们之间的联合表。基本上它会为唯一课程ID分配唯一的课程ID。但是......需要基于课程的课程内容。我的意思是,例如让我们看一下截图

    中的第一行和第二行

    enter image description here

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

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

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

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

2 个答案:

答案 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) ;