mysql 獲取全局惟一值

<p align="left">在涉及數據庫存儲數據的時候,常常會遇到惟一值問題,有的是主鍵帶來的限制,有的則是業務上的須要。</p> <p align="left">下面介紹幾種惟一值的獲取或者生產方法:</p> <div align="left">先建一個測試用的表tbl_user,有三個字段:Id、Name、Age,其中Id爲主鍵。</div> <div class="csharpcode"> <pre><span class="lnum"> 1: </span><span class="kwrd">drop</span> <span class="kwrd">table</span> <span class="kwrd">if</span> <span class="kwrd">exists</span> `tbl_user`;</pre>html

<pre><span class="lnum"> 2: </span><span class="kwrd">create</span> <span class="kwrd">table</span> </pre>mysql

<pre><span class="lnum"> 3: </span>`tbl_user` (</pre>算法

<pre><span class="lnum"> 4: </span> `Id` <span class="kwrd">int</span>(10),</pre>sql

<pre><span class="lnum"> 5: </span> `Name` <span class="kwrd">varchar</span>(20),</pre>數據庫

<pre><span class="lnum"> 6: </span> `Age` <span class="kwrd">int</span>(10),</pre>服務器

<pre><span class="lnum"> 7: </span> <span class="kwrd">PRIMARY</span> <span class="kwrd">KEY</span> (`Id`)</pre>app

<pre><span class="lnum"> 8: </span>)<span class="kwrd">DEFAULT</span> CHARSET=utf8 <span class="kwrd">COLLATE</span>=utf8_unicode_ci;</pre>函數

<pre>&#160;</pre>測試

</div>ui

<p>插入幾條數據</p>

<div class="csharpcode"> <pre><span class="lnum"> 1: </span>insert <span class="kwrd">into</span> tbl_user <span class="kwrd">values</span> (1000,&quot;小貓&quot;,22);</pre>

<pre><span class="lnum"> 2: </span>insert <span class="kwrd">into</span> tbl_user <span class="kwrd">values</span> (1001,&quot;小狗&quot;,22);</pre>

<pre><span class="lnum"> 3: </span>insert <span class="kwrd">into</span> tbl_user <span class="kwrd">values</span> (1002,&quot;小刺蝟&quot;,22);</pre>

<pre><span class="lnum"> 4: </span>&#160;</pre>

<pre><span class="lnum"> 5: </span><span class="kwrd">select</span> * <span class="kwrd">from</span> tbl_user;</pre>

<pre>  查詢結果:</pre>

<pre><a href="http://images.cnitblog.com/blog/313639/201312/24191613-3c357956539f4e01bf32db1cd711fae2.png">  <img style="background-image: none; border-right-width: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnitblog.com/blog/313639/201312/24191613-bb4c16c7c5e64ed6948ffe585fcf4c0c.png" width="212" height="113" /></a></pre>

<pre>&#160;</pre>

</div> <style>

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } --></style>

<div align="left"> <div id="codeSnippetWrapper"> <div>1.由<span style="color: #ff00ff">應用程序根據必定算法生成惟一值</span>:通常採用」<span style="color: #ff00ff">MD5(時間戳+隨機數)</span>「或者其餘的UUID算法,基本也比較好實現。若是遇到多機器上分佈的程序訪問統一數據庫的表,能夠把Ip、網卡號等信息考進來就能夠解決了(固然能夠不是簡單的拼接,你能夠根據須要去合適的位數通過必定的算法去獲取)。</div>

<div>&#160;</div>

</div> </div>

<p align="left">2.先查詢表中最大的值select max(id),再加1後做爲新的值。很笨的方法。</p>

<div class="csharpcode"> <pre><span class="lnum"> 1: </span><span class="kwrd">select</span> <span class="kwrd">max</span>(Id) <span class="kwrd">from</span> tbl_user;</pre>

<pre><span class="lnum"> 2: </span>查詢到的最大Id爲 1002</pre>

<pre><span class="lnum"> 3: </span>&#160;</pre>

<pre><span class="lnum"> 4: </span>以後插入 1003</pre>

<pre><span class="lnum"> 5: </span>&#160;</pre>

<pre><span class="lnum"> 6: </span>insert <span class="kwrd">into</span> tbl_user <span class="kwrd">values</span> (1003,&quot;小熊&quot;,22);</pre>

<pre><span class="lnum"> 7: </span>&#160;</pre>

</div> <style>

