数据库主键目前主要有两种:

a、自增数值型

  优:占用空间小,插入快,有序对索引友好,易懂

缺:多数据库迁移会有重复键值问题,有可能爆表

b、GUID

  优:多数据库唯一

  缺:占用空间大,无序对索引不友好,不易懂

察看GUD发现最主要的问题还是在于无序对索引不友好,会引起性能问题,已知有以下两种方式可以解决:

1、基于Twitter的snowflake算法,生成一个long型ID,参考代码如下:

  

  1. public class IdWorker
  2. {
  3. private long workerId;
  4. private long datacenterId;
  5. private long sequence = 0L;
  6.  
  7. private static long twepoch = 1288834974657L;
  8.  
  9. private static long workerIdBits = 5L;
  10. private static long datacenterIdBits = 5L;
  11. private static long maxWorkerId = -1L ^ (-1L << (int)workerIdBits);
  12. private static long maxDatacenterId = -1L ^ (-1L << (int)datacenterIdBits);
  13. private static long sequenceBits = 12L;
  14.  
  15. private long workerIdShift = sequenceBits;
  16. private long datacenterIdShift = sequenceBits + workerIdBits;
  17. private long timestampLeftShift = sequenceBits + workerIdBits + datacenterIdBits;
  18. private long sequenceMask = -1L ^ (-1L << (int)sequenceBits);
  19.  
  20. private long lastTimestamp = -1L;
  21. private static object syncRoot = new object();
  22.  
  23. public IdWorker(long workerId, long datacenterId)
  24. {
  25.  
  26. // sanity check for workerId
  27. if (workerId > maxWorkerId || workerId < )
  28. {
  29. throw new ArgumentException(string.Format("worker Id can't be greater than %d or less than 0", maxWorkerId));
  30. }
  31. if (datacenterId > maxDatacenterId || datacenterId < )
  32. {
  33. throw new ArgumentException(string.Format("datacenter Id can't be greater than %d or less than 0", maxDatacenterId));
  34. }
  35. this.workerId = workerId;
  36. this.datacenterId = datacenterId;
  37. }
  38.  
  39. public long nextId()
  40. {
  41. lock (syncRoot)
  42. {
  43. long timestamp = timeGen();
  44.  
  45. if (timestamp < lastTimestamp)
  46. {
  47. throw new ApplicationException(string.Format("Clock moved backwards. Refusing to generate id for %d milliseconds", lastTimestamp - timestamp));
  48. }
  49.  
  50. if (lastTimestamp == timestamp)
  51. {
  52. sequence = (sequence + ) & sequenceMask;
  53. if (sequence == )
  54. {
  55. timestamp = tilNextMillis(lastTimestamp);
  56. }
  57. }
  58. else
  59. {
  60. sequence = 0L;
  61. }
  62.  
  63. lastTimestamp = timestamp;
  64.  
  65. return ((timestamp - twepoch) << (int)timestampLeftShift) | (datacenterId << (int)datacenterIdShift) | (workerId << (int)workerIdShift) | sequence;
  66. }
  67. }
  68.  
  69. protected long tilNextMillis(long lastTimestamp)
  70. {
  71. long timestamp = timeGen();
  72. while (timestamp <= lastTimestamp)
  73. {
  74. timestamp = timeGen();
  75. }
  76. return timestamp;
  77. }
  78.  
  79. protected long timeGen()
  80. {
  81. return (long)(DateTime.UtcNow - new DateTime(, , , , , , DateTimeKind.Utc)).TotalMilliseconds;
  82. }
  83. }

2、用NewId开源项目

  项目地址:https://github.com/phatboyg/NewId

使用方法:

  1. NewId id = NewId.Next(); //produces an id like {11790000-cf25-b808-dc58-08d367322210}
  2.  
  3. // Supports operations similar to GUID
  4. NewId id = NewId.Next().ToString("D").ToUpperInvariant();
  5. // Produces 11790000-CF25-B808-2365-08D36732603A
  6.  
  7. // Start from an id
  8. NewId id = new NewId("11790000-cf25-b808-dc58-08d367322210");
  9.  
  10. // Start with a byte-array
  11. var bytes = new byte[] { , , , , , , , , , , , , , , , };
  12. NewId theId = new NewId(bytes);

