基于MySql的擴(kuò)展功能生成全局ID
本文利用 MySQL的擴(kuò)展功能 REPLACE INTO 來(lái)生成全局id,REPLACE INTO和INSERT的功能一樣,但是當(dāng)使用REPLACE INTO插入新數(shù)據(jù)行時(shí),如果新插入的行的主鍵或唯一鍵(UNIQUE Key)已有的行重復(fù)時(shí),已有的行會(huì)先被刪除,然后再將新數(shù)據(jù)行插入(REPLACE INTO 是原始操作)。
建立類(lèi)似下面的表:
CREATE TABLE `tickets64` ( `id` bigint(20) unsigned NOT NULL auto_increment, `stub` char(1) NOT NULL default '', PRIMARY KEY (`id`), UNIQUE KEY `stub` (`stub`) ) ENGINE=MyISAM;
當(dāng)需要獲得全局唯一ID時(shí),執(zhí)行下面的SQL語(yǔ)句:
REPLACE INTO `tickets64` (`stub`) VALUES ('a');
SELECT LAST_INSERT_ID();
第一次執(zhí)行這個(gè)語(yǔ)句后,ticket64表將包含以下數(shù)據(jù):
+--------+------+
| id | stub |
+--------+------+
| 1 | a |
+--------+------+
以后再次執(zhí)行前面的語(yǔ)句,stub字段值為'a'的行已經(jīng)存在,所以MySQL會(huì)先刪除這一行,再插入。因此,第二次執(zhí)行后,ticket64表還是只有一行數(shù)據(jù),只是id字段的值為2。這個(gè)表將一直只有一行數(shù)據(jù)。
更棒的方法:
比如,只需要一張ticket表就可以為所有的業(yè)務(wù)表提供各自連續(xù)的ID。下面,來(lái)看一下我們的方法。首先來(lái)看一下表結(jié)構(gòu):
CREATE TABLE `sequence` ( `name` varchar(50) NOT NULL, `id` bigint(20) unsigned NOT NULL DEFAULT '0', PRIMARY KEY (`name`) ) ENGINE=InnoDB;
注意區(qū)別,id字段不是自增的,也不是主鍵。在使用前,我們需要先插入一些初始化數(shù)據(jù):
INSERT INTO `sequence` (`name`) VALUES
('users'), ('photos'), ('albums'), ('comments');
接下來(lái),我們可以通過(guò)執(zhí)行下面的SQL語(yǔ)句來(lái)獲得新的照片ID:
UPDATE `sequence` SET `id` = LAST_INSERT_ID(`id` + 1) WHERE `name` = 'photos'; SELECT LAST_INSERT_ID();
我們執(zhí)行了一個(gè)更新操作,將id字段增加1,并將增加后的值傳遞到LAST_INSERT_ID函數(shù),從而指定了LAST_INSERT_ID的返回值。
實(shí)際上,我們不一定需要預(yù)先指定序列的名字。如果我們現(xiàn)在需要一種新的序列,我們可以直接執(zhí)行下面的SQL語(yǔ)句:
INSERT INTO `sequence` (`name`) VALUES('new_business') ON DUPLICATE KEY UPDATE `id` = LAST_INSERT_ID(`id` + 1);
SELECT LAST_INSERT_ID();
這里,我們采用了INSERT … ON DUPLICATE KEY UPDATE這個(gè)MySQL擴(kuò)展,這個(gè)擴(kuò)展的功能也和INSERT一樣插入一行新的記錄,但是當(dāng)新插入的行的主鍵或唯一鍵(UNIQUE Key)和已有的行重復(fù)時(shí),會(huì)對(duì)已有行進(jìn)行UPDATE操作。
當(dāng)我們第一次執(zhí)行上面的語(yǔ)句時(shí),因?yàn)檫€沒(méi)有name為'new_business'的字段,所以正常的執(zhí)行了插入操作,需要注意的是通過(guò)這種方式獲取的序列起始值為0,而不是1。因?yàn)榈谝淮螆?zhí)行時(shí),沒(méi)有執(zhí)行UPDATE,所以也沒(méi)有為L(zhǎng)AST_INSERT_ID傳遞值,我們也沒(méi)有自增字段,所以SELECT LAST_INSERT_ID()將返回0。不過(guò)這個(gè)應(yīng)該不是什么大問(wèn)題。
UPDATE: 這個(gè)方法更容易解決單點(diǎn)問(wèn)題,也不局限于兩個(gè)服務(wù)器,只要對(duì)不同的服務(wù)器設(shè)置不同的初始值(但必須是連續(xù)的),然后將增量變?yōu)榉?wù)器數(shù)就行了。
以上內(nèi)容是基于MySql的擴(kuò)展功能生成全局ID的相關(guān)資料,希望大家喜歡。
相關(guān)文章
Mysql 如何實(shí)現(xiàn)多張無(wú)關(guān)聯(lián)表查詢數(shù)據(jù)并分頁(yè)
這篇文章主要介紹了Mysql 實(shí)現(xiàn)多張無(wú)關(guān)聯(lián)表查詢數(shù)據(jù)并分頁(yè)的操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-06-06
Mysql如何通過(guò)binlog日志恢復(fù)數(shù)據(jù)詳解
binlog日志用于記錄所有更新了數(shù)據(jù)或者已經(jīng)潛在更新了數(shù)據(jù)的所有語(yǔ)句,下面這篇文章主要給大家介紹了關(guān)于Mysql如何通過(guò)binlog日志恢復(fù)數(shù)據(jù)的相關(guān)資料,文中通過(guò)圖文介紹的非常詳細(xì),需要的朋友可以參考下2022-02-02
詳細(xì)聊一聊mysql的樹(shù)形結(jié)構(gòu)存儲(chǔ)以及查詢
由于mysql是關(guān)系型數(shù)據(jù)庫(kù),因此對(duì)于類(lèi)似組織架構(gòu),子任務(wù)等相關(guān)的樹(shù)形結(jié)構(gòu)的處理不是很友好,下面這篇文章主要給大家介紹了關(guān)于mysql樹(shù)形結(jié)構(gòu)存儲(chǔ)以及查詢的相關(guān)資料,需要的朋友可以參考下2022-04-04
如何解決MySQL安裝遇到Start service紅叉問(wèn)題
在安裝MySQL時(shí),若遇到StartService步驟打紅叉無(wú)法繼續(xù),可通過(guò)計(jì)算機(jī)管理以管理員身份運(yùn)行服務(wù),找到MySQL服務(wù),更改為本地系統(tǒng)賬戶登錄,解決安裝問(wèn)題,此方法為實(shí)際操作經(jīng)驗(yàn),可供參考,確保安裝順利完成2024-10-10

