亚洲av成人无遮挡网站在线观看,少妇性bbb搡bbb爽爽爽,亚洲av日韩精品久久久久久,兔费看少妇性l交大片免费,无码少妇一区二区三区

Chinaunix

標題: Mysql如果不用自增長字段 [打印本頁]

作者: HappyWin    時間: 2010-08-02 22:51
標題: Mysql如果不用自增長字段
各位好,
我現(xiàn)在有個表,想用個ID int作為主鍵,但我不想把ID作為AUTO_INCREMENT類型,因為這樣在數(shù)據(jù)遷移或者增刪的時候,不好控制,但這個表可能同時被多個人修改,這樣在處理插入操作的時候不太好控制,我用PHP來實現(xiàn)。

問題是比如前一個然拿到當前的最大值加一,然后在他插入記錄以前,可能有人也拿到了這個ID并且已經(jīng)插入數(shù)據(jù)了。有什么辦法能避免這個沖突嗎?或者是有比較強大的SQL語句能搞定?

create table test(
  id       int NOT NULL DEFAULT 0,
  name      varchar(32)  NOT NULL DEFAULT '',
  PRIMARY KEY (id)
) ENGINE=MyISAM DEFAULT CHARSET=UTF8;

多謝
作者: kingwkb    時間: 2010-08-02 23:29
guid
作者: kafka0102    時間: 2010-08-03 10:39
回復 1# HappyWin

guid是個方法,如果你不要求主鍵是連續(xù)的話。
如果需要連續(xù)自增id,可以考慮由單獨一個表來存儲,只需要一列自增id,每次insert后通過getLastId得到自增的id值,由數(shù)據(jù)庫保證唯一性。
作者: ruochen    時間: 2010-08-03 14:14
自己用應用程序來維護一個自增字段?
作者: 909413335    時間: 2010-08-03 17:06
樓主的問題,可以用鎖表的辦法來解決。當一個SESSION進行的查詢插入的時候,鎖定表,加寫鎖。這樣其他SESSION不能寫入。
下面開始測試。
1:創(chuàng)建一個存儲過程,實現(xiàn)自增字段。

  1. create procedure sp1()
  2. begin
  3.   declare A int;
  4.   select max(id) into A from test;
  5.   insert into test values(if(A<=>null,0,A)+1,concat('a',if(A<=>null,0,A)));
  6. end ;
復制代碼
2:打開一個連接,先鎖定test 表,再進行call sp1();

mysql> lock table test write;
Query OK, 0 rows affected (0.00 sec)

mysql> call sp1();
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | a0   |
+----+------+
1 row in set (0.00 sec)
這時候不解鎖,看另外一個連接

3:另外一個連接進行插入操作
mysql> call sp1();
由于表被鎖,等待表釋放。。
(如果不鎖表的話,此條記錄的ID=2)

4:在第一個連接里再插入一條
mysql> call sp1();
Query OK, 1 row affected (0.00 sec)

mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | a0   |
|  2 | a1   |
+----+------+
2 rows in set (0.00 sec)
插入成功,ID是2.

5:釋放鎖定。
mysql> unlock tables;
Query OK, 0 rows affected (0.00 sec)

6:釋放鎖的同時,3的操作成功。

mysql> call sp1();
Query OK, 1 row affected (16.17 sec)
等待了16.17秒。
再來查3操作后,寫入的是否是2

mysql> select * from test;
+----+------+
| id | name |
+----+------+
|  1 | a0   |
|  2 | a1   |
|  3 | a2   |
+----+------+
3 rows in set (0.00 sec)

ID=3.

測試成功。
在程序調(diào)用的時候,CALL SP1前加lock table test write;執(zhí)行后加UNLOCK TABLES;
作者: HappyWin    時間: 2010-08-03 20:21
多謝樓上各位的解答,非常詳細,特別是909413335兄弟的回答很具體,受益匪淺,

我現(xiàn)在還是想用sql搞定,調(diào)用存儲過程會不會帶來性能問題啊?
如果分兩步做,先插入再用getLastId,可能拿到的是別人插入的ID,可能在我插入以后,在getLastId以前,后面又有人插入了數(shù)據(jù),會不會我拿到別人的LastId?

多謝了
作者: 909413335    時間: 2010-08-04 09:16
我現(xiàn)在還是想用sql搞定,調(diào)用存儲過程會不會帶來性能問題?

不會有性能問題。
在ID上建一個聚簇索引。




歡迎光臨 Chinaunix (http://www.72891.cn/) Powered by Discuz! X3.2