實現唯一標識符生成的最佳實踐

在軟件系統中,唯一標識符是非常重要的。一個唯一標識符是一個用來標識一個實體或對象的字符串或數字。比如,我們的用戶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/zh-hk/n/144212.html

(0)
打賞 微信掃一掃 微信掃一掃 支付寶掃一掃 支付寶掃一掃
FIGF的頭像FIGF
上一篇 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

發表回復

登錄後才能評論