Как сделать еще один столбец автоинкремента MySQL? - PullRequest
5 голосов
/ 08 сентября 2011

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 при вставке новой записи?

Ответы [ 6 ]

6 голосов
/ 08 сентября 2011

Вы можете сделать это из своего приложения, выполнив другой запрос, который увеличивает order, или вы можете создать триггер, который сделает это за вас.Что бы вы ни делали, ради здравого смысла мира программирования - не используйте зарезервированные слова для имен столбцов, такие как order:)

4 голосов
/ 08 сентября 2011

Почему вы хотите, чтобы 2 поля были автоматически увеличены - в любом случае они будут иметь одинаковые значения, поэтому вы можете просто использовать ID.

Если вы хотите, чтобы ваши счета-фактуры / заказы имели последовательные номера, вы должны хранить эту нумерацию в отдельной таблице и иметь отдельную логику для обновления этих номеров.

3 голосов
/ 08 сентября 2011

На основании вашей исходной таблицы:

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;
1 голос
/ 08 сентября 2011

Я бы посоветовал вам установить только поле order как AUTO_INCREMENT; и вручную вычислите новое значение для поля 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 |
+----+------+-------+
0 голосов
/ 28 сентября 2018

Не думайте, что слишком далеко, просто добавьте last_id к вашей строке заказа, и это все :) Я решил это так, что добавил строку, скажем, "Order_2018_00" + LAST_INSERT_ID ().Так что это поле уникально для каждого добавленного набора:)

0 голосов
/ 08 сентября 2011

Попробуйте добавить вторую таблицу для столбца 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();

Этот подход не требует ни транзакций, ни блокировки.

...