web-dev-qa-db-fra.com

Les différences entre les stratégies GeneratedValue

Dans la Doctrine docs ils mentionnent qu'il existe plusieurs stratégies différentes pour l'annotation @GeneratedValue:

  • AUTO
  • SEQUENCE
  • TABLE
  • IDENTITY
  • UUID
  • CUSTOM
  • NONE

Quelqu'un pourrait-il expliquer les différences entre toutes les stratégies?

43
superhero

Vérifiez la dernière documentation de la doctrine

Voici un résumé: La liste des stratégies de génération possibles:

AUTO (par défaut): indique à Doctrine de choisir la stratégie préférée par la plateforme de base de données utilisée. Les stratégies préférées sont IDENTITY pour MySQL, SQLite et MsSQL et SEQUENCE pour Oracle et PostgreSQL. Cette stratégie offre une portabilité complète.

SEQUENCE: Dit à Doctrine d'utiliser une séquence de base de données pour la génération ID. Cette stratégie n'offre pas actuellement une portabilité complète. Les séquences sont prises en charge par Oracle et PostgreSql.

IDENTITY: Indique à Doctrine d'utiliser des colonnes d'identité spéciales dans la base de données qui génèrent une valeur lors de l'insertion d'une ligne. Cette stratégie n'offre pas actuellement une portabilité complète et est prise en charge par les plates-formes suivantes: 

  • MySQL/SQLite => AUTO_INCREMENT
  • MSSQL => IDENTITY 
  • PostgreSQL => SERIAL

TABLE: Dit à Doctrine d'utiliser une table séparée pour la génération ID. Cette stratégie offre une portabilité complète. _ {Cette stratégie n'est pas encore implémentée! _

NONE: Indique à Doctrine que les identifiants sont attribués et donc générés par votre code. L'affectation doit avoir lieu avant qu'une nouvelle entité soit transmise à EntityManager # persist. NONE équivaut à laisser le @GeneratedValue entièrement.

DEPUIS LA VERSION 2.3:

UUID: Indique à Doctrine d'utiliser le générateur d'identificateurs universels uniques intégré. Cette stratégie offre une portabilité complète.

74
BADAOUI Mohamed

Bien sûr, la réponse acceptée est correcte, mais il faut une mineure update comme suit:

Selon la section Annotation de la documentation :

Cette annotation est facultatif et n'a de sens que lorsque est utilisé avec @Id . Si cette annotation n'est pas spécifiée avec @Id, la stratégie NONE est utilisée par défaut.

L'attribut de stratégie est facultatif.

Selon la section Basic Mapping de la documentation :

SEQUENCE: Dit à Doctrine d'utiliser une séquence de base de données pour la génération d'un ID. Cette stratégie n'offre pas actuellement une portabilité complète. Les séquences sont prises en charge par Oracle, PostgreSql et SQL Anywhere.

IDENTITY: Dit à Doctrine d'utiliser des colonnes d'identité spéciales dans la base de données qui génèrent une valeur lors de l'insertion d'une ligne. Cette stratégie n'offre pas actuellement une portabilité complète et est prise en charge par les plates-formes suivantes: 

  • MySQL/SQLite/SQL Anywhere (AUTO_INCREMENT)
  • MSSQL (IDENTITY)
  • PostgreSQL (SERIAL).

Vote négatif

En ce qui concerne le vote négatif donné par quelqu'un, il convient de noter que SQL Anywhere a été ajouté et que la réponse acceptée nécessite une mineure update.

1
Trix

Du point de vue d'un programmeur, ils obtiennent tous le même résultat: fournir une valeur UNIQUE pour le champ de clé primaire. Strictement parlant, deux autres conditions sont également remplies, à savoir: la clé doit également être obligatoire et non nul .

Les seules différences résident dans les implémentations internes qui fournissent la valeur de clé primaire. De plus, certains facteurs de performance et de compatibilité des bases de données doivent également être pris en compte. Différentes bases de données prennent en charge différentes stratégies.

Le plus simple à comprendre est SEQUENCE et c’est aussi généralement celui qui offre le meilleur avantage en termes de performances. Ici, la base de données maintient une séquence interne dont nextval est accessible par un appel SQL supplémentaire, comme illustré ci-dessous:

SELECT nextval ('hibernate_sequence')

La valeur suivante est allouée lors de l'insertion de chaque nouvelle ligne. Malgré l'appel SQL supplémentaire, l'impact sur les performances est négligeable. Avec SEQUENCE, il est possible de spécifier la valeur initiale (la valeur par défaut est 1) ainsi que la taille d'allocation (valeur par défaut = 50) à l'aide de l'annotation @SequenceGenerator:

@SequenceGenerator(name="seq", initialValue=1, allocationSize=100)

La stratégie IDENTITY repose sur la base de données pour générer la clé primaire en conservant une colonne supplémentaire dans la table dont la valeur suivante est automatiquement générée chaque fois qu'une nouvelle ligne est insérée. Un générateur d'identité distinct est requis pour chaque hiérarchie de types.

La stratégie TABLE repose sur une table distincte pour stocker et mettre à jour la séquence à chaque nouvelle insertion de ligne. Il utilise des verrous pessimistes pour maintenir la séquence et constitue donc la stratégie la plus lente de toutes ces options. Il peut être intéressant de noter qu’une annotation @TableGenerator peut être utilisée pour spécifier le nom du générateur, le nom de la table et le schéma pour cette stratégie:

@TableGenerator(name="book_generator", table="id_generator", schema="bookstore")

Avec l'option UUID, le fournisseur de persistance (par exemple, Hibernate) génère un ID universellement unique sous la forme: '8dd5f315-9788-4d00-87bb-10eed9eff566' . Pour sélectionner cette option, appliquez simplement l'annotation @GeneratedValue au-dessus d'une déclaration de champ dont le type de données est UUID; par exemple:

@Entity
public class UUIDDemo {

    @Id
    @GeneratedValue
    private UUID uuid;

    // ...
}

Enfin, la stratégie AUTO est la stratégie par défaut et avec cette option, le fournisseur de persistance sélectionne la stratégie optimale pour la base de données utilisée.

0
IqbalHamid