web前端开发项⽬实例,CSS浮动实战
前⾔:在mysql中设计表的时候,mysql官⽅推荐不要使⽤uuid或者不连续不重复的雪花id(long形且唯⼀),⽽是推荐连续⾃增的主键id,官⽅的推荐是auto_increment,那么为什么不建议采⽤uuid,使⽤uuid究竟有什么坏处?本篇博客我们就来分析这个问题,探讨⼀下内部的原因。
⼀:mysql和程序实例
1.1:要说明这个问题,我们⾸先来建⽴三张表,分别是user_auto_key,user_uuid,user_random_key,分别表⽰⾃动增长的主键,uuid作为主键,随机key作为主键,其它我们完全保持不变.根据控制变量法,我们只把每个表的主键使⽤不同的策略⽣成,⽽其他的字段完全⼀样,然后测试⼀下表的插⼊速度和查询速度:
注:这⾥的随机key其实是指⽤雪花算法算出来的前后不连续不重复⽆规律的id:⼀串18位长度的long值
id⾃动⽣成表:
⽤户uuid表
随机主键表:
1.2:光有理论不⾏,直接上程序,使⽤spring的jdbcTemplate来实现增查测试:
技术框架:springboot+jdbcTemplate+junit+hutool,程序的原理就是连接⾃⼰的测试数据库,然后在相同的环境下写⼊同等数量的数据,来分析⼀下insert插⼊的时间来进⾏综合其效率,为了做到最真实的效果,所有的数据采⽤随机⽣成,⽐如名字、邮箱、地址都是随机⽣成,程序已上传⾃gitee,地址在⽂底。
package sqldemo;
springboot推荐算法
import ollection.CollectionUtil;
import sqldemo.databaseobject.UserKeyAuto;
import sqldemo.databaseobject.UserKeyRandom;
import sqldemo.databaseobject.UserKeyUUID;
import sqldemo.diffkeytest.AutoKeyTableService;
import sqldemo.diffkeytest.RandomKeyTableService;
import sqldemo.diffkeytest.UUIDKeyTableService;
import sqldemo.util.JdbcTemplateService;
import org.junit.jupiter.api.Test;
import org.springframework.beans.factory.annotation.Autowired;
import org.st.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("执⾏sql时间消耗");
/**
* auto_increment key任务
*/
final String insertSql = "INSERT INTO user_key_auto(user_id,user_name,sex,address,city,email,state) VALUES(?,?,?,?,?,?,?)";
List<UserKeyAuto> insertData = InsertData();
stopwatch.start("⾃动⽣成key表任务开始");
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<UserKeyUUID> insertData2 = InsertData();
stopwatch.start("UUID的key表任务开始");
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(?,?,?,?,?,?,?,?)"; List<UserKeyRandom> insertData3 = InsertData();
stopwatch.start("随机的long值key表任务开始");
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任务消耗时间:" + (end - start));
stopwatch.stop();
String result = stopwatch.prettyPrint();
System.out.println(result);
}
1.3:程序写⼊结果
user_key_auto写⼊结果:
user_random_key写⼊结果:
user_uuid表写⼊结果:
1.4:效率测试结果
在已有数据量为130W的时候:我们再来测试⼀下插⼊10w数据,看看会有什么结果:
可以看出在数据量100W左右的时候,uuid的插⼊效率垫底,并且在后续增加了130W的数据,uudi的时间⼜直线下降。时间占⽤量总体可以打出的效率排名为:auto_key>random_key>uuid,uuid的效率最低,在数据量较⼤的情况下,效率直线下滑。那么为什么会出现这样的现象呢?带着疑问,我们来探讨⼀下这个问题:
⼆:使⽤uuid和⾃增id的索引结构对⽐
2.1:使⽤⾃增id的内部结构
⾃增的主键的值是顺序的,所以Innodb把每⼀条记录都存储在⼀条记录的后⾯。当达到页⾯的最⼤填充因⼦时候(innodb默认的最⼤填充因⼦是页⼤⼩的15/16,会留出1/16的空间留作以后的 修改):
①下⼀条记录就会写⼊新的页中,⼀旦数据按照这种顺序的⽅式加载,主键页就会近乎于顺序的记录填满,提升了页⾯的最⼤填充率,不会有页的浪费
②新插⼊的⾏⼀定会在原有的最⼤数据⾏下⼀⾏,mysql定位和寻址很快,不会为计算新⾏的位置⽽做出额外的消耗
③减少了页分裂和碎⽚的产⽣
2.2:使⽤uuid的索引内部结构
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论