mysql 獲取全域性唯一值

2021-09-02 15:52:50 字數 4252 閱讀 4957

在涉及資料庫儲存資料的時候,經常會遇到唯一值問題,有的是主鍵帶來的限制,有的則是業務上的需要。

下面介紹幾種唯一值的獲取或者生產方法:

先建乙個測試用的表tbl_user,有三個字段:id、name、age,其中id為主鍵。

drop table if exists `tbl_user`;

create table

`tbl_user` (

`id` int(10),

`name` varchar(20),

`age` int(10),

primary key (`id`)

)default charset=utf8 collate=utf8_unicode_ci;

插入幾條資料

insert into tbl_user values (1000,"小貓",22);

insert into tbl_user values (1001,"小狗",22);

insert into tbl_user values (1002,"小刺蝟",22);

查詢結果:

1.由應用程式根據一定演算法生成唯一值:一般採用」md5(時間戳+隨機數)「或者其他的uuid演算法,基本也比較好實現。如果遇到多機器上分布的程式訪問統一資料庫的表,可以把ip、網絡卡號等資訊考進來就可以解決了(當然可以不是簡單的拼接,你可以根據需要去合適的位數經過一定的演算法去獲取)。

2.先查詢表中最大的值select max(id),再加1後作為新的值。很笨的方法。

select max(id) from tbl_user; 

#查詢到的最大id為 1002,之後插入 1003

insert into tbl_user values (1003,"小熊",22);

此時表中資料為

3.如果是表級別的唯一,即在同乙個表中某個字段唯一,可以把該字段設定為「自增(auto_increment)」的。這樣你不必費心思去生成這個不能重複的唯一值了。但是一般應用程式是需要這個唯一值的,這個時候你就得在查詢一次去獲取剛才資料庫自增生成的id。比如在使用者登入的時候,你要生成乙個登入會話id或者token,這些程式一般是需要得到這個值而不是僅僅存在資料庫中。生成的值,a.可以一般的select條件查詢,根據條件查詢剛才插入的資料。b.直接呼叫select @@identity 就可以得到上一次插入記錄時自動產生的id(注意是在資料庫同乙個連線(會話)中),用在插入後立即select @@identity。

看例子,先將表中的id欄位設定為自增,再插入一條資料(不要插入id值,讓資料庫自增得到值),select @@identity查詢,最後驗證看看。

#1.#將id改為自增(auto_increment)

alter table tbl_user change id id int not null auto_increment;

#或者 先刪除id欄位再新增乙個id欄位

alter table tbl_user auto_increment=1000;

alter table tbl_user drop column id;

alter table tbl_user add id int not null auto_increment primary key first;

#2.插入一條記錄

insert tbl_user set name='小猴',age=23;

#3.查詢剛才的自增id值

select @@identity;

#值是1004

驗證下:select * from tbl_user;得到的當前表記錄為

過剛插入的資料「小猴」id為1004,和select @@identity;結果一樣。

4.使用mysql的 uuid()函式。前面的自增欄位(auto_increment)只能生成」表內」的唯一值,且需要搭配使其為」唯一的主鍵或唯一索引」,它的值是逐步增長的。這裡的uuid產生的是字串型別值,固定長度為:36個字元。uuid生成的是在時間、空間上都獨一無二的值,是「隨機+規則」組合而成。

select uuid(); -- c725d905-388e-11e6-9cab-b8ca3a6f5881

select uuid(); -- cb7d3894-388e-11e6-9cab-b8ca3a6f5881

select replace(uuid(),'-',''); -- eb1347a2388e11e69cabb8ca3a6f5881

可以看到,多次呼叫uuid()函式得到的值不相同,它由五部分組成,並且有連字元(-)隔開,一共36個字元。其中:

前3組值是時間戳換算過來的,解決「時間上唯一」;

第4組值是暫時性保持時間戳的唯一性,重啟mysql才會變動;

第5組是mac值轉過來的,有助於解決「空間上的唯一」,同乙個機器多例項的一般相同。如果mac值獲取不到,則是乙個隨機值。

這些已經可以保證得到的值在時間和空間上的唯一。當然你也可以去掉連字元: select replace(uuid(),'-','')。

在mysql 5.1.*及更高版本有乙個變種的uuid()函式,uuid_short(),可以生成乙個17-64位無符號的整數,注意是生成的乙個整數,而前面uuid()生成的是字串。mysql啟動後第一次執行的值是通過時間戳等初始化這個值,在本次執行中再次呼叫的時候都加1。這個值一般比較大,可以呼叫right(uuid_short(),9)取後面的若干位。或者,你還可以寫成自定義函式,來按需生成這個值。舉個例子:

#1.呼叫uuid_short()函式

select uuid_short(); -- 17246045196806782976

select uuid_short(); -- 17246045196806782977

#執行兩次得到的值遞增的:

23285634974089217

#2.建立乙個自定義函式,按需獲取唯一值:

delimiter //

create function `getuuidtest`(sysid int) returns int(10) deterministic

begin

declare tmpid int;

set tmpid = 0;

select concat(sysid,right(uuid_short(),8)) into tmpid;#sysid和uuid_short()後8位數拼接得到

return tmpid;

end; //

#3.呼叫自定義的函式getuuidtest(int)函式:

select getuuidtest(1);

select getuuidtest(1);

select getuuidtest(2);

select getuuidtest(2);

#得到結果:

#1+uuid_short()後8位(74089233)組成

#1+uuid_short()後8位(74089234)組成

#2+uuid_short()後8位(74089235)組成

#3+uuid_short()後8位(74089236)組成

#uuid_short()值遞增,前面在加乙個id,不同的伺服器idsysid不同。

#4.在例子中呼叫自定義函式getuuidtest(int) 來插入記錄:這時候不需要把id設定為自增了。

insert tbl_user set id=getuuidtest(1),name='小熊貓',age=22;

insert tbl_user set id=getuuidtest(2),name='小鴨子',age=21;

例子中,select * from tbl_user;得到的所有記錄為例子中,select * from tbl_user;得到的所有記錄為

mysql 唯一值 mysql 獲取全域性唯一值

在涉及資料庫儲存資料的時候,經常會遇到唯一值問題,有的是主鍵帶來的限制,有的則是業務上的需要。下面介紹幾種唯一值的獲取或者生產方法 先建乙個測試用的表tbl user,有三個字段 id name age,其中id為主鍵。1 drop table if exists tbl user 2 create...

mysql 獲取唯一值 mysql 獲取全域性唯一值

在涉及資料庫儲存資料的時候,經常會遇到唯一值問題,有的是主鍵帶來的限制,有的則是業務上的需要。下面介紹幾種唯一值的獲取或者生產方法 先建乙個測試用的表tbl user,有三個字段 id name age,其中id為主鍵。1 drop table if exists tbl user 2 create...

唯一值獲取

問題 唯一值無法獲取 using system.collections.generic using esri.arcgis.carto using esri.arcgis.geodatabase using system.collections 官網示例 idatastatistics exampl...