2011-09-08 141 views
4

MySQL不支持多個自動增量列。如何創建另一個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增加值當我插入一個新的記錄?

+0

還有一個「rowid」,它代表每個插入的行:選擇部分的rowid,其中id = somenumber – Louis

+0

http://stackoverflow.com/questions/7085275/multiple-auto-increment-in-mysql –

+1

所以,你想兩個字段都是auto_incemented,並在所有行中存儲完全相同的值? –

回答

5

爲什麼你想要2個字段自動增加 - 它們將有相同的值,所以你可以使用ID。

如果您希望讓您的發票/訂單具有連續編號,那麼您應該將該編號保存在單獨的表格中,並有單獨的邏輯來更新這些編號。

+4

他們可能會相互抵消,或者OP可能會在自動增量中「關閉漏洞」。這篇文章是MSSQL,但可能是相關的。 http://stackoverflow.com/questions/349092/can-a-sql-server-table-have-two-identity-columns – StuartLC

+0

如果你自己沒有指定一個,MySQL只會分配一個自動遞增的id。因此,您可以使用它來自動分配一個新的值,如果沒有填入任何值,但仍允許顯式選擇任何現有的值。所以他們不必每個記錄都一樣。 –

0

考慮添加的第二表爲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(); 

此方法不需要交易也不鎖定。

+0

表是MyISAM,爲什麼事務呢? –

+0

如果沒有交易或鎖定,你無法做到這一點。 – sanmai

+0

如果您仔細閱讀,您會發現表格類型是MyISAM。該表類型不支持事務。無論是否「好」,交易**都不會在MyISAM中起作用。 –

5

您可以通過發出另一個查詢來增加order,或者您可以創建一個觸發器來執行此操作。不管你做什麼,爲了編程世界的理智 - 不要使用保留字作爲列名,例如order :)

+13

爲了編程世界的智慧,您必須使用反引號來避免列名,並且永遠不會對保留字有任何問題。 – sanmai

1

我建議你只設置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

如果沒有鎖定或交易,這將無法正常工作。 – sanmai

+0

是的,表格可以鎖定。 ...我編輯了我的答案,現在SELECT和INSERT語句被替換爲一個INSERT ... SELECT語句;在這種情況下,我們可以不鎖定地完成它。 – Devart

+0

INSERT ... SELECT在比賽條件下不安全 – sanmai

3

根據您的原始表:

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; 
+0

如果沒有鎖定或交易,它將無法正常工作。 – sanmai

+1

無法對此查詢產生任何問題; 50個並行查詢,並且不會導致任何重複。是否有源代表說這種查詢會導致問題? – HenrikW

+1

@sanmai爲我的答案添加了表鎖。如果沒有表鎖定,這個單個查詢何時會導致問題,我們仍然想解釋一下。 – HenrikW

相關問題