如何创建另一个 MySQL 自动增量列?

发布于 2024-12-03 12:39:24 字数 323 浏览 2 评论 0原文

MySQL 不支持多个自动增量列。

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

是否有另一种解决方案可以在插入新记录时使 order 列的值自动增加?

MySQL doesn't support multiple auto increment columns.

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

Is there another solution to make the value of column order increase automatically when I insert a new record?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(7

戏蝶舞 2024-12-10 12:39:24

您可以在应用程序内通过发出另一个增加订单的查询来完成此操作,也可以创建一个触发器来为您执行此操作。无论你做什么,为了编程世界的理智 - 不要对列名使用保留字,例如 order :)

You can do it from within your application by issuing another query that increases order or you can create a trigger that does that for you. Whatever you do, for the sake of sanity of programming world - don't use reserved words for column names such as order :)

黑寡妇 2024-12-10 12:39:24

基于您的原始表:

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

这个单个插入查询怎么样:

INSERT INTO `parts` (`name`, `order`) 
SELECT 'name of new part', IFNULL(MAX(`order`), 0) + 1 FROM parts;

如果声明正确,这不是一个安全查询,则可以简单地引入表锁定,如下所示:

LOCK TABLES `parts` AS t1 WRITE, `parts` WRITE;

INSERT INTO `parts` (`name`, `order`) 
SELECT 'name of new part', IFNULL(MAX(`order`), 0) + 1 FROM `parts` AS t1;

UNLOCK TABLES;

Based on your original table:

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=latin1 AUTO_INCREMENT=1 ;

How about this single insert query:

INSERT INTO `parts` (`name`, `order`) 
SELECT 'name of new part', IFNULL(MAX(`order`), 0) + 1 FROM parts;

If the claim is true that this is not a safe query, one can simply introduce table locking as follows:

LOCK TABLES `parts` AS t1 WRITE, `parts` WRITE;

INSERT INTO `parts` (`name`, `order`) 
SELECT 'name of new part', IFNULL(MAX(`order`), 0) + 1 FROM `parts` AS t1;

UNLOCK TABLES;
始终不够爱げ你 2024-12-10 12:39:24

为什么你想要 2 个字段自动递增 - 它们无论如何都会有相同的值,所以你可以只使用 ID。

如果您希望发票/订单具有连续编号,那么您应该将该编号保留在单独的表中,并具有单独的逻辑来更新这些编号。

Why do you want 2 fields to be auto incremented - they will have the same values anyway so you can just use ID.

If you want to have your invoices/orders to have sequential numbers then you should keep that numbering in separate table and haves separate logic to update those numbers.

标点 2024-12-10 12:39:24

