`
rensanning
  • 浏览: 3548887 次
  • 性别: Icon_minigender_1
  • 来自: 大连
博客专栏
Efef1dba-f7dd-3931-8a61-8e1c76c3e39f
使用Titanium Mo...
浏览量:38156
Bbab2146-6e1d-3c50-acd6-c8bae29e307d
Cordova 3.x入门...
浏览量:607320
C08766e7-8a33-3f9b-9155-654af05c3484
常用Java开源Libra...
浏览量:682352
77063fb3-0ee7-3bfa-9c72-2a0234ebf83e
搭建 CentOS 6 服...
浏览量:89358
E40e5e76-1f3b-398e-b6a6-dc9cfbb38156
Spring Boot 入...
浏览量:401860
Abe39461-b089-344f-99fa-cdfbddea0e18
基于Spring Secu...
浏览量:69699
66a41a70-fdf0-3dc9-aa31-19b7e8b24672
MQTT入门
浏览量:91724
社区版块
存档分类
最新评论

数据库表的ID/PK生成策略

 
阅读更多
SessionID、AccessToken、OrderID、PrimaryKey等等这些都需要一个唯一标示的ID值。

需求:
生成速度、不可推测、唯一性(高并发)、有序性

场景:
直接插入数据无需生成的ID
插入数据后需要生成的ID(主从表)

先看看Tomcat和Jetty的SessionID:

Tomcat的SessionID
https://github.com/apache/tomcat/blob/trunk/java/org/apache/catalina/util/StandardSessionIdGenerator.java

Jetty的SessionID
https://github.com/eclipse/jetty.project/blob/jetty-9.4.x/jetty-server/src/main/java/org/eclipse/jetty/server/session/DefaultSessionIdManager.java

(1)UUID/GUID
能保证唯一性,但是字节太长,无法排序,索引性能

(2)数值自动增长(auto-increment字段 / sequence)
MySQL: id bigint AUTO_INCREMENT
PostgreSQL :id bigserial

PostgreSQL :CREATE SEQUENCE users_id_seq MINVALUE 1;
nextval('users_id_seq')

插入时查找最大ID后加1:
INSERT INTO users(id, name)
VALUES ((select (case when max(id) is null then 1 else (max(id)+1) end) from users), 'xxx')


分库分表(sharding)无法保证唯一性
无法防爬虫爬数据(优惠券号码)


(3)预生成模式
使用表统一管理所有需要增长的字段,每次取出值后做加1更新:
CREATE TABLE ids (
  table_name character varying(20) NOT NULL, 
  field_name character varying(20) NOT NULL, 
  nextid bigint NOT NULL,
  CONSTRAINT ids_pkc PRIMARY KEY (table_name, field_name)
);


需要synchronized排他

(4)基于时间戳(Time-based)生成
Twitter的Snowflake

以下是Instagram采用PL/pgSQL的完整ID策略:
create sequence global_id_sequence;

CREATE OR REPLACE FUNCTION id_generator(OUT result bigint) AS $$
DECLARE
    our_epoch bigint := 1314220021721;
    seq_id bigint;
    now_millis bigint;
    -- the id of this DB shard, must be set for each
    -- schema shard you have - you could pass this as a parameter too
    shard_id int := 1;
BEGIN
    SELECT nextval('global_id_sequence') % 1024 INTO seq_id;

    SELECT FLOOR(EXTRACT(EPOCH FROM clock_timestamp()) * 1000) INTO now_millis;
    result := (now_millis - our_epoch) << 23;
    result := result | (shard_id << 10);
    result := result | (seq_id);
END;
$$ LANGUAGE PLPGSQL;

CREATE TABLE users
(
  id bigint NOT NULL DEFAULT id_generator(),
  "name" character varying(50),
  CONSTRAINT users_pkey PRIMARY KEY (id)
);
===============================================================
生成的ID:842362613529576449

最后,如何获取刚插入记录的ID的值:

MySQL:
INSERT INTO users(name) VALUES ('xxx');
SELECT LAST_INSERT_ID();


PostgreSQL:
INSERT INTO users(id, name) VALUES (1, 'xxx') RETURNING id;


JDBC 的 getGeneratedKeys() 方法:
Statement stmt = ..... ;
int count = stmt.executeUpdate( "INSERT语句", Statement.RETURN_GENERATED_KEYS);
if ( count > 0 )  {
  ResultSet rs = stmt.getGeneratedKeys();
  while( rs.next() )  {
    int generatedKey = rs.getInt( 1 ); // .....
  }
  rs.close();
}
if ( !stmt.isClosed() )  stmt.close();


参考:
https://github.com/twitter/snowflake/
https://qiita.com/kawasima/items/6b0f47a60c9cb5ffb5c4
http://instagram-engineering.tumblr.com/post/10853187575/sharding-ids-at-instagram
http://www.wekeroad.com/2014/05/29/a-better-id-generator-for-postgresql/
http://blog.codinghorror.com/primary-keys-ids-versus-guids/
http://my.oschina.net/u/142836/blog/174465
http://blog.csdn.net/bluishglc/article/details/7710738
业务系统需要什么样的ID生成器
如何在高并发分布式系统中生成全局唯一Id
分享到:
评论

相关推荐

    使用SQL查询 生成sql server数据库结构字典 生成html

    SQL Server数据库字典可以帮助我们清晰地看到每张表的结构、各字段的定义等信息。下面将详细介绍如何使用SQL查询快速生成SQL Server数据库的结构字典,并将其格式化输出为易于阅读的HTML文档。 #### SQL查询生成...

    JPA学习笔记-EJB-03JPA主键生成策略总结

    - **概述**:`TABLE`策略通过在数据库中创建一个单独的表来管理主键值。这种方式相对独立于数据库类型,适合需要跨库生成唯一ID的场景。该策略通过`@TableGenerator`注解来配置生成器的细节。 - **示例代码**: ...

    数据库结构文档生成器

    随着项目的复杂度增加,数据库表结构也会越来越复杂,这就需要一个工具能够帮助我们快速地生成数据库结构文档,以便于团队成员之间的沟通与协作。本文将详细介绍一种基于SQL查询来实现数据库结构文档生成的方法。 *...

    数据库关系图导出到sql文件 数据库模型图导出到sql文件

    ALTER TABLE [dbo].[sysdiagrams] ADD CONSTRAINT [PK__sysdiagr__C2B05B61023D5A04] PRIMARY KEY CLUSTERED ([diagram_id]) ON [PRIMARY]GO ALTER TABLE [dbo].[sysdiagrams] ADD CONSTRAINT [UK_principal_name] ...

    Powerdesigner逆向工程从现有数据库生成PDM

    ### PowerDesigner逆向工程从现有数据库生成PDM详解 #### 一、背景介绍 在数据建模领域,PowerDesigner是一款非常强大的工具,它能够帮助数据架构师和开发人员设计、构建以及维护高质量的数据模型。传统的数据建模...

    PowerDesigner逆向工程生成PDM模型及数据库

    在PowerDesigner中,导入这样的SQL脚本,可以自动解析其中的表结构,生成对应的PDM模型,进一步实现对数据库设计的管理与优化。 #### 总结 逆向工程在PowerDesigner中的运用,极大地简化了数据库与物理数据模型之间...

    Hibernate映射文件主键的生成

    在Java的持久化框架Hibernate中,主键的生成策略是一个重要的概念,它涉及到数据库表记录的唯一标识如何自动生成。本篇文章将详细讲解Hibernate映射文件中关于主键生成的各种策略及其配置,帮助开发者更好地理解和...

    AWS6.1-数据库表结构参考

    ### AWS6.1-数据库表结构参考 #### 核心知识点概述 本文档详细介绍了AWS6.1数据库表结构的设计规范及其应用示例。主要内容包括数据库表命名规则、字段命名规则、索引命名规则以及常见字段的定义。此外,还提供了以...

    获取数据库表、视图、字段等.pdf

    这通常涉及到对系统表的查询,以便获取元数据,进而生成自定义的代码或进行数据库维护。 首先,获取数据库列表是基础步骤。在SQL Server 2005中,系统表`sysdatabases`包含了所有数据库的信息。我们可以执行以下SQL...

    获取SQL2005的数据库表结构

    where xtype='PK' and parent_obj = syscolumns.id and sysindexkeys.colid = syscolumns.colid) then 1 else 0, IsIdentity = Case when syscolumns.isidentity = 1 then 1 else 0 end from syscolumns, ...

    hibernate中的generator的生成方式hibernate中的generator的生成方式

    不同的数据库和不同的应用场景可能需要不同的生成策略。接下来,我们将逐一介绍各种常见的生成策略及其适用场景。 #### 1. Assigned - **定义**:该策略允许用户手动为实体指定主键值。 - **使用场景**:当应用...

    数据库设计商业数据库对象命名规范

    - 字段规则,如主键字段,应明确其角色,如`customer_id_pk`,表示这是`customer`表的主键字段。 3. 变量使用: - 在编写存储过程或函数时,变量命名应清晰描述其存储的数据,如`v_customer_name`,`v_order_...

    获取数据库表、视图、字段等.docx

    在开发应用程序时,经常需要与数据库进行交互,这包括获取数据库中的表、视图以及它们的字段信息。本文将详细介绍如何通过SQL查询来获取这些信息,以SQL Server 2005为例。 首先,我们需要了解SQL Server的系统表。...

    图书管理系统数据库

    例如,`admin`和`reader`表都添加了主键约束(PK_adminId 和 PK_readerId),确保每条记录的唯一性。同时,这两个表还添加了针对性别和年龄的检查约束,以保持数据的逻辑一致性。 这个图书管理系统数据库的设计是...

    二维码数据库设计报告.doc

    此外,还需要考虑其他可能的表,如二维码信息表(包含二维码ID、关联数据、生成时间等),扫描记录表(记录二维码的扫描次数、扫描时间、扫描位置等)。 在设计过程中,应充分考虑数据的完整性、安全性、性能优化...

    数据库知识整理,很详细完整,适合入门或者复习。

    序列是一种特殊的数据库对象,用于自动生成唯一编号,通常用于为主键字段提供值。 ##### 1. 创建序列 - **示例代码**: ```sql CREATE SEQUENCE seq_emp_id START WITH 1 INCREMENT BY 1 MINVALUE 1 MAXVALUE 9999 ...

    数据库命名规范(表、字段名).docx

    数据库自动生成的自动编号简单命名为ID。 2. 类型后缀: - 属性名应加上类型后缀,如TX表示文本类型。特殊情况下可省略,如类型明显或依赖关系明确。 3. 关系命名: - 关系命名遵循特定结构,如[must/may/can/...

    大数据Excel通过POI导入数据库通用设计方案

    - Produce_method:生成方法,可以是直接导入、自定义策略或默认值。 - Is_unique:是否要求列数据唯一,用于判断重复数据。 - Column_name:数据库中的列名。 - Header_name:Excel中的列标题。 三、导入规则...

    oracle数据库

    通过以上概述,我们了解了Oracle数据库的基本管理和核心概念,包括SQL\*PLUS的常用命令、数据定义语言(DDL)的使用、表的约束及主键的设计原则,为深入学习Oracle数据库管理打下了坚实的基础。

Global site tag (gtag.js) - Google Analytics