如何在mysql中创建两个自动增量列?

时间:2014-04-02 22:37:52

标签: mysql

CREATE TRIGGER test1 AFTER INSERT ON `course_metadata_31`
 FOR EACH ROW BEGIN
 update `course_metadata_31`set `articleID`=`articleID`+1
 END;

我正在使用这种方法。当我在course_metadata_31中插入新条目时,它也应该增加articleID。因为我想将articleID作为另一个自动增量列。我该怎么办?

6 个答案:

答案 0 :(得分:4)

不知道为什么你需要两列自动递增值,没有意义......但是如果你坚持 - 你可以在UDF或SP中完成它,这样你有多个列自动递增一个值。

示例#1:存储过程(SP)


表格

CREATE TABLE tests (
    test_id INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
    test_num INT(10) NULL,
    test_name VARCHAR(10) NOT NULL
);



存储过程

DELIMITER $$
CREATE PROCEDURE autoInc (name VARCHAR(10))
    BEGIN
        DECLARE getCount INT(10);

        SET getCount = (
            SELECT COUNT(test_num)
            FROM tests) + 1;

        INSERT INTO tests (test_num, test_name)
            VALUES (getCount, name);
    END$$
DELIMITER ;



致电SP

CALL autoInc('one');
CALL autoInc('two');
CALL autoInc('three');



查看表格

SELECT * FROM tests;

+---------+----------+-----------+
| test_id | test_num | test_name |
+---------+----------+-----------+
|       1 |       1  | one       |
|       2 |       2  | two       |
|       3 |       3  | three     |
+---------+----------+-----------+


<小时/>
示例#2:用户自定义功能(UDF)


表格

CREATE TABLE tests (
    test_id INT(10) NOT NULL PRIMARY KEY AUTO_INCREMENT,
    test_num INT(10) NULL,
    test_name VARCHAR(10) NOT NULL
);



用户定义的功能

DELIMITER $$
CREATE FUNCTION autoInc ()
    RETURNS INT(10)
    BEGIN
        DECLARE getCount INT(10);

        SET getCount = (
            SELECT COUNT(test_num)
            FROM tests) + 1;

        RETURN getCount;
    END$$
DELIMITER ;



使用UDF

插入
INSERT INTO tests (test_num, test_name) VALUES (autoInc(), 'one');
INSERT INTO tests (test_num, test_name) VALUES (autoInc(), 'two');
INSERT INTO tests (test_num, test_name) VALUES (autoInc(), 'three');



查看表格

SELECT * FROM tests;

+---------+----------+-----------+
| test_id | test_num | test_name |
+---------+----------+-----------+
|       1 |       1  | one       |
|       2 |       2  | two       |
|       3 |       3  | three     |
+---------+----------+-----------+

这些已经过测试和验证。我个人使用这个功能,它更灵活。

答案 1 :(得分:3)

如果你有两个auto_increment列,它们将是相同的,所以没有必要有两个auto_increment列。

答案 2 :(得分:0)

我的用例是必须使用AI列,一列作为PK,另一列用于重新排列项目的顺序。

我考虑过要使用MySQL触发器来使用第一列的值初始化第二个AI列,以便稍后进行洗牌。但事实证明,MySQL中的插入后触发器不允许更新

我使用Sequelize Hooks

非常轻松地完成了此任务

如果使用Sequelize,则可以使用类似于以下内容的东西:

db.define('songs', { <your_model_definition> }, {
    hooks: {
        afterCreate: async (item, {}) => {
            //id here is the PK which is Auto Increment (AI)
            //order is the second key I want as AI
            await item.update({ order: item.id}); 
            console.log("afterCreate", item);
        }
    }
})

答案 3 :(得分:0)

遇到了同样的问题。我是这样解决的:

DELIMITER //
CREATE TRIGGER `estimate_before_insert` BEFORE INSERT ON `estimate` FOR EACH ROW BEGIN
DECLARE newNum INT DEFAULT 0;
   SET newNum = (SELECT max(num) FROM estimate) + 1;
   IF newNum IS NULL THEN
    SET newNum = 1;
   END IF;
SET NEW.num = newNum;
END//
DELIMITER ;

答案 4 :(得分:-1)

问:我该怎么办?

A:查看您认为需要第二个AUTO_INCREMENT列的原因,仔细考虑您要实现的目标。

提出一个替代设计,不要求你在MySQL表中添加两个AUTO_INCREMENT列。

如果你真的需要第二列用&#34;自动增量&#34;类型行为,一种方法是使用auto_increment列添加第二个虚拟表,并使用BEFORE INSERT触发器插入虚拟表,并检索插入的id值。

这样的事情:

CREATE TABLE course_metadata_31_ai
( i INT UNSIGNED PRIMARY KEY AUTO_INCREMENT
);

DELIMITER $$

CREATE TRIGGER course_metadata_31_bi
BEFORE INSERT ON course_metadata_31
FOR EACH ROW
BEGIN
   DECLARE lii INT;
   IF ( NEW.article_id IS NULL OR NEW.article_id < 1 ) THEN
      -- set article_id to auto_increment from dummy table
      INSERT INTO course_metadata_31_ai (i) VALUES (NULL);
      SELECT LAST_INSERT_ID() INTO lii;
      SET NEW.article_id = lii;
      -- DELETE FROM course_metadata_31_ai WHERE i < lii;
   ELSE
      -- set auto_increment col in dummy table to match a larger article_id
      UPDATE course_metadata_31_ai t
        JOIN ( SELECT MAX(r.i) AS i
                 FROM course_metadata_31_ai r
             ) s
          ON s.i = t.i
         SET t.i = GREATEST(t.i,NEW.article_id);
   END IF;
END;
$$

DELIMITER ;

注意

你不一定要从虚拟表中删除行,你不必在触发器中执行它,但是没有必要保留它们。您可能只需要保留具有最大auto_increment值的行,就像使用ALTER TABLE语句无意中将AUTO_INCREMENT设置为较低时一样。)

触发器主体中的IF ELSE用于模拟auto_increment行为...如果为article_id提供了值,请使用它,如果它大于auto_increment列的当前最大值,则使用它伪表,更新虚拟表中的那一行以获得更大的值(因此需要auto_increment值的下一个插入将获得下一个更高的值)。

答案 5 :(得分:-2)

在phpMyAdmin中将列属性设置为AI,它是表结构上的勾选框。你甚至不需要将细节传递给数据库