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 !