<!-- .csharpcode, .csharpcode pre { font-size: small; color: black; font-family: consolas, "Courier New", courier, monospace; background-color: #ffffff; /*white-space: pre;*/ } .csharpcode pre { margin: 0em; } .csharpcode .rem { color: #008000; } .csharpcode .kwrd { color: #0000ff; } .csharpcode .str { color: #006080; } .csharpcode .op { color: #0000c0; } .csharpcode .preproc { color: #cc6633; } .csharpcode .asp { background-color: #ffff00; } .csharpcode .html { color: #800000; } .csharpcode .attr { color: #ff0000; } .csharpcode .alt { background-color: #f4f4f4; width: 100%; margin: 0em; } .csharpcode .lnum { color: #606060; } --></style>

<p align="left">此時表中數據爲</p>

<p align="left"><a href="http://images.cnitblog.com/blog/313639/201312/24191614-098ab587823c454f93a1205e7687ffc6.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnitblog.com/blog/313639/201312/24191614-f85e6a501a8944968c179873dcd58f8a.png" width="220" height="131" /></a></p>

<p align="left">3.若是是表級別的惟一,即在同一個表中某個字段惟一,能夠把該字段設置爲「<span style="color: #ff00ff">自增(AUTO_INCREMENT)</span>」的。這樣你沒必要費心思去生成這個不能重複的惟一值了。可是通常應用程序是須要這個惟一值的,這個時候你就得在查詢一次去獲取剛纔數據庫自增生成的Id。好比在用戶登陸的時候,你要生成一個登陸會話Id或者Token,這些程序通常是須要獲得這個值而不是僅僅存在數據庫中。生成的值,1.能夠<span style="color: #ff00ff">通常的select條件查詢</span>,根據條件查詢剛纔插入的數據。2.直接調用<span style="color: #ff00ff">select @@IDENTITY</span> 就能夠獲得上一次插入記錄時自動產生的ID(注意是在數據庫同一個鏈接(會話)中),用在插入後立<span style="color: #000000">即</span><span style="color: #333333">select @@IDENTITY</span> 。</p>

<p align="left">看例子,先將表中的Id字段設置爲自增,再插入一條數據(不要插入Id值,讓數據庫自增獲得值),select @@IDENTITY查詢,最後驗證看看。</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code"> <pre><span style="color: #800000; font-weight: bold">1</span><span style="color: #000000">.#將Id改成自增(auto_increment) </span><span style="color: #0000ff">ALTER</span> <span style="color: #0000ff">TABLE</span> tbl_user CHANGE Id Id <span style="color: #0000ff">int</span> <span style="color: #808080">not</span> <span style="color: #0000ff">null</span><span style="color: #000000"> auto_increment;

#或者 先刪除Id字段再添加一個Id字段 </span><span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> tbl_user auto_increment<span style="color: #808080">=</span><span style="color: #800000; font-weight: bold">1000</span><span style="color: #000000">; </span><span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> tbl_user <span style="color: #0000ff">drop</span> <span style="color: #0000ff">column</span><span style="color: #000000"> Id; </span><span style="color: #0000ff">alter</span> <span style="color: #0000ff">table</span> tbl_user <span style="color: #0000ff">add</span> Id <span style="color: #0000ff">int</span> <span style="color: #808080">not</span> <span style="color: #0000ff">null</span> auto_increment <span style="color: #0000ff">primary</span> <span style="color: #0000ff">key</span><span style="color: #000000"> first;

</span><span style="color: #800000; font-weight: bold">2</span><span style="color: #000000">.插入一條記錄 </span><span style="color: #0000ff">insert</span> tbl_user <span style="color: #0000ff">set</span> Name<span style="color: #808080">=</span><span style="color: #ff0000">'</span><span style="color: #ff0000">小猴</span><span style="color: #ff0000">'</span>,Age<span style="color: #808080">=</span><span style="color: #800000; font-weight: bold">23</span><span style="color: #000000">;

</span><span style="color: #800000; font-weight: bold">3</span><span style="color: #000000">.查詢剛纔的自增Id值 </span><span style="color: #0000ff">select</span> <span style="color: #008000; font-weight: bold">@@IDENTITY</span><span style="color: #000000">; 值是1004,</span></pre>

</div>

<p> <br />驗證下:select * from tbl_user;獲得的當前表記錄爲</p>

<p><a href="http://images.cnitblog.com/blog/313639/201312/25190638-1c3a06e8e03b4077969b7b0a73ff4d77.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnitblog.com/blog/313639/201312/25190640-f6520567a8fc4d45a7a17c62cfa2a778.png" width="208" height="138" /></a></p>

<p>過剛插入的數據「小猴」id爲1004,和<span style="color: #000000">select </span><span style="color: #008000; font-weight: bold"><span style="color: #333333">@@IDENTITY</span></span><span style="color: #000000">;結果同樣。</span> </p>

<p>4.使用mysql的<span style="color: #ff00ff"> UUID()</span>函數。前面的自增字段(auto_increment)只能生成」表內」的惟一值,且須要搭配使其爲」惟一的主鍵或惟一索引」,它的值是逐步增加的。這裏的UUID產生的是字符串類型值,固定長度爲:36個字符。UUID生成的是在時間、空間上都獨一無二的值,是「隨機+規則」組合而成。</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code"> <pre><span style="color: #0000ff">select</span><span style="color: #000000"> uuid(); </span><span style="color: #0000ff">select</span><span style="color: #000000"> uuid();

執行兩次,結果: 69ad8b74</span><span style="color: #808080">-</span>6d47<span style="color: #808080">-</span>11e3<span style="color: #808080">-</span>ba6e<span style="color: #808080">-</span><span style="color: #000000">7446a08ee8ec 69b03c16</span><span style="color: #808080">-</span>6d47<span style="color: #808080">-</span>11e3<span style="color: #808080">-</span>ba6e<span style="color: #808080">-</span>7446a08ee8ec</pre>

</div>

<p>能夠看到,屢次調用UUID()函數獲得的值不相同,它由五部分組成,而且有連字符(-)隔開,一共36個字符。其中:</p>

<p>前3組值是時間戳換算過來的,解決「時間上惟一」;</p>

<p>第4組值是暫時性保持時間戳的惟一性,重啓mysql纔會變更;</p>

<p>第5組是mac值轉過來的,有助於解決「空間上的惟一」,同一個機器多實例的通常相同。若是mac值獲取不到,則是一個隨機值。</p>

<p>這些已經能夠保證獲得的值在時間和空間上的惟一。固然你也能夠去掉連字符: select replace(uuid(),'-','')。</p>

<p>在MySQL 5.1.*及更高版本有一個變種的UUID()函數,<strong><span style="color: #ff00ff">UUID_SHORT()</span></strong>,能夠生成一個17-64位無符號的整數,注意是生成的一個整數,而前面UUID()生成的是字符串。MySQL啓動後第一次執行的值是經過時間戳等初始化這個值,在本次運行中再次調用的時候都加1。這個值通常比較大,能夠調用right(UUID_SHORT(),9)取後面的若干位。或者,你還能夠寫成自定義函數,來按需生成這個值。舉個例子:</p>

<div style="border-bottom: #cccccc 1px solid; border-left: #cccccc 1px solid; padding-bottom: 5px; background-color: #f5f5f5; padding-left: 5px; padding-right: 5px; border-top: #cccccc 1px solid; border-right: #cccccc 1px solid; padding-top: 5px" class="cnblogs_code"> <pre>#<span style="color: #800000; font-weight: bold">1</span><span style="color: #000000">.調用uuid_short()函數 </span><span style="color: #0000ff">SELECT</span><span style="color: #000000"> UUID_SHORT(); </span><span style="color: #0000ff">SELECT</span><span style="color: #000000"> UUID_SHORT();

#執行兩次獲得的值遞增的: </span><span style="color: #800000; font-weight: bold">23285634974089216</span> <span style="color: #800000; font-weight: bold">23285634974089217</span><span style="color: #000000">

#</span><span style="color: #800000; font-weight: bold">2</span><span style="color: #000000">.建立一個自定義函數,按需獲取惟一值: </span><span style="color: #0000ff">CREATE</span> DEFINER<span style="color: #808080">=</span>root@<span style="color: #808080">%</span> <span style="color: #0000ff">FUNCTION</span> GetUuidTest(SysId <span style="color: #0000ff">int</span>) <span style="color: #0000ff">RETURNS</span> <span style="color: #0000ff">int</span>(<span style="color: #800000; font-weight: bold">10</span><span style="color: #000000">) </span><span style="color: #0000ff">begin</span> <span style="color: #0000ff">declare</span> tmpID <span style="color: #0000ff">int</span><span style="color: #000000">;
</span><span style="color: #0000ff">set</span> tmpID <span style="color: #808080">=</span> <span style="color: #800000; font-weight: bold">0</span><span style="color: #000000">;
#</span><span style="color: #0000ff">SELECT</span> UUID_SHORT() <span style="color: #0000ff">into</span><span style="color: #000000"> tmpID; #直接取值 </span><span style="color: #0000ff">SELECT</span> concat(SysId,<span style="color: #808080">right</span>(UUID_SHORT(),<span style="color: #800000; font-weight: bold">8</span>)) <span style="color: #0000ff">into</span><span style="color: #000000"> tmpID;#SysId和UUID_SHORT()後8位數拼接獲得 </span><span style="color: #0000ff">return</span><span style="color: #000000"> tmpID; </span><span style="color: #0000ff">end</span><span style="color: #000000">

#</span><span style="color: #800000; font-weight: bold">3</span>.調用自定義的函數GetUuidTest(<span style="color: #0000ff">int</span><span style="color: #000000">)函數: </span><span style="color: #0000ff">select</span> GetUuidTest(<span style="color: #800000; font-weight: bold">1</span><span style="color: #000000">); </span><span style="color: #0000ff">select</span> GetUuidTest(<span style="color: #800000; font-weight: bold">1</span><span style="color: #000000">); </span><span style="color: #0000ff">select</span> GetUuidTest(<span style="color: #800000; font-weight: bold">2</span><span style="color: #000000">); </span><span style="color: #0000ff">select</span> GetUuidTest(<span style="color: #800000; font-weight: bold">2</span><span style="color: #000000">); #獲得結果: </span><span style="color: #800000; font-weight: bold">174089233</span> #<span style="color: #800000; font-weight: bold">1</span><span style="color: #808080">+</span>uuid_short()後8位(<span style="color: #800000; font-weight: bold">74089233</span><span style="color: #000000">)組成 </span><span style="color: #800000; font-weight: bold">174089234</span> #<span style="color: #800000; font-weight: bold">1</span><span style="color: #808080">+</span>uuid_short()後8位(<span style="color: #800000; font-weight: bold">74089234</span><span style="color: #000000">)組成 </span><span style="color: #800000; font-weight: bold">274089235</span> #<span style="color: #800000; font-weight: bold">2</span><span style="color: #808080">+</span>uuid_short()後8位(<span style="color: #800000; font-weight: bold">74089235</span><span style="color: #000000">)組成 </span><span style="color: #800000; font-weight: bold">274089236</span> #<span style="color: #800000; font-weight: bold">3</span><span style="color: #808080">+</span>uuid_short()後8位(<span style="color: #800000; font-weight: bold">74089236</span><span style="color: #000000">)組成 #uuid_short()值遞增,前面在加一個Id,不一樣的服務器IdSysId不一樣。

#</span><span style="color: #800000; font-weight: bold">4</span>.在例子中調用自定義函數GetUuidTest(<span style="color: #0000ff">int</span><span style="color: #000000">) 來插入記錄:這時候不須要把Id設置爲自增了。 </span><span style="color: #0000ff">insert</span> tbl_user <span style="color: #0000ff">set</span> Id<span style="color: #808080">=</span>GetUuidTest(<span style="color: #800000; font-weight: bold">1</span>),Name<span style="color: #808080">=</span><span style="color: #ff0000">'</span><span style="color: #ff0000">小熊貓</span><span style="color: #ff0000">'</span>,Age<span style="color: #808080">=</span><span style="color: #800000; font-weight: bold">22</span><span style="color: #000000">; </span><span style="color: #0000ff">insert</span> tbl_user <span style="color: #0000ff">set</span> Id<span style="color: #808080">=</span>GetUuidTest(<span style="color: #800000; font-weight: bold">2</span>),Name<span style="color: #808080">=</span><span style="color: #ff0000">'</span><span style="color: #ff0000">小鴨子</span><span style="color: #ff0000">'</span>,Age<span style="color: #808080">=</span><span style="color: #800000; font-weight: bold">21</span>;</pre>

</div>

<p>例子中,select * from tbl_user;獲得的全部記錄爲</p>

<p><a href="http://images.cnitblog.com/blog/313639/201312/25190640-3ece31e0fdd3419384139d8be1d03c37.png"><img style="background-image: none; border-right-width: 0px; margin: 0px; padding-left: 0px; padding-right: 0px; display: inline; border-top-width: 0px; border-bottom-width: 0px; border-left-width: 0px; padding-top: 0px" title="image" border="0" alt="image" src="http://images.cnitblog.com/blog/313639/201312/25190641-65d418d786984345959c7acc64ee0b6f.png" width="239" height="188" /></a></p>

<p style="text-align: left"><a href="http://www.cnblogs.com/alylee/p/Mysql_UUID.html">歡迎轉載,方便的話,請註明出處,謝謝</a>!</p>

<p style="text-align: left">做者:<a href="http://www.cnblogs.com/alylee">子韋一</a></p>

相關文章
相關標籤/搜索