国产探花免费观看_亚洲丰满少妇自慰呻吟_97日韩有码在线_资源在线日韩欧美_一区二区精品毛片,辰东完美世界有声小说,欢乐颂第一季,yy玄幻小说排行榜完本

首頁 > 數據庫 > MySQL > 正文

MySQL分表自增ID問題的解決方法

2024-07-24 12:44:39
字體:
來源:轉載
供稿:網友

當我們對MySQL進行分表操作后,將不能依賴MySQL的自動增量來產生唯一ID了,因為數據已經分散到多個表中。  
 應盡量避免使用自增IP來做為主鍵,為數據庫分表操作帶來極大的不便。
 在postgreSQL、oracle、db2數據庫中有一個特殊的特性---sequence。 任何時候數據庫可以根據當前表中的記錄數大小和步長來獲取到該表下一條記錄數。然而,MySQL是沒有這種序列對象的。
 可以通過下面的方法來實現sequence特性產生唯一ID:

 1. 通過MySQL表生成ID
 對于插入也就是insert操作,首先就是獲取唯一的id了,就需要一個表來專門創建id,插入一條記錄,并獲取最后插入的ID。代碼如下: 

CREATE TABLE `ttlsa_com`.`create_id` ( `id` BIGINT( 20 ) NOT NULL AUTO_INCREMENT PRIMARY KEY) ENGINE = MYISAM

 也就是說,當我們需要插入數據的時候,必須由這個表來產生id值,我的php代碼的方法如下:

<?php function get_AI_ID() { $sql = "insert into create_id (id) values('')"; $this->db->query($sql); return $this->db->insertID(); } ?>

這種方法效果很好,但是在高并發情況下,MySQL的AUTO_INCREMENT將導致整個數據庫慢。如果存在自增字段,MySQL會維護一個自增 鎖,innodb會在內存里保存一個計數器來記錄auto_increment值,當插入一個新行數據時,就會用一個表鎖來鎖住這個計數器,直到插入結 束。如果是一行一行的插入是沒有問題的,但是在高并發情況下,那就悲催了,表鎖會引起SQL阻塞,極大的影響性能,還可能會達到 max_connections值。
 innodb_autoinc_lock_mode:可以設定3個值:0、1、2
 0:traditonal (每次都會產生表鎖)
 1:consecutive (默認,可預判行數時使用新方式,不可時使用表鎖,對于simple insert會獲得批量的鎖,保證連續插入)
 2:interleaved (不會鎖表,來一個處理一個,并發最高)
 對于myisam表引擎是traditional,每次都會進行表鎖的。 

2. 通過redis生成ID 

function get_next_autoincrement_waitlock($timeout = 60){ $count = $timeout > 0 ? $timeout : 60; while($r->get("serial:lock")){ $count++; sleep(1); if ($count > 10) return false; } return true;} function get_next_autoincrement($timeout = 60){ // first check if we are locked... if (get_next_autoincrement_waitlock($timeout) == false) return 0; $id = $r->incr("serial"); if ( $id > 1 ) return $id; // if ID == 1, we assume we do not have "serial" key... // first we need to get lock. if ($r->setnx("serial:lock"), 1){ $r->expire("serial:lock", 60 * 5); // get max(id) from database. $id = select_db_query("select max(id) from user_posts"); // or alternatively: // select id from user_posts order by id desc limit 1 // increase it $id++; // update Redis key $r->set("serial", $id); // release the lock $r->del("serial:lock"); return $id; } // can not get lock. return 0;} $r = new Redis();$r->connect("127.0.0.1", "6379"); $id = get_next_autoincrement();if ($id){ $sql = "insert into user_posts(id,user,message)values($id,'$user','$message')" $data = exec_db_query($sql);}
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
主站蜘蛛池模板: 淳安县| 河西区| 合山市| 常宁市| 岑巩县| 延川县| 珲春市| 蒲江县| 扬中市| 浦北县| 开阳县| 青海省| 海伦市| 黑水县| 昌黎县| 烟台市| 昌都县| 阳朔县| 北海市| 巴彦淖尔市| 斗六市| 体育| 怀集县| 庆元县| 白朗县| 清徐县| 大悟县| 额济纳旗| 凤翔县| 宽城| 武定县| 化德县| 湄潭县| 乃东县| 内江市| 佛冈县| 无极县| 文昌市| 左云县| 正阳县| 隆化县|