MySQL 為啥不能用 UUID 做主鍵?
來自:博客園 | 作者:Yrion
前言
mysql程序?qū)嵗?/section> 使用uuid和自增id的索引結(jié)構(gòu)對比 總結(jié)
一、mysql和程序?qū)嵗?/span>
1.1.要說明這個問題,我們首先來建立三張表
注:這里的隨機(jī)key其實(shí)是指用雪花算法算出來的前后不連續(xù)不重復(fù)無規(guī)律的id:一串18位長度的long值



1.2.光有理論不行,直接上程序,使用spring的jdbcTemplate來實(shí)現(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é)
喜歡就三連呀
長按識別如下兩個公眾號二維碼,可在該公眾號平臺優(yōu)惠充值話費(fèi),流量,視頻會員等。(如二維碼已過期,可在公眾號后臺發(fā)送?充值?獲取最新二維碼)
評論
圖片
表情