我建议您仅将 order 字段设置为 AUTO_INCRMENT;并手动计算 id 字段的新值。这是一个例子 -

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`, `order`)
) ENGINE=myisam DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

-- Add some new rows with manually auto-incremented id:

--    SELECT COALESCE(MAX(id), 0) + 1 INTO @next_id FROM parts;
--    INSERT INTO parts VALUES(@next_id, '', NULL);
--    SELECT COALESCE(MAX(id), 0) + 1 INTO @next_id FROM parts;
--    INSERT INTO parts VALUES(@next_id, '', NULL);

  INSERT INTO parts SELECT COALESCE(MAX(id), 0) + 1, '', NULL FROM parts;
  INSERT INTO parts SELECT COALESCE(MAX(id), 0) + 1, '', NULL FROM parts;

SELECT * FROM parts;
+----+------+-------+
| id | name | order |
+----+------+-------+
|  1 |      |     1 |
|  2 |      |     1 |
+----+------+-------+


-- Add some new rows for specified `id`, the value for `order` field will be set automatically:

INSERT INTO parts VALUES(2, '', NULL);
INSERT INTO parts VALUES(2, '', NULL);

+----+------+-------+
| id | name | order |
+----+------+-------+
|  1 |      |     1 |
|  2 |      |     1 |
|  2 |      |     2 |
|  2 |      |     3 |
+----+------+-------+

I'd suggest you to set only order field as AUTO_INCREMENT; and calculate new value for the id field manually. Here it is an example -

CREATE TABLE IF NOT EXISTS `parts` (
  `id` int(11) NOT NULL,
  `name` varchar(255) NOT NULL,
  `order` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`id`, `order`)
) ENGINE=myisam DEFAULT CHARSET=latin1 AUTO_INCREMENT=1;

-- Add some new rows with manually auto-incremented id:

--    SELECT COALESCE(MAX(id), 0) + 1 INTO @next_id FROM parts;
--    INSERT INTO parts VALUES(@next_id, '', NULL);
--    SELECT COALESCE(MAX(id), 0) + 1 INTO @next_id FROM parts;
--    INSERT INTO parts VALUES(@next_id, '', NULL);

  INSERT INTO parts SELECT COALESCE(MAX(id), 0) + 1, '', NULL FROM parts;
  INSERT INTO parts SELECT COALESCE(MAX(id), 0) + 1, '', NULL FROM parts;

SELECT * FROM parts;
+----+------+-------+
| id | name | order |
+----+------+-------+
|  1 |      |     1 |
|  2 |      |     1 |
+----+------+-------+


-- Add some new rows for specified `id`, the value for `order` field will be set automatically:

INSERT INTO parts VALUES(2, '', NULL);
INSERT INTO parts VALUES(2, '', NULL);

+----+------+-------+
| id | name | order |
+----+------+-------+
|  1 |      |     1 |
|  2 |      |     1 |
|  2 |      |     2 |
|  2 |      |     3 |
+----+------+-------+
放肆 2024-12-10 12:39:24

对于有价值的事情,如果有人再次需要这个,你可以使用这个触发器。
它根据 idorder 增加 +1,并且适用于多个插入值

DELIMITER $
CREATE TRIGGER MyTrigger BEFORE INSERT ON parts
FOR EACH ROW
BEGIN
    IF NEW.`order` < 0 THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    ELSEIF NEW.`order` > 0 THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    ELSEIF NEW.`order` is null THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    END IF;
END $
DELIMITER ;

For what is worth, if anybody need this again you can use this trigger.
It increment order by +1 based on id and it works on multiple insert values

DELIMITER $
CREATE TRIGGER MyTrigger BEFORE INSERT ON parts
FOR EACH ROW
BEGIN
    IF NEW.`order` < 0 THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    ELSEIF NEW.`order` > 0 THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    ELSEIF NEW.`order` is null THEN
        SET NEW.`order` = (select id from parts order by id desc limit 1) +1;
    END IF;
END $
DELIMITER ;
白芷 2024-12-10 12:39:24

考虑为 order 列添加第二个表:

CREATE TABLE IF NOT EXISTS `parts_order` (
  `order` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`order`)
) ENGINE=MyISAM;

用法示例:

-- First we insert a new empty row into `parts_order`
INSERT INTO `parts_order` VALUES (NULL);
-- Next we insert a new row into `parts` with last inserted id from `parts_order`
INSERT INTO `parts` SET `name` = "new name", `order` = LAST_INSERT_ID();

此方法不需要事务,也不需要锁定。

Consider adding a second table for the order column:

CREATE TABLE IF NOT EXISTS `parts_order` (
  `order` int(11) NOT NULL AUTO_INCREMENT,
  PRIMARY KEY (`order`)
) ENGINE=MyISAM;

Example usage:

-- First we insert a new empty row into `parts_order`
INSERT INTO `parts_order` VALUES (NULL);
-- Next we insert a new row into `parts` with last inserted id from `parts_order`
INSERT INTO `parts` SET `name` = "new name", `order` = LAST_INSERT_ID();

This approach does not require transactions nor locking.

久伴你 2024-12-10 12:39:24

不要想得太远_只需将last_id 添加到您的订单字符串中即可:)
我这样解决了这个问题,我添加了一个字符串“Order_2018_00”+ LAST_INSERT_ID()。
所以这个字段对于每个添加的集合都是唯一的:)

Don't think too far _ just add the last_id to your order String and thats it :)
I solved it this way that I added a string let's say "Order_2018_00" + LAST_INSERT_ID().
So this field is unique for each added set :)

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文