雪花主键_在postgres的实现

一、主键的属性:

1. 全局唯一,不重复

2. 趋势有序,后面的值大于前面的值

3. 高性能, 读写效率高。qps不能太低,否则容易造成线程堵塞

4. 可用性好,业务对ID的可用性高,不存在单点故障


二、常见的主键方式

2.1、自增主键

利用数据库表自增主键

优点: 1. 简单

            2. 查询和插入的性能高

            3. 保证有序

缺点:1. 无法保证全局唯一, 分库分表

2.2、UUID

以java的UUID为例

优点: 1. 基本能保证全部唯一(重复概率低),如果加上时间戳和机器码

缺点: 1. 无序,无法保证后来的消息主键值大于前面的主键

            2. 因为乱序,所以对数据的存储,以mysql为例,B+树形结构的存储不友好。读写效率低

2.3、雪花主键

优点: 1. 基本能保证全部唯一(重复概率低)

            2. 主键值有序

            3. 读取性能高

            4. 可用性好,他适合分布式主键,不担心单点故障。

缺点: 1. 写入性能没自增主键好 (自增主键是int类型)

            2. 存在乱序或 重复的可能性,即机器的时钟回调


三、雪花主键的原理

一共64位,8个字节。它的值分别有, 符号位,时间戳,机器码,序列号组成。

基础的格式是,位数是从低向高(从右往左数)

1. 第64位,符号位, 0代表正数,1代表负数。所以默认为0

2. 第23-63位,一共41位,是时间戳的值,毫秒值。2^41 = 2199023255552 毫秒。除以 24*60*60*1000,约为69年。标准时间戳基准是1970-1-1,即可以用到 2039-1-1, 为了增加使用时间 ,可以修改时间基准值。

3. 第13-23位,一共10位,是机器ID值, 2^10, 1024台机器。集群可以有1024个节点。

4. 第1-12位,一共12位,是序列值,2^12 = 4096, 即每个节点每毫秒最大的并发,生成4096个雪花值。再多就会重复了。如果想要增加并发值, 可以降低机器ID值的位数,增加序列值的位数(一般集群也不会有1024个节点)。 

例如修改成23-15,一共8位是机器ID值,2^8 = 256 ,也有256个节点值。 1-14位是序列值,则16384,每个节点每毫秒的最大并发数就有16384个了。

下图为标准的雪花位数示意图


四、雪花主键的实现

华为高斯dws数据仓库,postgres的sql语法实现。

4.1、序列值

创建一个序列 

SET search_path = test;
CREATE SEQUENCE seq_table_id_1START WITH 0   -- 序列值开始值INCREMENT BY 1 -- 步长MINVALUE 0    -- 最小值NO MAXVALUE  -- 为了保证 序列有序, 如果设定了最大值,则要打开cycleCACHE 100;  -- 缓存,加快速度

4.2、雪花主键的实现

/**
本例是按照标准的雪花位数分配,即机器ID值是10位,序列号是12位。
本例没有规范机器ID值,因为我的集群实际也只有一台。 你可以依据自己实际情况,指定机器ID值,例如mac码,ip地址等。
获取机器ID值后调用函数传入参数
*/ CREATE OR REPLACE FUNCTION test.f_generate_snow_id(input_machine_id integer)RETURNS bigintLANGUAGE plpgsqlNOT FENCED SHIPPABLE
AS $$
DECLARE
--   our_epoch bigint := 1672502400000; --2023-1-1 00:00:00 的时间戳 , 修改基准时间为2023-01-01. 这样就可以使用到 2023 +69 = 2092年。seq_id bigint;machine_id int;now_millis bigint;result bigint := 0 ;  --确保符号位是0,正数
BEGINseq_id := nextval('test.seq_table_id_1') % 4096; -- 序列号值大于4096,需要循环machine_id := input_machine_id % 1024 ;-- SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;-- result := result | ((now_millis - our_epoch) << 22) ; -- 调整基准时间的实现SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;result := result | (now_millis  << 22) ;result := result | (machine_id << 10) ;result := result | (seq_id&4095);  return result;
END $$
/

 五、测试写入性能。

5.1、目标表,建表时指定主键,并使用雪花

create table test.t_test(id bigint not null default test.f_generate_snow_id(20)  -- 建表时,传入 0-1023 的  任意值, age int,PRIMARY key (id)
)

 数据来源表: 200w

create table test.t_source(id int,name varchar2 
)

生产200w数据插入来源表 t_source.  这个语句效率有点低跑了30+分钟

DECLARE
i bigint := 0 ;
sql    text;
begin 
loopsql := 'insert into test.t_source(age) values (1) ;' ;EXECUTE sql;i := i+1 ; exit when i > 2000000 ;
end loop ;
end ;

 5.2、插入性能

insert into test.t_test(age)
select age from test.t_source

费时: 2min37s

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

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

相关文章

