mysql 主键 最佳实践_设计套路:Mysql主键的选取

最近在对一些大表进行优化,发现主键和索引设计都有争议,就此从原理上分析主键设计该如何选取。

Mysql的数据结构

Mysql是由B+树构成,搞清楚下面两个问题,就知道为什么用B+树了。

FmxVVIkPQxVq5JqXzXGn9rhDSUTH

1.B+Tree是为磁盘或者其他直接存取辅助设备而设计的一种平衡二叉树?

答:数据库系统的设计者巧妙利用了磁盘预读原理,将一个节点的大小设为等于一个页,这样每个节点只需要一次I/O就可以完全载入。为了达到这个目的,在实际实现B+Tree还需要使用如下技巧:每次新建节点时,直接申请一个页的空间,这样就保证一个节点物理上也存储在一个页里,加之计算机存储分配都是按页对齐的,就实现了一个node只需一次I/O。

②B+Tree的节点都是按照键值的大小顺序存放的,叶节点之间也通过指针连接起来,为了提高取数据时的效率。

主键的选取

我先把结论给出来,方便喜欢直接套用的童鞋,但是对技术有追求的人来说,还是了解下原理比较有说服力。

非分布式架构直接套用自增id做主键

小规模分布式架构用uuid或者自增id+步长做主键

大规模分布式架构用自建的id生成器做主键,参考twitter的snowflake算法

一.自增id

1.性能消耗

从上面的原理可以得知,Mysql会按照键值的大小进行顺序存放,如果我们设置自增id为主键,这个时候主键是按照一种紧凑的接近顺序写入的方式进行存储数据。

Fltd_FHMoMVAxxNBqpxjS_nXKWAc

如果我们用其他字段作为主键的话,此时Mysql不得不为了将新记录插到合适位置而移动数据,甚至目标页面可能已经被回写到磁盘上而从缓存中清掉,此时又要从磁盘上读回来,这增加了很多额外的开销,同时频繁的移动、分页操作造成了大量的碎片。

FhieZwh69irAcx2UlcMnL9xRZeRO

2.资源消耗

根据mysql官方的文档,非聚集(二级)索引都包含主键索引的列,所以如果主键太大,非聚集索引

会占用更多的磁盘空间。

二.uuid或者自增id+步长

小规模分布式在数据量不大,使用成本最低的方式就直接用uuid,或者自增id+步长的方式,省时省力。

三.自建的id生成器

当数据量比较大,又是分布式架构的时候,可能我们需要考虑各种分库分表方案了,这个时候就不能贪图方便,必须有更好更长远的方案来替代。自建id生成器,可以保证全局唯一,可以参考snowflake的算法方案,具体实施也可以根据自身业务进行调整算法。唯一麻烦的就是id生成器的高可用问题,需要多加注意。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/525890.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

mysql写下拉树_PHP+mysql实现从数据库获取下拉树功能的方法

这篇文章主要介绍了PHPmysql实现从数据库获取下拉树功能,结合实例形式分析了phpmysql数据库查询及select下拉框输出查询结果的实现技巧,需要的朋友可以参考下本文实例讲述了PHPmysql实现从数据库获取下拉树功能。分享给大家供大家参考,具体如下:include …

mysql ssh错误_通过SSH隧道连接时,MySQL访问被拒绝错误

几个月来,我一直通过SSH隧道连接到我们本地测试服务器上运行的MySQL实例,没有任何问题.突然之间,没有我能想到的任何变化,服务器已经开始拒绝来自Sequel Pro的登录尝试,但错误:Unable to connect to host 127.0.0.1 because access was denied.Double-check your us…

java tostring格式化日期_java日期格式化SimpleDateFormat的使用详解

日期和时间格式由 日期和时间模式字符串 指定。在 日期和时间模式字符串 中,未加引号的字母 A 到 Z 和 a 到 z 被解释为模式字母,用来表示日期或时间字符串元素。文本可以使用单引号 () 引起来,以免进行解释。所有其他字符均不解释&#xff1…

java pingpong_面试题。线程pingpong的输出问题

第一种情况:public class Main {public static void main(String args[]) {Thread t new Thread() {public void run() {pong();}};t.run();System.out.println("ping");}static void pong() {System.out.println("pong");}}输出:p…

java将字体输出成图片格式_JAVA IO流中,能否将一个字符串以图片的格式输出出来呢,即字符串显示在图片上...

展开全部执行成功后会在D盘根目录生成32313133353236313431303231363533e59b9ee7ad9431333332616433一张名为image的jpg格式的图片,图片上以红色Serif体写着“你好”两个字——import java.awt.Color;import java.awt.Font;import java.awt.Graphics2D;import java.…

java hibernate 多对多_java - hibernate多对多问题

