為什么MySQL不推薦使用uuid或者雪花id作為主鍵?

前言
一、mysql和程序?qū)嵗?/span>
1.1.要說明這個問題,我們首先來建立三張表
注:這里的隨機(jī)key其實是指用雪花算法算出來的前后不連續(xù)不重復(fù)無規(guī)律的id:一串18位長度的long值



1.2.光有理論不行,直接上程序,使用spring的jdbcTemplate來實現(xiàn)增查測試:
package?com.wyq.mysqldemo;
import?cn.hutool.core.collection.CollectionUtil;
import?com.wyq.mysqldemo.databaseobject.UserKeyAuto;
import?com.wyq.mysqldemo.databaseobject.UserKeyRandom;
import?com.wyq.mysqldemo.databaseobject.UserKeyUUID;
import?com.wyq.mysqldemo.diffkeytest.AutoKeyTableService;
import?com.wyq.mysqldemo.diffkeytest.RandomKeyTableService;
import?com.wyq.mysqldemo.diffkeytest.UUIDKeyTableService;
import?com.wyq.mysqldemo.util.JdbcTemplateService;
import?org.junit.jupiter.api.Test;
import?org.springframework.beans.factory.annotation.Autowired;
import?org.springframework.boot.test.context.SpringBootTest;
import?org.springframework.util.StopWatch;
import?java.util.List;
@SpringBootTest
class?MysqlDemoApplicationTests?{
????@Autowired
????private?JdbcTemplateService?jdbcTemplateService;
????@Autowired
????private?AutoKeyTableService?autoKeyTableService;
????@Autowired
????private?UUIDKeyTableService?uuidKeyTableService;
????@Autowired
????private?RandomKeyTableService?randomKeyTableService;
????@Test
????void?testDBTime()?{
????????StopWatch?stopwatch?=?new?StopWatch("執(zhí)行sql時間消耗");
????????/**
?????????*?auto_increment?key任務(wù)
?????????*/
????????final?String?insertSql?=?"INSERT?INTO?user_key_auto(user_id,user_name,sex,address,city,email,state)?VALUES(?,?,?,?,?,?,?)";
????????List?insertData?=?autoKeyTableService.getInsertData();
????????stopwatch.start("自動生成key表任務(wù)開始");
????????long?start1?=?System.currentTimeMillis();
????????if?(CollectionUtil.isNotEmpty(insertData))?{
????????????boolean?insertResult?=?jdbcTemplateService.insert(insertSql,?insertData,?false);
????????????System.out.println(insertResult);
????????}
????????long?end1?=?System.currentTimeMillis();
????????System.out.println("auto?key消耗的時間:"?+?(end1?-?start1));
????????stopwatch.stop();
????????/**
?????????*?uudID的key
?????????*/
????????final?String?insertSql2?=?"INSERT?INTO?user_uuid(id,user_id,user_name,sex,address,city,email,state)?VALUES(?,?,?,?,?,?,?,?)";
????????List?insertData2?=?uuidKeyTableService.getInsertData();
????????stopwatch.start("UUID的key表任務(wù)開始");
????????long?begin?=?System.currentTimeMillis();
????????if?(CollectionUtil.isNotEmpty(insertData))?{
????????????boolean?insertResult?=?jdbcTemplateService.insert(insertSql2,?insertData2,?true);
????????????System.out.println(insertResult);
????????}
????????long?over?=?System.currentTimeMillis();
????????System.out.println("UUID?key消耗的時間:"?+?(over?-?begin));
????????stopwatch.stop();
????????/**
?????????*?隨機(jī)的long值key
?????????*/
????????final?String?insertSql3?=?"INSERT?INTO?user_random_key(id,user_id,user_name,sex,address,city,email,state)?VALUES(?,?,?,?,?,?,?,?)";
????????List?insertData3?=?randomKeyTableService.getInsertData();
????????stopwatch.start("隨機(jī)的long值key表任務(wù)開始");
????????Long?start?=?System.currentTimeMillis();
????????if?(CollectionUtil.isNotEmpty(insertData))?{
????????????boolean?insertResult?=?jdbcTemplateService.insert(insertSql3,?insertData3,?true);
????????????System.out.println(insertResult);
????????}
????????Long?end?=?System.currentTimeMillis();
????????System.out.println("隨機(jī)key任務(wù)消耗時間:"?+?(end?-?start));
????????stopwatch.stop();
????????String?result?=?stopwatch.prettyPrint();
????????System.out.println(result);
????}
1.3.程序?qū)懭虢Y(jié)果



1.4.效率測試結(jié)果


二、使用uuid和自增id的索引結(jié)構(gòu)對比
2.1.使用自增id的內(nèi)部結(jié)構(gòu)

2.2.使用uuid的索引內(nèi)部結(jié)構(gòu)

2.3.使用自增id的缺點(diǎn)
附:Auto_increment的鎖爭搶問題,如果要改善需要調(diào)優(yōu)innodb_autoinc_lock_mode的配置
三、總結(jié)
最近熱文
? ?思科前員工刪庫跑路,損失達(dá) 1600 多萬 ???如何破解“僅三天可見”的朋友圈? ???面試官寫了個雙冒號::問我這是什么語法?Java中有這玩意? ???Java反射到底慢在哪? 最近整理了一份大廠算法刷題指南,包括一些刷題技巧,在知乎上已經(jīng)有上萬贊。同時還整理了一份6000頁面試筆記。關(guān)注下面公眾號,在公眾號內(nèi)回復(fù)「刷題」,即可免費(fèi)獲取!回復(fù)「加群」,可以邀請你加入讀者群!
明天見(??ω??)??
評論
圖片
表情