漏洞复现-任我行CRM系统SmsDataList接口SQL注入漏洞(附漏洞检测脚本)

免责声明 文章中涉及的漏洞均已修复&#xff0c;敏感信息均已做打码处理&#xff0c;文章仅做经验分享用途&#xff0c;切勿当真&#xff0c;未授权的攻击属于非法行为&#xff01;文章中敏感信息均已做多层打马处理。传播、利用本文章所提供的信息而造成的任何直接或者间接的…

3DMAX 中的 VR 渲染器如何设置局部渲染?

首先我们要得打开渲染设置&#xff0c;在3damx里按F10&#xff0c;调出渲染设置。选定渲染器为Vary渲染器&#xff1a; 设置VR的局部渲染&#xff0c;需要打开帧缓冲&#xff0c;我们在V-ary项下&#xff0c;打开帧缓冲(点击显示VFB)&#xff1a; 然后点击茶壶按钮&#xff08;…

如何打开wps的备份中心查找备份文件

备份中心在我们使用WPS Office时扮演着重要的角色。经常保存文件的同时&#xff0c;我们也应该学会备份文件&#xff0c;以免意外损失。本文将向您介绍如何使用WPS备份中心来查找并恢复备份文件&#xff0c;方便您在需要时快速找到所需文件。 图片来源于网络&#xff0c;如有侵…

2024美赛数学建模常用数学建模模型之——层次分析法

一、层次分析法的基本原理与步骤 人们在进行社会的、经济的以及科学管理领域问题的系统分析中&#xff0c;面临的常常是 一个由相互关联、相互制约的众多因素构成的复杂而往往缺少定量数据的系统。层次 分析法为这类问题的决策和排序提供了一种新的、简洁而实用的建模方法。 …

数据库设计-DDL

D D L \huge{DDL} DDL DDL&#xff1a;数据库定义语言&#xff0c;用来定义数据对象&#xff08;数据库、表&#xff09; 简单操作 首先在cmd中进行操作&#xff0c;登录数据库 show databases; -- 以列表的形式显示所有的数据库create database [if not exists] 数据库名称…

ngrok-内网穿透

一、访问官网下载相关的内容 Download (ngrok.com) linux或者windows可供选择&#xff0c;主要在于你的项目跑在什么地方 选择下载 二、获取Authtoken 点击右上角登录&#xff0c;没有号用谷歌账号登录即可跳转 三、在Windows进行内网穿透 下载打开 打开 运行在命令行中&am…

CodeWave智能开发平台--02--目标:文档快速阅读--02新手入门

摘要 本文是网易数帆CodeWave智能开发平台系列的第03篇&#xff0c;主要介绍了基于CodeWave平台文档的新手入门进行学习&#xff0c;并对新手入门的内容重新排序 CodeWave智能开发平台的03次接触 CodeWave参考资源 网易数帆CodeWave开发者社区课程中心 网易数帆CodeWave开发…

爬虫入门与urllibrequests

前情摘要 一、web请求全过程剖析 我们浏览器在输入完网址到我们看到网页的整体内容, 这个过程中究竟发生了些什么? 我们看一下一个浏览器请求的全过程 接下来就是一个比较重要的事情了. 所有的数据都在页面源代码里么? 非也~ 这里要介绍一个新的概念 那就是页面渲染数据的…

【零基础入门TypeScript】TypeScript - 运算符

目录 ​编辑 什么是操作员&#xff1f; 算术运算符 关系运算符 逻辑运算符 按位运算符 赋值运算符 杂项运算符 否定运算符 (-) 字符串运算符&#xff1a;连接运算符 () 条件运算符 (?) 类型运算符 类型运算符 实例化 什么是操作员&#xff1f; 运算符定义将对数…

yolo增加Shape-IoU,完美超越SIoU/EIoU/CIoU

论文地址&#xff1a;https://arxiv.org/pdf/2312.17663.pdf 代码地址&#xff1a;GitHub - malagoutou/Shape-IoU 摘要 作为检测定位分支的重要组成部分&#xff0c;边界框回归损失在目标检测任务中起着重要作用。现有的边界框回归方法通常考虑GT框和预测框之间的几何关系&…

Arrays

Arrays 用来操作数组的一个工具类 Arrays提供的常见方法 方法名说明public static String toString&#xff08;类型 [ ] arr&#xff09;返回数组的内容 public static int [ ] copyOfRange&#xff08;类型 [ ] arr&#xff0c;起始索引&#xff0c;结束索引&#xff09;…

uniapp 使用wx.getFuzzyLocation获取当前的模糊地理位置

前言&#xff1a; 最近在进行一个小程序项目开发的时候&#xff0c;需要用到定位的功能&#xff0c;然后首先是尝试了getLocation方法&#xff0c;但是sccess中的内容始终无法打印&#xff0c;后来才知道是需要申请权限&#xff0c;在连续小程序后台管理员申请权限之后&#x…