映射文件如下:sequence_stuidsequence_teaidTestpublic void testSave2() {Configuration cfg null;ServiceRegistry sr null;SessionFactory sf null;Session session null;Transaction tx null;try {cfg new Configuration().configure("hibernate.cfg…

java封装对象数组_java解析JSON对象和封装对象的示例

在本例中java解析JSON对象使用的是org.json,因此,如果各位想测试我的代码,请先确保有java.json.jar包,否则,就需要去网上下载这个jar包,然后才可以正常使用本代码。本例的功能就是对两个json对象&#xff0…

python xgboost用法_XGBoost使用教程(纯xgboost方法)一

一、导入必要的工具包# 导入必要的工具包import xgboost as xgb# 计算分类正确率from sklearn.metrics import accuracy_score二、数据读取XGBoost可以加载libsvm格式的文本数据,libsvm的文件格式(稀疏特征)如下:1 101:1.2 102:0.030 1:2.1 10001:300 …

ul 原点显示_CSS+HTML ul li列表原点如何相连

方案一:html参与考试《第一期模拟考试》3小时50分钟学习文档《LDO电路设计规范》3小时50分钟学习文档《LDO电路设计规范》3小时50分钟Css:*{margin:0;padding:0;}ul{margin:100px;padding:0;list-style: none;}ul li{position:relative;padding-left: 30px;padding-bottom: 20p…

java并发执行一个方法_JAVA的执行并发原理

VolatileVolatile关键字用于确保共享数据的可见性与有序性,但是并不能保证方法的原子性,在程序中对Volatile关键字使用得当的话,它比synchronized的使用和执行成本会更低,因为他不会引起线程的上下文切换和调度。先讲一下重排序&a…

java欧洲_java欧洲/明斯克时区问题

我写了以下程序:import sun.security.action.GetPropertyAction;import java.security.AccessController;import java.text.SimpleDateFormat;import java.util.Date;import java.util.TimeZone;public class Main {public static void main(String[] args) {System…

java.util. 什么意思_java.util中,util是什么意义

展开全部1. util包的框架常用的集合类主要636f70793231313335323631343130323136353331333431343630实现两个“super接口”而来:Collection和Map。1.1 Collection有两个子接口:List和SetList特点是元素有序,且可重复。实现的常用集合类有Arra…

算法描述怎么写伪代码java_伪代码描述算法

伪代码是自然语言和类编程语言组成的混合结构。它比自然语言更精确,描述算法很简洁;同时也可以很容易转换成计算机程序。下面就为大家介绍一下伪代码描述算法的介绍。伪代码描述算法一、算法描述是指对设计出的算法,用一种方式进行详细的描述…

java测试用例编写_TestNG测试用例编写和执行

编写TestNG用例测试基本上包括以下步骤:编写业务逻辑针对业务逻辑中涉及的方法编写测试类,在代码中插入TestNG的注解直接执行测试类或者添加一个testng.xml文件运行 TestNG.下面我们介绍一个完整的例子来测试一个逻辑类;1.创建一个pojo类Empl…

好爽 java_Intellij是进行scala开发的一个非常好用的工具,可以非常轻松查看scala源码,当然用它来开发Java也是很爽的,之前一直在用scala ide和ec...

Intellij是进行scala开发的一个非常好用的工具,可以非常轻松查看scala源码,当然用它来开发Java也是很爽的,之前一直在用scala ide和eclipse,现在换成intellij简直好用到飞起,但是有些人不知道怎么用intellij去创建一个…

java创建读取文件_Java实现文件的创建、读取、写入操作-Fun言

在日常的开发中,对文件的操作经常会有,所以今天教大家其中一种使用Java实现文件的创建、读取、写入操作创建文件String filenameTemp "D:\demo.txt";File filename new File(filenameTemp);if (!filename.exists()) {filename.createNewFile…

java调用js查询mongo_MongoDB增删查改操作示例【基于JavaScript Shell】

本文实例讲述了MongoDB增删查改操作。分享给大家供大家参考,具体如下:MongoDB自带了一个JavaScript Shell,所以在其中使用js语法是可以的。Insert操作:单条插入var single{"name":"mei","age":22}d…

java中什么是task_20171018java总结——Spring任务调度task:scheduled-tasks

从认识eclipse开始到现在,学习编程已经接近8个月的时间,从什么都不懂,到现在慢慢一点点学习编程,自己在不断地进步,要学习的地方还有很多。自己也从这个平台收获到了很多知识,我也希望在这个博客上面记录自…

java155apk_【原创】浅谈 Android APK定点爆破

[Java] 纯文本查看 复制代码.class public Lcom/mayor/codeSig/CodeSigWindow;.super Landroid/app/Activity;.source "CodeSigWindow.java"# instance fields.field private csig:Ljava/lang/String;.field editText:Landroid/widget/EditText;.field private isNum…

python包含多个元组的元组_如何在python中将多个”列出的”元组连接成一个元组?...

在python中,关于这个问题的答案很少,如何将一个元组列表连接到一个列表中?,如何在python中合并两个元组?,如何在python中合并任意数量的元组?所有的答案都引用了元组列表,所以提供的…