Maison  >  Article  >  php教程  >  Algorithme SnowFlake pour générer des identifiants uniques en PHP

Algorithme SnowFlake pour générer des identifiants uniques en PHP

高洛峰
高洛峰original
2016-12-28 15:33:501363parcourir

Avant-propos : j'ai récemment eu besoin de créer un système CMS, étant donné que les fonctions sont relativement simples et que les exigences sont flexibles, j'ai abandonné un système mature comme WP et j'en ai construit moi-même un relativement simple. L'URL de la page de détails de l'article doit être transformée dans un format d'URL pseudo-statique, c'est-à-dire que xxx.html xxx a envisagé d'utiliser directement une clé primaire auto-incrémentée, mais je pense que cela exposerait le nombre d'articles. a dit que la valeur initiale peut être définie plus haut, mais c'est toujours possible. Le nombre d'articles sur une période donnée est calculé en fonction de la différence d'ID, donc un algorithme capable de générer des ID uniques est nécessaire.

Les méthodes considérées

utilisent directement l'horodatage, ou une série de méthodes qui en dérivent

Le propre uuid de MySQL

Les deux ci-dessus méthodes peuvent être trouvées, donc je n'expliquerai pas trop

Au final, j'ai choisi l'algorithme SnowFlake de Twitter

L'avantage de cet algorithme est très simple et il peut générer environ 4 millions de différents 16 messages par seconde ID numérique (décimal)

Le principe est très simple

L'ID est composé de 64 bits

Le premier bit est vacant

41. le bit est utilisé pour stocker les millisecondes Horodatage du niveau

10 bits sont utilisés pour stocker l'ID de la machine

12 bits sont utilisés pour stocker l'ID d'incrémentation automatique

Sauf pour le plus élevé bit marqué comme indisponible, les trois groupes de bits restants sont occupés. Tous peuvent être flottants, en fonction des besoins spécifiques de l'entreprise. Par défaut, l'horodatage de 41 bits peut prendre en charge l'utilisation de cet algorithme jusqu'en 2082, l'ID de machine de travail de 10 bits peut prendre en charge 1023 machines et le numéro de série prend en charge 1 milliseconde pour générer 4095 ID de séquence à incrémentation automatique.
Ce qui suit est le code source PHP

<?php
namespace App\Services;
 
abstract class Particle {
  const EPOCH = 1479533469598;
  const max12bit = 4095;
  const max41bit = 1099511627775;
 
  static $machineId = null;
 
  public static function machineId($mId = 0) {
    self::$machineId = $mId;
  }
 
  public static function generateParticle() {
    /*
    * Time - 42 bits
    */
    $time = floor(microtime(true) * 1000);
 
    /*
    * Substract custom epoch from current time
    */
    $time -= self::EPOCH;
 
    /*
    * Create a base and add time to it
    */
    $base = decbin(self::max41bit + $time);
 
 
    /*
    * Configured machine id - 10 bits - up to 1024 machines
    */
    if(!self::$machineId) {
      $machineid = self::$machineId;
    } else {
      $machineid = str_pad(decbin(self::$machineId), 10, "0", STR_PAD_LEFT);
    }
     
    /*
    * sequence number - 12 bits - up to 4096 random numbers per machine
    */
    $random = str_pad(decbin(mt_rand(0, self::max12bit)), 12, "0", STR_PAD_LEFT);
 
    /*
    * Pack
    */
    $base = $base.$machineid.$random;
 
    /*
    * Return unique time id no
    */
    return bindec($base);
  }
 
  public static function timeFromParticle($particle) {
    /*
    * Return time
    */
    return bindec(substr(decbin($particle),0,41)) - self::max41bit + self::EPOCH;
  }
}
 
?>

La méthode d'appel est la suivante

Particle::generateParticle($machineId);//生成ID
Particle::timeFromParticle($particle);//反向计算时间戳

J'ai apporté des améliorations ici Si l'ID de la machine est passé à 0, le 10. les bits seront supprimés car parfois nous n'en avons pas besoin. Il y a tellement d'identifiants

Pour plus d'articles liés à l'algorithme SnowFlake pour générer des identifiants uniques en PHP, veuillez faire attention au site Web chinois de PHP !

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn