為什么MySQL不推薦使用uuid或者雪花id作為主鍵?
在mysql中設(shè)計表的時候,mysql官方推薦不要使用uuid或者不連續(xù)不重復(fù)的雪花id(long形且唯一,單機遞增),而是推薦連續(xù)自增的主鍵id,官方的推薦是auto_increment,那么為什么不建議采用uuid,使用uuid究竟有什么壞處?
本篇博客我們就來分析這個問題,探討一下內(nèi)部的原因。
本篇博客的目錄
mysql程序?qū)嵗?/p>
使用uuid和自增id的索引結(jié)構(gòu)對比
總結(jié)
一、mysql和程序?qū)嵗?/span>
1.1.要說明這個問題,我們首先來建立三張表
注:這里的隨機key其實是指用雪花算法算出來的前后不連續(xù)不重復(fù)無規(guī)律的id:一串18位長度的long值



@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(?,?,?,?,?,?,?)";
????????ListinsertData = 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(?,?,?,?,?,?,?,?)";
????????ListinsertData2 = 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();
????????/**
?????????* 隨機的long值key
?????????*/
????????final?String insertSql3 =?"INSERT INTO user_random_key(id,user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?,?)";
????????ListinsertData3 = randomKeyTableService.getInsertData();
????????stopwatch.start("隨機的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("隨機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)
③減少了頁分裂和碎片的產(chǎn)生
2.2.使用uuid的索引內(nèi)部結(jié)構(gòu)

附:Auto_increment的鎖爭搶問題,如果要改善需要調(diào)優(yōu)innodb_autoinc_lock_mode的配置
三、總結(jié)
歡迎關(guān)注“Java引導(dǎo)者”,我們分享最有價值的Java的干貨文章,助力您成為有思想的Java開發(fā)工程師!
評論
圖片
表情


