实现唯一标识符生成的最佳实践

在软件系统中,唯一标识符是非常重要的。一个唯一标识符是一个用来标识一个实体或对象的字符串或数字。比如,我们的用户ID、订单号等都需要是唯一的。在本文中,我们将探讨一些关于生成唯一标识符的最佳实践。

一、UUID

UUID(通用唯一标识符)是一个用于标识信息的128位数字,它的唯一性和随机性很高。它不需要像序列号那样在多台计算机之间进行同步,也不需要像GUID那样需要Windows API的支持。因此,它是一种生成唯一标识符的很好选择。

<?php
function generateUUID() {
    return sprintf('%04x%04x-%04x-%04x-%04x-%04x%04x%04x',
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff),
        mt_rand(0, 0x0fff) | 0x4000,
        mt_rand(0, 0x3fff) | 0x8000,
        mt_rand(0, 0xffff), mt_rand(0, 0xffff), mt_rand(0, 0xffff)
    );
}
?>

这个generateUUID函数生成一个UUID。注意,它使用了mt_rand,这是一个更好的随机数生成器。如果你在旧的PHP版本中使用rand,你可能会得到两个完全相同的UUID。

二、Snowflake算法

Snowflake是由Twitter发明的算法,它可以在分布式系统中生成唯一的ID,是生成分布式唯一ID的一种解决方案。它的核心思想是将ID分解成多个部分,通过对每个部分的合理设计来保证生成的所有ID全局唯一。Snowflake IDs由以下几个部分组成:

  • 一个时间戳(毫秒级,41位)
  • 一个机器ID(10位)
  • 一个序列号(12位)
<?php
class Snowflake
{
  const EPOCH = 1593649964177;
  const MACHINE_ID = 1;

  private static $lastTimestamp = -1;
  private static $sequence = 0;

  public static function generateId()
  {
    $timestamp = self::getUnixTimestampInMilliseconds();

    if (self::$lastTimestamp === $timestamp) {
      self::$sequence = (self::$sequence + 1) & 4095;

      if (self::$sequence === 0) {
        $timestamp = self::waitNextMillis($timestamp);
      }
    } else {
      self::$sequence = 0;
    }

    $lastTimestamp = $timestamp;

    return ((string) ($timestamp - self::EPOCH) << 22)
      | ((string) (self::MACHINE_ID << 12))
      | (string) self::$sequence;
  }

  private static function getUnixTimestampInMilliseconds()
  {
    return round(microtime(true) * 1000);
  }

  private static function waitNextMillis($timestamp)
  {
    while ($timestamp === self::$lastTimestamp) {
      $timestamp = self::getUnixTimestampInMilliseconds();
    }

    return $timestamp;
  }
}
?>

如上述代码,我们可以用Snowflake生成全局唯一标识符,可以调用Snowflake::generateId()函数来生成唯一 ID。

三、利用数据库

使用数据库自增长列的思路是最传统的方式生成QQ号、订单号等唯一编码,利用auto_increment列可以生成唯一ID。然而,使用数据库有一个明显的缺点,那就是需要和数据库进行交互,如果高并发,可能会占用数据库大量的资源。

<?php
class MysqlIdMaker
{
  private $db;

  public function __construct(mysqli $db)
  {
    $this->db = $db;
  }

  public function nextId()
  {
    $result = $this->db->query('SELECT next_id FROM sequence WHERE `key`=\'global\'');

    if (!$result || $result->num_rows fetch_assoc();
    $nextId = $row['next_id'];

    $this->db->query(
      'UPDATE sequence SET next_id=next_id+1 WHERE `key`=\'global\' AND next_id=' . $nextId
    );

    if ($this->db->affected_rows nextId();
    }

    return $nextId;
  }
}
?>

上述例子中抽象出了一个MysqlIdMaker类,通过数据库自增长列生成全局唯一ID,我们可以调用MysqlIdMaker::nextId()函数来生成下一个唯一ID。

四、结语

本文讨论了生成唯一标识符的最佳实践,包括使用UUID、Snowflake算法和使用数据库。不同的场景和需求,会有不同的选择。我们可以根据具体的场景和需求,选择合适的方法来生成唯一标识符。

原创文章,作者:FIGF,如若转载,请注明出处:https://www.506064.com/n/144212.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
FIGFFIGF
上一篇 2024-10-24 15:28
下一篇 2024-10-24 15:28

相关推荐

  • PYTHON中的标识符不区分大小写

    Python是一种非常灵活的编程语言。其中,标识符不区分大小写是Python语言的一个重要特性,在使用Python语言时,掌握这个特性可以提高编程效率。 一、标识符简介 在Pyth…

    编程 2025-04-27
  • inchikey – 化学分子的唯一标识符

    一、inchikey翻译 inchikey,也称为InChI Key,是化学结构标识符InChI(International Chemical Identifier)的一部分,被设…

    编程 2025-04-24
  • Java需要标识符的阐述

    一、标识符的概念 在Java中,标识符指的是用来标识各种变量、方法、类、接口等实体的名称。Java中标识符必须是由字母、数字、下划线和美元符号组成且可以包含任意数量的这些字符。另外…

    编程 2025-04-23
  • Oracle 00904标识符无效

    一、 什么是Oracle 00904标识符无效错误 在使用Oracle数据库时,经常会遇到00904标识符无效的错误。这个错误通常是由于SQL语句中引用了不存在的列、表、视图或者是…

    编程 2025-04-12
  • Python标识符详解

    Python是一种高级语言,被广泛应用于web开发、数据分析、机器学习等领域。Python标识符是编程中非常重要的概念,其在Python中起着诸多作用。本文将从多个方面对Pytho…

    编程 2025-01-16
  • Python标识符详解

    Python是一种高级语言,被广泛应用于web开发、数据分析、机器学习等领域。Python标识符是编程中非常重要的概念,其在Python中起着诸多作用。本文将从多个方面对Pytho…

    编程 2025-01-16
  • Python代码出错:标识符未被识别

    一、缩进问题 Python是一门强制要求缩进的语言,因此如果在程序中缺少缩进,就会引发标识符未被识别的错误。换句话说,程序中关键字、变量和函数名等标识符必须要正确地缩进,否则就无法…

    编程 2025-01-14
  • c语言中的sscanf,C语言中的标识符

    本文目录一览: 1、c语言,sscanf的用法问题,急! 2、关于c语言中sscanf的用法不懂,求指教 3、C语言 sscanf() 用法 4、c语言中关于sscanf函数的运用…

    编程 2025-01-14
  • java的保留字,java的保留字可以作为标识符使用吗

    本文目录一览: 1、在java中保留字和预定义的标识符之间没有区别? 2、保留字是java特殊的标识符正确还是错误 3、java保留字有哪些 在java中保留字和预定义的标识符之间…

    编程 2025-01-14
  • c语言提示未声明的标识符,c++语言中未定义标识符怎么解决

    本文目录一览: 1、为什么老是提示:未声明的标识符a,b,望c语言大神指教 2、C语 未声明的标识符 3、C语言中未声明标识符,可以怎样修改 4、C#的未声明标识符错误是什么原因?…

    编程 2025-01-06

发表回复

登录后才能评论