c#生成唯一编号方法记录,可用数据库主键 唯一+有序的更多相关文章

  1. 利用Java.util.UUID来生成唯一ID(用来做数据库主键好用)

    UUID(Universally Unique Identifier)全局唯一标识符,是指在一台机器上生成的数字,它保证对在同一时空中的所有机器都是唯一的.按照开放软件基金会(OSF)制定的标准计算, ...

  2. Statement和PreparedStatement的特点 MySQL数据库分页 存取大对象 批处理 获取数据库主键值

    1 Statement和PreparedStatement的特点   a)对于创建和删除表或数据库,我们可以使用executeUpdate(),该方法返回0,表示未影向表中任何记录   b)对于创建和 ...

  3. SQL 数据库主键 ,外键

    主键 数据库主键是指表中一个列或列的组合,其值能唯一地标识表中的每一行.这样的一列或多列称为表的主键,通过它可强制表的实体完整性.当创建或更改表时可通过定义 PRIMARY KEY约束来创建主键.一个 ...

  4. 数据库主键到底是用自增长(INT)好还是UUID好

    其实针对使用自增长还是UUID,大家讨论最多的就是速度和存储空间,这里我加入了安全性和分布式,具体对比如下: 使用自增长做主键的优点:1.很小的数据存储空间2.性能最好3.容易记忆使用自增长做主键的缺 ...

  5. 使用Hashids来保护你的数据库主键

    为什么要保护数据库主键? 数据库主键一般是有序自增主键,极易被爬虫抓取数据,作为应用开发者,这是不应该的,你辛辛苦苦收集的数据转眼之间被其他人给抓取了,是不是很大的损失? Hashids的介绍 gen ...

  6. oracle手工生成AWR报告方法记录

    AWR(Automatic Workload Repository)报告是我们进行日常数据库性能评定.问题SQL发现的重要手段.熟练掌握AWR报告,是做好开发.运维DBA工作的重要基本功. AWR报告 ...

  7. 手工生成AWR报告方法记录

    AWR(Automatic Workload Repository)报告是我们进行日常数据库性能评定.问题SQL发现的重要手段.熟练掌握AWR报告,是做好开发.运维DBA工作的重要基本功. AWR报告 ...

  8. Mysql数据库主键,外键,索引概述

    主键: 主键是数据表的唯一索引,比如学生表里有学号和姓名,姓名可能有重名的,但学号确是唯一的,你要从学生表中搜索一条纪录如查找一个人,就只能根据学号去查找,这才能找出唯一的一个,这就是主键;如:id ...

  9. 数据库主键ID生成策略

    前言: 系统唯一ID是我们在设计一个系统的时候常常会遇见的问题,下面介绍一些常见的ID生成策略. Sequence ID UUID GUID COMB Snowflake 最开始的自增ID为了实现分库 ...

随机推荐

  1. C51数据类型

  2. springboot-数据库

    Spring-data-jpa jpa定义了一系列持久化的标准,比如hibernate就实现了这一标准. Springboot 的jpa就是hibernate的整合. 在pom文件中增加配置: < ...

  3. 学好 Python 的 11 个优秀资源

    Python是目前最流行.最易学最强大的编程语言之一,无论你是新手还是老鸟,无论是用于机器学习还是web开发(Pinterest就是案例),Python都是一件利器.此外,Python不但人气日益高涨 ...

  4. windows10 搜索桌面搜索功能失效的解决

    windows桌面的搜索框用起来很方便,很多时候直接把不常用的程序的快捷方式删掉,直接从搜索框搜索就可以,但是这两天突然不能用了,今天晚上找了一下原因,终于弄好了. 参考知乎上面的陈滔滔的方法: ht ...

  5. 【P2564】生日礼物(单调队列)

    这个题看上去状态比较多,实际上由于题目的输出需要,又因为是一个线性的结构,所以我们可以有一些操作. 这么想,如果我们有了一个满足条件的区间,此时我们缩减左端点,然后判断此时是否还是满足,满足就继续缩减 ...

  6. C#遍历指定文件夹中的所有文件

    DirectoryInfo TheFolder=new DirectoryInfo(folderFullName);//遍历文件夹foreach(DirectoryInfo NextFolder in ...

  7. web应用路径问题(相对路径,绝对路径,动态获取路径)

    1.相对路径和绝对路径 绝对路径:以 “ / ” 开头的路径,是完整的路径. 相对路径:不以 “ / ” 开头的路径,是相对于当前web资源目录的路径. 在绝对路径中, “ / ” 的含义有两种解释: ...

  8. VC 写注册表

    BOOL Running() { HKEY hKey; LPCTSTR strRegPath = L"SOFTWARE\\Microsoft\\Windows\\CurrentVersion ...

  9. shell学习之杂项

    ? 表示任意一个字符. > 重写 >> 追加 &> 将错误信息一并写入 Ctrl+Z 暂停 fg 恢复 jobs 查看所有已暂停任务 bg 丢到后台 env 查看系统环 ...

  10. pandas通过字典生成dataframe

    1.将一个字典输入: 该字典必须满足:value是一个list类型的元素,且每一个key对应的value长度都相同: (以该字典的key为columns) >>> import pa ...