Retour au Blog

Prendre INT, UUI ou ULID pour un index de base de données ?

Prendre INT, UUI ou ULID pour un index de base de données ?

L'indexation est une partie essentielle de la gestion de base de données. Les index permettent d'accélérer les recherches et les jointures de tables, ce qui améliore considérablement les performances des requêtes SQL. Lorsqu'il s'agit de choisir le type d'index à utiliser pour une base de données, il existe plusieurs options, notamment INT, UUID et ULID. Dans cet article, nous allons examiner les avantages et les inconvénients de chaque option et comment choisir celle qui convient le mieux à votre base de données.

INT

Le type d'index INT est l'un des types les plus couramment utilisés dans les bases de données. INT signifie "entier" et est souvent utilisé pour stocker des valeurs numériques dans une base de données. Lorsqu'il est utilisé comme index, INT peut accélérer considérablement les recherches et les jointures de tables, car les valeurs numériques sont souvent triées dans un ordre naturel.

Le principal avantage d'utiliser INT comme index est la vitesse car les entiers sont des types de données primitifs, et ils sont ultra rapides à manipuler. Ils sont aussi très compacts, prennent peu de mémoire dans la base de données. Cela peut être un avantage important si la base de données est très volumineuse.

Cependant, il existe quelques inconvénients à l'utilisation d'INT comme index. Tout d'abord, les index INT ont une limite de taille. Dans MySQL, par exemple, un index INT ne peut pas stocker de valeurs supérieures à 2^32-1. Si vous devez stocker des valeurs plus grandes, vous devrez utiliser BIGINT. Cela demande un peu de travail à migrer. Vous pouvez retrouver un article à ce sujet. (Vous êtes arrivés au max des int)

UUID

UUID signifie "Universal Unique Identifier"  la RFC 4122 et est un type de données couramment utilisé dans les bases de données modernes. Les UUID sont des chaînes de caractères aléatoires qui sont généralement stockées sous forme de texte. Les UUID sont souvent utilisés comme clés primaires dans les bases de données distribuées, car ils garantissent l'unicité des données même lorsque les données sont stockées sur plusieurs serveurs.

Les UUID sont des identifiants de 32 chiffres hexadécimaux générés par un algorithme qui le rend unique dans l'univers connu. Certains systèmes font référence à l'UUID en tant que GUID (identificateur global unique).

L'un des avantages de l'utilisation de UUID comme index est qu'ils sont universellement uniques. Ce qui est bien pratique et même particulièrement adapté pour des bases de données distribuées.

Cependant, il y a des inconvénients à l'utilisation de UUID comme index. Tout d'abord, les UUID sont des types de données plus complexes que les entiers, ce qui signifie qu'ils sont plus lents à manipuler. Les UUID sont également plus volumineux que les index INT, ce qui peut poser des problèmes si la base de données est très volumineuse.

Voici quelques exemples de valeurs UUID:

40e6215d-b5c6-4896-987c-f30f3678f608
6ecd8c99-4036-403d-bf84-cf8400f67836
3f333df6-90a4-4fda-8dd3-9485d27cee36

Si vous souhaitez aller plus loin dans son intégration, vous pouvez lire la doc de Symfony. Vous y apprendrez comment générer un UUID, comment l'intégrer dans votre base de données avec doctrine et l'utiliser comme un index.

ULID

ULID signifie "Universally Unique Lexicographically Sortable Identifier". C'est une évolution des UUID qui ajoute un ordre lexicographique aux identifiants. Les ULID sont des identifiants aléatoires qui sont également triables dans l'ordre chronologique car la notion de temps intervient dans la génération de l'identifiant. Les ULID sont souvent utilisés dans les applications distribuées, où les identifiants doivent être uniques sur plusieurs machines. Notez que ces UUID ne sont pas du texte, mais sont des types natifs.

Les ULID offrent une très bonne garantie contre les collisions d'identifiants, ce qui les rend très fiables pour les applications critiques. Ils sont également plus efficaces que les UUID en termes de stockage, car ils ne nécessitent que 16 octets pour stocker un identifiant.

Cependant, les ULID sont plus lents que les INT en termes de jointures de tables, car les ULID sont stockés sous forme de chaînes de caractères. De plus, ils peuvent être plus difficiles à lire et à comprendre que les nombres entiers.

Il est composé de deux nombres codés en base32, d'un horodatage UNIX suivi d'un nombre aléatoire.

   01AN4Z07BY      79KA1307SR9X4MV3
   |-------------|    |----------------|
     Timestamp          Randomness
         48bits                   80bits

ULID: le meilleur des deux saveurs ensemble

  • Étant donné que la première partie de uuid est un horodatage, il peut être facilement trié.
  • La deuxième partie aléatoire le rend idéal pour le système distribué sur plusieurs instances.
  • Aucune indexation supplémentaire n'est requise et aucune sortie originale lorsque vous souhaitez utiliser la pagination.
  • Toujours évolutif comme UUID.
  • Difficile de deviner, voire impossible les identifiants d'une ressource. (Au moins manuellement).

De la même manière, vous trouverez ici la documentation pour comprendre son intégration dans votre code.

Et comment migrer vers UUID ou vers ULID ?

Imaginons que nous ayons une entité Enfant, et une entité Parent, et que dans la base de données, l'enfant a le parent_id dans ses colonnes.

Dans les annotations Doctrine, vous prenez comme dans la doc, pour créer une colonne new_id dans la table enfant. Appelons la new_parent_id et new_id

#[ORM\Id]

#[ORM\Column(type: UlidType::NAME, unique: true)]

#[ORM\GeneratedValue(strategy: 'CUSTOM')]    

#[ORM\CustomIdGenerator(class: 'doctrine.ulid_generator')]

private ?Ulid $id;

public function getId(): ?Ulid {

    return $this->id;  

}

  1. Ensuite, vous pourrez avec une commande générer pour chaque ligne Parent les nouveaux ulid, avec l'objet new Ulid(); et placer cette même valeur chez les enfants dans new_parent_id
  2. Puis vous pourrez ajouter une clé externe sql entre new_parent_id et new _id.
  3. Et une fois fait, vous pourrez supprimer les id des parents et les parent_id des enfants, en ayant au préalable supprimé la clé externe liant les deux, et la clé primaire sur l'id Parent
  4. Ensuite vous pourrez ajouter la clé primaire sur le new_id
  5. Et enfin, vous pourrez renommer vos colonnes pour que tout revienne dans l'ordre dans votre application
  6. Si vous avez un soucis dans vos tests, ou si vous avez besoin d'un accompagnement, pensez à nous contacter !

Conclusion

En fait, cela dépend surtout de vos besoins en termes de développement. La migration d'un système à un autre est faisable donc vous gardez toujours cette possibilité si vous souhaitez changer de système.

Symfony quant à lui, a décidé de faire le pas, d'intégrer uuid et ulid au sein de ses types doctrine dont le composant est ici, et disponible également en contrainte pour vos formulaires.

Selon vos besoins, Efficience IT sait intégrer un système et un autre, n'hésitez pas à nous contacter en cas de besoin d'accompagnement ou d'expertise sur ces sujets.

Contactez-nous !
Je veux en savoir plus !