Suite

Utilisation du code d'incrémentation automatique avec compteur

Utilisation du code d'incrémentation automatique avec compteur


Je me demandais s'il était possible d'utiliser le code d'incrémentation automatique standard pour travailler sur des groupes d'enregistrements :

FeatureClass = "newFC" recs = collections.defaultdict(int) autoIncrementEXP = "autoIncrement()" expCalc = """def autoIncrement(!Group!): recs[!Group!] += 1 return recs[!Group!]" "" arcpy.CalculateField_management(FeatureClass, "Number",autoIncrementEXP,"PYTHON",expCalc)

Ainsi, au lieu d'arrêter la partie d'incrémentation automatique du script lorsqu'il atteint la fin des enregistrements, demandez-lui de créer des numéros séquentiels à l'aide de groupes de valeurs de champ si cela a du sens. Vous commenceriez par quelque chose comme leGrouperchamp ci-dessous et terminer par leNumérochamp contenant les valeurs d'incrément :

Numéro de groupe A 1 A 2 A 3 B 1 B 2 C 1 C 2 C 3 C 4 C 5

Merci pour toute idée que vous pouvez fournir.


Vous devrez transmettre la valeur de votre champ de groupe auincrémentation automatiquefonctionner maintenant, mais cela fonctionnerait:

importer des collections recs = collections.defaultdict(int) def autoIncrement(field_value): recs[field_value] += 1 return recs[field_value]

Donc quelque chose comme ça :

FeatureClass = "newFC" expCalc = "import collections

recs = collections.defaultdict(int)

def autoIncrement(field_value):
 recs[field_value] += 1
 return recs[field_value]
" arcpy .CalculateField_management(FeatureClass, "Number", "autoIncrement(!Group!)","PYTHON", expCalc)

Comment travailler avec des ID à incrémentation automatique dans SQL

Allie Dyer Bluemel

Si vous traitez des données produit (commandes, ressources, SKU, applications), vous devez probablement travailler avec identifiants auto-incrémentés, généralement en tant que clé primaire ou partie d'une clé composite. Les faire fonctionner peut être assez ennuyeux, surtout si l'on considère que les principaux dialectes SQL - Postgres, MySQL et MSSQL - gèrent tous la syntaxe de manière très différente.

Ce guide expliquera comment implémenter et utiliser des champs auto-incrémentés dans SQL, passera en revue la syntaxe des différents dialectes SQL et expliquera comment gérer des UUID plus sécurisés.


4 réponses 4

Tim, j'avais rencontré le même problème où je devais redémarrer l'identité à la valeur suivante. J'utilisais db2v9.1.

Malheureusement, il n'y a aucun moyen de spécifier automatiquement la valeur suivante. Conformément à la documentation DB2, la valeur doit être une « constante numérique ». Par conséquent, j'ai dû faire un select max(id), obtenir la valeur et la remplacer manuellement dans alter..restart stmt.

Je ne me souviens pas si j'ai essayé ceci - mais vous pouvez écrire un sp où max(id) est défini dans une variable et affecter la variable dans le fichier alter. redémarrer stmt. (Je ne peux pas essayer car je n'ai plus accès à aucune base de données db2). Je doute que ça marche quand même. (Si ça marche faites le moi savoir :))

Référence DB2 :

REDÉMARRER ou REDÉMARRER AVEC une constante numérique

Réinitialise l'état de la séquence associée à la colonne identité. Si WITH numerique-constant n'est pas spécifié, la séquence de la colonne d'identité est redémarrée à la valeur qui a été spécifiée, implicitement ou explicitement, comme valeur de départ lors de la création initiale de la colonne d'identité. La colonne doit exister dans la table spécifiée (SQLSTATE 42703) et doit déjà être définie avec l'attribut IDENTITY (SQLSTATE 42837). RESTART ne modifie pas la valeur START WITH d'origine.

La constante numérique est une constante numérique exacte qui peut être n'importe quelle valeur positive ou négative pouvant être affectée à cette colonne (SQLSTATE 42815), sans chiffres différents de zéro existant à droite de la virgule décimale (SQLSTATE 428FA). La constante numérique sera utilisée comme valeur suivante pour la colonne.


3 réponses 3

GUID est unique, donc à long terme si vous rencontrez ce scénario où vous pouvez vous joindre en utilisant simplement Guid plutôt que PK + autre champ. ex: il y a des ventes, des commandes, des ajustements et il y a du stock, au lieu de rejoindre en utilisant PK et le type de transaction, vous pouvez simplement vous joindre en utilisant Guid car il 99.9. % garanti unique.

En utilisant le GUID, vous pouvez générer le GUID à partir du code afin d'éviter d'avoir à effectuer un rappel pour obtenir un nouveau PK.

En ayant l'auto-incrémentation, vous pouvez obtenir la dernière transaction simplement en commandant l'auto-incrémentation au lieu de la date de transaction (stackoverflow en utilisant cette méthode)

Comme déjà indiqué dans les commentaires de l'autre question, cela n'a pas de sens si vous n'interrogez pas du tout en utilisant l'identifiant. Si vous utilisez uniquement les GUID, omettez l'index clusterisé et configurez simplement l'index non clusterisé sur les GUID.

Mais n'utilisez jamais les GUID en tant qu'index cluster, sauf si vous souhaitez effectuer un test de résistance sur votre sous-système d'E/S. -)

Il n'est pas rare d'avoir plusieurs clés dans une table et il n'y a fondamentalement rien de mal à cela. Si une table a plus d'une clé, le choix de la clé "primaire" est sans importance - ou seulement aussi important que vous le souhaitez.

Votre patron a raison de dire d'habitude une bonne idée pour que chaque table SQL Server soit mise en cluster. Les guides ne font pas de bons index clusterisés et lorsqu'il n'y a pas de candidat décent pour le clustering, il est parfois judicieux d'ajouter une clé entière incrémentielle pour le clustering. Ce que je pense est faux dans ce cas, c'est la suggestion que vous faites cela pour tous tableau. La sélection des clés doit être basée sur les exigences réelles et les considérations pratiques pour chaque table. Une taille unique pour toutes les solutions n'est vraiment d'aucune aide.


Utilisation du code d'incrémentation automatique avec compteur - Systèmes d'Information Géographique

Contrairement à Drupal intégré à l'identifiant de nœud à incrémentation automatique, qui est global et partagé par les nœuds de tous types, les champs série sont gérés par type de nœud. Par exemple, un champ série d'un type de nœud Facture générera un numéro séquentiel unique (commençant à 1, puis 2, etc.) dédié aux nœuds Facture.

Ce module alloue les numéros de série de manière atomique, en gardant les valeurs de série uniques même si plusieurs nœuds sont créés simultanément.

Cette troisième partie du tutoriel écrit par l'auteur contient des fonctions comme la boucle while, la boucle do-while, la boucle for, la boucle foreach, les variables de tableau, les opérateurs d'incrémentation et de décrémentation automatiques. Toutes les fonctions sont démontrées facilement.

CodeExpress For Delphi est un ensemble de plus de 20 outils IDE (experts) conçus pour accélérer le processus de développement. Il est compatible avec la plupart des experts tiers célèbres, tels que Coderush (5.0/6.0) , GExperts , VSSConnexion , etc. Capacités : ExpertsRun.

CodeExpress For Delphi est un ensemble de plus de 20 outils IDE (experts) conçus pour accélérer le processus de développement. Il est compatible avec la plupart des experts tiers célèbres, tels que Coderush (5.0/6.0) , GExperts , VSSConnexion , etc. Capacités : ExpertsRun.

La fenêtre d'agrandissement automatique est un script simple qui agrandit automatiquement la fenêtre du navigateur lorsqu'elle est chargée dans une page Web.

"PS Auto Sitemap" est un plugin qui génère automatiquement une page de plan de site à partir de votre site WordPress.

Il est facile à installer pour les débutants et facile à personnaliser pour les experts. Il peut modifier les paramètres d'affichage des listes.

Le rôle d'attribution automatique sert trois objectifs principaux. La première consiste à fournir une attribution automatique des rôles lorsqu'un nouveau compte est créé. La seconde est de permettre à l'utilisateur final de choisir son ou ses propres rôles lors de la création des siens.

Crée des formulaires d'inscription en bloc pour les rôles spécifiés lors de l'utilisation de l'« attribution automatique de rôle » pour l'inscription. Si vous souhaitez fournir vos formulaires d'inscription à partir des pages d'attribution automatique de rôle sous forme de blocs à vos utilisateurs, ce module est la solution. Tout.

Un plugin de marquage automatique conçu pour inclure automatiquement des symboles boursiers valides en tant que balises, ainsi que leur nom officiel.

Le plugin fonctionne en détectant les symboles $ticker tels que $appl ou $gm et en les convertissant en une balise, avec un.

! Contenu dynamique :: Rotation automatique du contenu du site Web ! est compatible multi-plateforme. psDynamic est conçu pour faire pivoter le contenu de votre site automatiquement - dynamiquement. Les webmasters passent beaucoup de temps à mettre à jour le contenu de leurs pages pour faire des choses.

20/20 Auto Gallery est un script ASP adapté à la mise en œuvre d'un système de commerce électronique pour vendre des véhicules de manière dynamique. Prend en charge un nombre illimité de formulaires pour gérer individuellement les concessionnaires, les propriétaires de voitures, les acheteurs et les sponsors. Permet à quiconque de rechercher des produits avec plusieurs.

Ace Auto Reload est un script compatible multi-plateforme qui recharge automatiquement une page à un intervalle spécifié.

ASP.NET Auto Email est un composant de messagerie spécialement conçu pour générer des formulaires de courrier électronique sur les sites Web des utilisateurs et fournit également toutes les fonctionnalités permettant de générer des systèmes de messagerie sur le site Web des utilisateurs. Il a plusieurs attractifs.

Un outil facile à utiliser pour les concessionnaires automobiles et les webmasters qui gèrent des sites de petites annonces automobiles. Ajoutez et modifiez vos annonces via une interface Web et personnalisez facilement les champs et la conception des annonces automatiques. Définissez les droits d'accès pour vos utilisateurs et publiez en appuyant sur a.

La fenêtre contextuelle à centrage automatique est un JavaScript qui peut créer et afficher une fenêtre qui s'ouvre et s'ajuste en détectant les dimensions de la fenêtre qui l'appelle ou de l'écran et se centre automatiquement. Idéal si l'utilisateur n'a pas allumé.

Le site de petites annonces automobiles permet aux acheteurs de voitures de parcourir gratuitement les propriétés disponibles. Les listes de propriétés sont détaillées avec des caractéristiques, des photos, des informations sur les revendeurs/individus et des itinéraires liés à MapQuest. / Concessionnaires et voiture individuelle.

Les voitures d'occasion Auto express sont à la fois compatibles Unix et Linux. Vous pouvez rechercher et annoncer des véhicules gratuitement.

Auto Form est un tutoriel qui permet aux utilisateurs de créer automatiquement un formulaire HTML sur leurs sites Web. Ce didacticiel décrit également la création de formulaires automatiques. La procédure de ce tutoriel est décrite en détail avec un exemple. Ce tutoriel.

L'affichage automatique des images créera une page html temporaire à la volée pouvant afficher des bannières publicitaires, des boutons, du texte et d'autres objets que vous pourriez vouloir inclure. Il peut également changer la couleur de fond !

Le gestionnaire de liste automatique est compatible avec plusieurs plates-formes. Solution complète de gestion des listes de véhicules, construite sur les petites annonces d'Esvon, personnalisée et prête à l'emploi pour votre site Web automobile, votre site de voitures spécialisées ou votre section d'inventaire automobile.

Tous les fichiers et téléchargements gratuits sont la propriété de leurs propriétaires respectifs. Nous ne fournissons aucune version piratée, craquée, illégale ou piratée des scripts, codes, téléchargements de composants. Tous les fichiers sont téléchargés depuis le site Web des éditeurs, nos serveurs de fichiers ou nos miroirs de téléchargement. Toujours vérifier les fichiers antivirus téléchargés à partir du Web, spécialement zip, rar, exe, version d'essai, versions complètes, etc. Les liens de téléchargement depuis rapidshare, depositfiles, megaupload, etc. ne sont pas publiés.


Le plus grand mythe lors de la conception d'applications est que vous n'êtes autorisé à avoir qu'une seule clé.

Ayez plusieurs clés, allez-y et faites-le. Votre application est autorisée à avoir une clé primaire différente de celle de votre base de données. Je sais que cela peut sembler étrange au début, mais vous obtenez le meilleur des deux mondes en suivant cette voie.

Les UUID ont de nombreux avantages, mais font généralement des index cluster horribles. Ainsi, vous pouvez simplement utiliser un int comme index PK/cluster dans votre base de données, mais également avoir un autre index unique sur votre colonne d'identifiant externe. Cela peut nécessiter une jointure supplémentaire pour de nombreuses requêtes, mais ce n'est pas grave, car dans les bases de données relationnelles, les jointures internes sur les colonnes int auto-incrémentées sont extrêmement rapides.

Un autre avantage de cette approche à double clé est la possibilité de répartir facilement géographiquement votre base de données. Étant donné que les UUID sont globalement uniques, deux bases de données séparées géographiquement n'auront pas à ralentir la coordination de leurs clés, tant que vous vous assurez que la DB int PK ne quitte jamais la base de données et n'est pas utilisée par le service rest.

Voici un autre point, votre identifiant externe n'a même pas besoin d'être un UUID, il peut également y avoir d'autres options.

L'externe peut également être un entier, ou une chaîne, ou la clé naturelle de l'entité quoi que ce soit. Cela rendrait vos URL moins moche qu'un UUID

N'ayez pas peur d'avoir plusieurs clés, cacher votre clé DB aux autres consommateurs d'API est une bonne chose.

Le plus grand nombre de clés que j'ai jamais utilisées a été de deux, mais dans la bonne situation, je peux imaginer que quatre soient justifiées (clé DB, clé d'application, clé métier, clé client)

Il ne sert à rien d'avoir deux clés primaires.

Non ils ne sont pas. Arrêtez de vous soucier des nombres obscurs comme les pages et la fragmentation et faites quelques tests.

Dans tous les cas, si vous avez tous les deux et indexez l'UUID alors vous avez le même problème

En tout cas si vous avez tous les deux c'est définitivement plus gros

  1. Les UUID sont moches. Eh bien, vous ne voudriez pas en taper un, mais voulez-vous taper 13243444444431 ou Gdih£$%d1 ? si vous avez besoin d'une jolie URL pour le référencement ou pour une autre raison, il existe de meilleures solutions que d'ajouter plus de colonnes d'identification à votre table.

Les ints séquentiels ont des problèmes majeurs qui sont résolus avec les UUID, dont l'un consiste à deviner le prochain identifiant ou le nombre de commandes que vous avez prises.

Ce sont de réelles préoccupations de sécurité et commerciales et devraient, à elles seules, suffire à justifier de ne pas utiliser du tout les ints auto_inc.

N'essayez pas de corriger les problèmes avec des solutions piratées, remplacez-les simplement par la norme de l'industrie.

Si votre seul objectif est de masquer la clé primaire de votre interface REST, je vous le déconseille. Au lieu de cela, crypter vos clés serait une bonne solution pour cela.

Le problème avec l'utilisation des clés primaires comme identifiant public pour votre entité est que vous divulguez les détails de votre solution de stockage de données à vos clients (et par conséquent, tout au long de votre application). Cela peut avoir des implications sur la sécurité, ainsi que signifier que les modifications apportées au backend de vos applications peuvent être plus compliquées. Les UUID résolvent en partie ce problème en fournissant un identifiant alternatif entièrement indépendant de la technologie de votre base de données.

Les UUID ne sont qu'une solution à ce problème, avec l'avantage inhérent qu'à toutes fins pratiques, ils sont garantis uniques. Cependant, si vous vous êtes efforcé d'utiliser autre chose que la clé primaire comme identifiant, vous constaterez peut-être que l'utilisation d'une chaîne arbitraire ou simplement d'un autre identifiant numérique fournit des URL plus agréables.

Une autre considération est que si vous utilisez des GUID/UUID comme identifiant public pour votre entité, vous aurez probablement besoin d'une sorte d'index pour eux. Étant donné qu'ils occupent beaucoup plus d'espace que les entiers, votre index sera beaucoup plus grand.

C'est un problème courant que j'ai moi-même rencontré plusieurs fois. J'ai fini par emprunter la route "utilisez simplement un numéro pour l'identifiant", ce qui signifie que ce n'est pas aussi laid pour les clients de voir ces UUID.

Le seul autre moyen, comme vous l'avez déjà évoqué, est de masquer cet identifiant derrière une sorte de requête, à laquelle vous devrez fournir des paramètres afin de récupérer le bon UUID, cependant, cela signifie que vous pouvez aussi bien utiliser ceux-ci paramètres comme clé primaire pour la table !

Je dirais qu'il n'y a aucun moyen de faire du REST (c'est-à-dire le transfert d'état d'un modèle) sans pouvoir identifier l'instance que vous êtes en train de REST, vous aurez donc besoin d'une clé, quelle que soit la forme que prend cette clé.

Si votre préoccupation est due à la sécurité, je vois le problème tel qu'il est dans le code de validation des messages de votre serveur, pas que le client voit les identifiants. Si un pirate veut charger des données de votre table, il n'aura pas besoin d'identifiants pour le faire. Et vous devriez également valider les demandes, afin qu'aucun élément douteux ne parvienne de toute façon à vos couches métier, c'est-à-dire l'authentification et l'autorisation des messages.

Pour revenir à ta question :

"accessible via REST, donc je ne veux pas exposer la clé primaire"

Je pense que c'est le contraire, vous DEVEZ exposer la clé primaire pour faire REST.

EDIT : comme l'a souligné @Murph, cela donne en fait une meilleure chance aux attaquants si vous donnez des identifiants au client - je ne le savais pas. Il se peut que d'autres réponses ici (je regarde la plus courte disant de crypter la clé) soient plus adaptées à votre situation. Edit 2: Semble que les UUID ne soient pas plus sûrs que les ints.


17 réponses 17

Ce n'est jamais une mauvaise idée d'avoir un identifiant de ligne unique garanti. Je suppose que je ne devrais pas dire jamais &ndash, mais allons-y avec l'écrasante majorité du temps, c'est une bonne idée.

Les inconvénients potentiels théoriques incluent un index supplémentaire à maintenir et un espace de stockage supplémentaire utilisé. Cela n'a jamais été une raison suffisante pour moi de ne pas en utiliser un.

TLDR : Utilisez des UUID au lieu de l'auto-incrémentation, si vous ne disposez pas déjà d'un moyen unique d'identifier chaque ligne.

Je ne suis pas d'accord avec toutes les réponses précédentes. Il existe de nombreuses raisons pour lesquelles c'est une mauvaise idée d'ajouter un champ d'incrémentation automatique dans toutes les tables.

Si vous avez une table où il n'y a pas de clés évidentes, un champ à incrémentation automatique semble être une bonne idée. Après tout, vous ne voulez pas sélectionner * du blog où body = '[10000 character string]' . Vous préférez sélectionner * dans le blog où >. Je dirais que dans la plupart de ces cas, ce que vous voulez vraiment, c'est un identifiant unique et non un identifiant unique séquentiel. Vous voudrez probablement utiliser un identifiant universellement unique à la place.

Il existe des fonctions dans la plupart des bases de données pour générer des identifiants uniques aléatoires ( uuid dans mysql, postgres. newid dans mssql). Ceux-ci vous permettent de générer des données dans plusieurs bases de données, sur différentes machines, à tout moment, sans connexion réseau entre elles, tout en fusionnant les données sans conflit. Cela vous permet de configurer plus facilement plusieurs serveurs et même des centres de données, comme par exemple avec des microservices.

Cela évite également aux attaquants de deviner les URL des pages auxquelles ils ne devraient pas avoir accès. S'il y a un https://example.com/user/1263, il y a probablement aussi un https://example.com/user/1262. Cela pourrait permettre l'automatisation d'un exploit de sécurité dans la page de profil de l'utilisateur.

Il existe également de nombreux cas où une colonne uuid est inutile voire nuisible. Disons que vous avez un réseau social. Il y a une table des utilisateurs et une table des amis. La table friends contient deux colonnes d'ID utilisateur et un champ d'auto-incrémentation. Vous voulez que 3 soient amis avec 5 , vous insérez donc 3,5 dans la base de données. La base de données ajoute un identifiant auto-incrémenté et stocke 1,3,5 . D'une manière ou d'une autre, l'utilisateur 3 clique à nouveau sur le bouton "ajouter un ami". Vous insérez à nouveau 3,5 dans la base de données, la base de données ajoute un identifiant auto-incrémenté et insère 2,3,5 . Mais maintenant, 3 et 5 sont amis deux fois ! C'est une perte d'espace, et si vous y réfléchissez, la colonne d'auto-incrémentation l'est aussi. Tout ce dont vous avez besoin pour voir si a et b sont amis, c'est de sélectionner pour la ligne avec ces deux valeurs. Ils constituent, ensemble, un identifiant de ligne unique. (Vous voudriez probablement écrire une logique pour vous assurer que 3,5 et 5,3 sont dédupliqués.)

Il existe encore des cas où les identifiants séquentiels peuvent être utiles, comme lors de la création d'un raccourcisseur d'URL, mais la plupart du temps (et même avec le raccourcisseur d'URL), un identifiant unique généré de manière aléatoire est ce que vous voulez vraiment utiliser à la place.

Les clés auto-incitatives ont surtout des avantages.

Mais certains inconvénients possibles pourraient être :

  • Si vous avez une clé métier, vous devez également ajouter un index unique sur cette ou ces colonnes afin d'appliquer les règles métier.
  • Lors du transfert de données entre deux bases de données, en particulier lorsque les données se trouvent dans plusieurs tables (c'est-à-dire maître/détail), ce n'est pas simple car les séquences ne sont pas synchronisées entre les bases de données, et vous devrez d'abord créer une table d'équivalence en utilisant le clé métier comme correspondance pour savoir quel ID de la base de données d'origine correspond à quel ID dans la base de données cible. Cependant, cela ne devrait pas poser de problème lors du transfert de données depuis/vers des tables isolées.
  • De nombreuses entreprises disposent d'outils de reporting ad hoc, graphiques, pointer-cliquer, glisser-déposer. Étant donné que les ID auto-incrémentés n'ont pas de sens, ce type d'utilisateurs aura du mal à comprendre les données en dehors de "l'application".
  • Si vous modifiez accidentellement la clé métier, il est probable que vous ne récupérerez jamais cette ligne car vous n'avez plus rien à faire pour que les humains l'identifient. Cela a causé une fois une erreur dans la plate-forme BitCoin.
  • Certains concepteurs ajoutent un ID à une table de jointure entre deux tables, alors que le PK doit simplement être composé des deux ID étrangers. Évidemment, si la table de jointure se situe entre trois tables ou plus, un ID auto-incrémenté est logique, mais vous devez alors ajouter une clé unique lorsqu'elle s'applique à la combinaison de FK pour appliquer les règles métier.

Voici une section d'article de Wikipédia sur les inconvénients des clés de substitution.

Juste pour être contraire, non, vous n'avez PAS besoin d'avoir toujours un PK AutoInc numérique.

Si vous analysez soigneusement vos données, vous identifiez souvent des clés naturelles dans les données. C'est souvent le cas lorsque les données ont une signification intrinsèque pour l'entreprise. Parfois, les PK sont des artefacts de systèmes anciens que les utilisateurs professionnels utilisent comme deuxième langue pour décrire les attributs de leur système. J'ai vu des numéros VIN de véhicule utilisés comme clé primaire d'un tableau "Véhicule" dans un système de gestion de flotte par exemple.

Quelle que soit sa provenance, SI vous possédez déjà un identifiant unique, utilisez-le. Ne créez pas une deuxième clé primaire dénuée de sens, c'est du gaspillage et cela peut provoquer des erreurs.

Parfois, vous pouvez utiliser un AutoInc PK pour générer une valeur client significative, par ex. Numéros de police. Définir la valeur de départ sur quelque chose de sensé et appliquer des règles métier sur les zéros non significatifs, etc. C'est probablement une approche du « meilleur des deux mondes ».

Lorsque vous avez un petit nombre de valeurs qui sont relativement statiques, utilisez des valeurs qui ont du sens pour l'utilisateur du système. Pourquoi utiliser 1,2,3 alors que vous pourriez utiliser L,C,H où L,H et C représentent la vie, la voiture et l'habitation dans un contexte d'assurance "Type de police", ou, pour revenir à l'exemple VIN, que diriez-vous d'utiliser "TO " pour Toyota ? Toutes les voitures Toyata ont un VIN qui commence par "TO". à écrire et peut-être plus rapide à générer.

Un développement ultérieur de ceci est probablement "un pont trop loin" et je ne le recommande généralement pas, mais je l'inclus par souci d'exhaustivité et vous pouvez en trouver une bonne utilisation. C'est-à-dire, utilisez la description comme clé primaire. Pour les données qui changent rapidement, c'est une abomination. Pour très données statiques qui sont rapportées sur Tout le temps, peut être pas. Il suffit de le mentionner pour qu'il reste là comme une possibilité.

J'utilise les PK AutoInc, j'engage simplement mon cerveau et je cherche d'abord de meilleures alternatives. L'art de la conception de bases de données consiste à créer quelque chose de significatif qui peut être interrogé rapidement. Avoir trop de jointures empêche cela.

EDIT Un autre cas crucial où vous n'avez pas besoin d'une PK générée automatiquement est le cas des tables qui représentent l'intersection de deux autres tables. Pour rester dans l'analogie avec la voiture, une voiture a 0..n accessoires, chaque accessoire peut être trouvé sur de nombreuses voitures. Donc, pour représenter cela, vous créez une table Car_Accessory contenant les PK de Car et Accessory et d'autres informations pertinentes sur le lien Dates, etc.

Ce dont vous n'avez pas (généralement) besoin, c'est d'un AutoInc PK sur cette table - il ne sera accessible que via la voiture "dites-moi quels accessoires sont sur cette voiture" ou à partir de l'accessoire "dites-leur quelles voitures ont cet accessoire"

De nombreuses tables ont déjà un identifiant unique naturel. N'ajoutez pas d'autre colonne d'identifiant unique (auto-incrémentation ou autre) sur ces tables. Utilisez plutôt l'identifiant unique naturel. Si vous ajoutez un autre identifiant unique, vous avez essentiellement une redondance (duplication ou dépendance) dans vos données. Cela va à l'encontre des principes de normalisation. Un identifiant unique dépend de l'autre pour la précision. Cela signifie qu'ils doivent être parfaitement synchronisés à chaque fois dans chaque système qui gère ces lignes. C'est juste une autre fragilité dans l'intégrité de vos données que vous ne voulez pas vraiment avoir à gérer et valider à long terme.

De nos jours, la plupart des tables n'ont pas vraiment besoin de l'amélioration des performances très mineure qu'une colonne d'identifiant unique supplémentaire donnerait (et parfois cela nuit même aux performances). En règle générale en informatique, évitez les redondances comme les la peste! Résistez-lui partout où il vous est suggéré. C'est l'anathème. Et tenez compte de la citation. Tout doit être aussi simple que possible, mais pas plus simple. N'ayez pas deux identifiants uniques où un seul suffira, même si le naturel semble moins bien rangé.

Sur les systèmes plus importants, l'ID est un booster de cohérence, utilisez-le presque partout. Dans ce contexte, les clés primaires individuelles ne sont PAS recommandées, elles sont chères en fin de compte (lisez pourquoi).

Chaque règle a une exception, vous n'aurez donc peut-être pas besoin d'un ID d'auto-incrémentation d'entier sur les tables intermédiaires utilisées pour l'exportation/importation et sur les tables à sens unique ou les tables temporaires similaires. Vous préféreriez également les GUID au lieu des ID sur les systèmes distribués.

De nombreuses réponses ici suggèrent que la clé unique existante devrait être prise. Et bien même s'il a 150 caractères ? Je ne pense pas.

Maintenant mon point principal :

Il semble que les opposants à l'ID entier à incrémentation automatique parlent de petites bases de données contenant jusqu'à 20 tables. Là, ils peuvent se permettre une approche individuelle à chaque table.

MAIS une fois que vous avez un ERP avec plus de 400 tables, ayant un ID d'auto-incrémentation entier n'importe où (sauf cas mentionnés ci-dessus) a tout simplement beaucoup de sens. Vous ne comptez pas sur d'autres champs uniques même s'ils sont présents et sécurisés pour l'unicité.

  • Vous bénéficiez d'une convention universelle facile à mémoriser et gagner du temps.
  • Dans la plupart des cas, vous JOIGNEZ des tables, sans avoir besoin de vérifier quelles sont les clés.
  • Vous pouvez avoir des routines de code universelles fonctionnant avec votre colonne d'auto-incrémentation d'entiers.
  • Vous pouvez étendre votre système avec de nouvelles tables ou des plugins utilisateur non prévus auparavant en vous référant simplement aux ID des tables existantes. Ils sont déjà là depuis le début, aucun frais pour les ajouter en plus.

Sur les systèmes plus importants, il peut être utile d'ignorer les avantages mineurs de ces clés primaires individuelles et d'utiliser systématiquement l'ID d'auto-incrémentation entière dans la plupart des cas. L'utilisation de champs uniques existants comme clés primaires permet peut-être d'économiser quelques octets par enregistrement, mais un temps de stockage ou d'indexation supplémentaire pose pas de problème dans les moteurs de bases de données d'aujourd'hui. En fait, vous perdez beaucoup plus d'argent et de ressources sur le temps perdu des développeurs/mainteneurs. Le logiciel d'aujourd'hui doit être optimisé pour le temps et les efforts des programmeurs – quelle approche avec des ID cohérents est bien meilleure.

Ce n'est pas une bonne pratique pour les conceptions superflues. C'est à dire. - ce n'est pas une bonne pratique d'avoir toujours une clé primaire d'incrémentation automatique quand on n'en a pas besoin.

Voyons un exemple où l'on n'en a pas besoin.

Vous avez une table pour les articles - elle a une clé primaire int identifiant , et une colonne varchar nommée Titre .

Vous avez également une table pleine de catégories d'articles - clé primaire id int, nom varchar .

Une ligne du tableau Articles a un identifiant de 5, et un Titre "Comment faire cuire l'oie avec du beurre". Vous souhaitez lier cet article aux lignes suivantes de votre tableau Catégories : "Fowl" (identifiant: 20), "Oie" (identifiant: 12), "Cuisine" (identifiant: 2), "Beurre" (id: 9).

Maintenant, vous avez 2 tableaux : articles et catégories. Comment créez-vous la relation entre les deux ?

Vous pourriez avoir une table avec 3 colonnes : id (clé primaire), article_id (clé étrangère), category_id (clé étrangère). Mais maintenant vous avez quelque chose comme :

Une meilleure solution est d'avoir une clé primaire composée de 2 colonnes.

Ceci peut être accompli en faisant :

Une autre raison de ne pas utiliser un entier à incrémentation automatique est si vous utilisez des UUID pour votre clé primaire.

Les UUID sont par définition uniques, ce qui accomplit la même chose que l'utilisation d'entiers uniques. Ils ont également leurs propres avantages (et inconvénients) par rapport aux nombres entiers. Par exemple, avec un UUID, vous savez que la chaîne unique à laquelle vous faites référence pointe vers un enregistrement de données particulier, ce qui est utile dans les cas où vous n'avez pas 1 base de données centrale, ou lorsque les applications ont la possibilité de créer des enregistrements de données hors ligne ( puis les télécharger dans la base de données à une date ultérieure).

En fin de compte, vous ne devez pas considérer les clés primaires comme une chose. Vous devez les considérer comme la fonction qu'ils remplissent. Pourquoi avez-vous besoin de clés primaires ? Être capable d'identifier de manière unique des ensembles de données spécifiques à partir d'une table à l'aide d'un champ qui ne sera pas modifié à l'avenir. Avez-vous besoin d'une colonne particulière appelée id pour ce faire, ou pouvez-vous baser cette identification unique sur d'autres données (immuables) ?

Ou existe-t-il des scénarios dans lesquels vous ne souhaitez pas ajouter un tel champ ?

Tout d'abord, il existe des bases de données qui n'ont pas d'auto-incréments (par exemple, Oracle, qui n'est certainement pas l'un des plus petits concurrents). Cela devrait être une première indication que tout le monde ne les aime pas ou n'en a pas besoin.

Plus important encore, pensez à ce que l'ID fait réellement est - c'est une clé primaire pour vos données. Si vous avez une table avec une clé primaire différente, vous n'avez pas besoin d'ID et ne devriez pas en avoir. Par exemple, une table (EMPLOYEE_ID, TEAM_ID) (où chaque employé peut être dans plusieurs équipes simultanément) a une clé primaire clairement définie constituée de ces deux ID. L'ajout d'une colonne d'ID d'auto-incrémentation, qui est également une clé primaire pour cette table, n'aurait aucun sens. Maintenant, vous trimballez 2 clés primaires, et le premier mot de "clé primaire" devrait vous donner un indice que vous ne devriez vraiment en avoir qu'une.

J'utilise généralement une colonne "identité" (entier auto-incrémenté) lors de la définition de nouvelles tables pour les données "à longue durée de vie" (enregistrements que je prévois d'insérer une fois et de conserver indéfiniment même s'ils finissent par être "logiquement supprimés" en définissant un champ de bits ).

Il y a quelques situations auxquelles je peux penser lorsque vous ne voulez pas les utiliser, dont la plupart se résument à des scénarios où une table sur une instance de la base de données ne peut pas être la source faisant autorité pour les nouvelles valeurs d'ID :

  • Lorsque les identifiants incrémentiels seraient trop d'informations pour un attaquant potentiel. L'utilisation d'une colonne d'identité pour les services de données « publics » vous rend vulnérable au « problème des chars allemands » si l'ID d'enregistrement 10234 existe, il va de soi que les enregistrements 10233, 10232, etc. existent, jusqu'à au moins l'enregistrement 10001, et il est alors facile de vérifier les enregistrements 1001, 101 et 1 pour déterminer où a commencé votre colonne d'identité. Les GUID V4 composés principalement de données aléatoires cassent ce comportement incrémentiel par conception, de sorte que juste parce qu'un GUID existe, un GUID créé en incrémentant ou décrémentant un octet du GUID n'existe pas nécessairement, ce qui rend plus difficile pour un attaquant d'utiliser un service prévu pour la récupération d'un seul enregistrement en tant qu'outil de vidage. Il existe d'autres mesures de sécurité qui peuvent mieux restreindre l'accès, mais cela aide.
  • Dans les tableaux de concordance M:M. Celui-ci est une sorte de cadeau mais je l'ai déjà vu faire. Si vous avez une relation plusieurs-à-plusieurs entre deux tables de votre base de données, la solution idéale est une table de références croisées contenant des colonnes de clé étrangère référençant le PK de chaque table. Le PK de cette table doit pratiquement toujours être une clé composée des deux clés étrangères, pour obtenir le comportement de l'index intégré et garantir l'unicité des références.
  • Lorsque vous prévoyez d'insérer et de supprimer en masse sur cette table, beaucoup. Le plus gros inconvénient des colonnes d'identité est probablement le battage supplémentaire que vous devez traverser lors de l'insertion de lignes à partir d'une autre table ou requête, où vous souhaitez conserver les valeurs clés de la table d'origine. Vous devez activer "l'insertion d'identité" (cependant cela est fait dans votre SGBD), puis vous assurer manuellement que les clés que vous insérez sont uniques, puis lorsque vous avez terminé l'importation, vous devez définir le compteur d'identité dans le les métadonnées de la table à la valeur maximale présente. Si cette opération se produit souvent sur cette table, envisagez un autre schéma PK.
  • Pour les tables distribuées. Les colonnes d'identité fonctionnent parfaitement pour les bases de données à instance unique, les paires de basculement et d'autres scénarios dans lesquels une instance de base de données est la seule autorité sur l'ensemble du schéma de données à un moment donné. Cependant, il n'y a que si grand que vous pouvez aller et toujours avoir un ordinateur assez rapide. Replication or transaction log shipping can get you additional read-only copies, but there's a limit to that solution's scale as well. Sooner or later you'll need two or more server instances handling inserts of data and then synchronizing with each other. When that situation comes, you'll want a GUID field instead of an incremental one, because most DBMSes come pre-configured to use a portion of the GUIDs they generate as an instance-specific identifier, then generate the rest of the identifier either randomly or incrementally. In either case, the odds of a collision between two GUID generators are nil, while an identity integer column is a nightmare to manage in this situation (you can go even/odd by offsetting seeds and setting the increment to 2, but if one server sees more activity than the other you're wasting IDs).
  • When you have to enforce uniqueness across multiple tables in the DB. It's common in accounting systems, for instance, to manage the General Ledger (with a row for each credit or debit of every account that has ever occurred, so it gets very big very quickly) as a sequence of tables each representing one calendar month/year. Views can then be created to hook them together for reporting. Logically, this is all one very big table, but chopping it up makes the DB's maintenance jobs easier. However, it presents the problem of how to manage inserts into multiple tables (allowing you to begin logging transactions in the next month while still closing out the last) without ending up with duplicate keys. Again, GUIDs instead of identity integer columns are the go-to solution, as the DBMS is designed to generate these in a truly unique way, so that a single GUID value will be seen once and only once in the entire DBMS.

There are workarounds that allow use of identity columns in these situations, as I've hopefully mentioned, but in most of these, upgrading from the identity integer column to a GUID is simpler and solves the problem more completely.

An auto-incremented (identity) primary key is a good idea except to note that it is meaningless outside of the context of the database and immediate clients of that database. For example, if you transfer and store some of the data in another database, then proceed to write different data to both database tables, the id's will diverge - i.e., data with an id of 42 in one database won't necessarily match the data with an id of 42 in the other.

Given this, if it's necessary to still be able to identify rows uniquely outside of the database (and it frequently is), then you must have a different key for this purpose. A carefully selected business key will do, but you'll often end up in a position of a large number of columns required to guarantee uniqueness. Another technique is to have an Id column as an auto-increment clustered primary-key and another uniqueidentifier (guid) column as a non-clustered unique key, for the purposes of uniquely identifying the row wherever it exists in the world. The reason you still have an auto-incremented key in this case is because it's more efficient to cluster and index the auto-incrementing key than it is to do the same to a guid.

One case where you might not want an auto-incrementing key would be a many-to-many table where the primary key is a compound of the Id columns of two other tables (you could still have an auto-incrementing key here, but I don't see the point of it).

One other question is the datatype of the auto-incremented key. Using an Int32 gives you a large, but relatively limited range of values. Personally I frequently use bigint columns for the Id, in order to practically never need to worry about running out of values.

As other people have made the case for an incrementing primary key I will make one for a GUID:

  • It is guaranteed to be unique
  • You can have one less trip to the database for data in your application. (For a types table for instance you can store the GUID in the application and use that to retrieve the record. If you use an identity you need to query the database by name and I have seen many an application that does this to get the PK and later queries it again to get the full details).
  • It is useful for hiding data. www.domain.com/Article/2 Lets me know you only have two articles whereas www.domain.com/article/b08a91c5-67fc-449f-8a50-ffdf2403444a tells me nothing.
  • You can merge records from different databases easily.
  • MSFT uses GUIDS for identity.

As a principle of good design, every table should have a reliable way to uniquely identify a row. Although that is what a primary key is for, it doesn't always require the existence of a primary key. Adding a primary key to every table is not a bad practice since it provides for unique row identification, but it may be unnecessary.

To maintain reliable relationships between the rows of two or more tables, you need to do it via foreign keys, hence the need for primary keys in at least some tables. Adding a primary key to every table makes it easier to extend your database design when it comes time to add new tables or relationships to existing data. Planning ahead is always a good thing.

As a basic principle (hard rule perhaps), the value of a primary key should never change throughout the life of its row. It's wise to assume that any business data in a row is subject to change over its lifetime, so any business data will be a poor candidate for a primary key. This is why something abstract like an auto-incremented integer is often a good idea. However, auto-incremented integers do have their limitations.

If your data will only have a life within your database, auto-incremented integers are fine. But, as has been mentioned in other answers, if you ever want your data to be shared, synchronized, or otherwise have a life outside your database, auto-incremented integers make poor primary keys. A better choice will be a guid (aka uuid "universally unique id").

The question, and many of the answers, miss the important point that all the natural keys for each table reside solely in the logical schema for the database, and all the surrogate keys for each table reside solely in the physical schema for the database. other answers discuss solely the relative benefits of integer versus GUID surrogate keys, without discussing the reasons why surrogate keys are properly used, and when.

BTW: Let us avoid use of the ill defined and imprecise term primary key. It is an artifact of pre-relational data models that was first co-opted (unwisely) into the relational model, and then co-opted back into the physical domain by various RDBMS vendors. Its use serves only to confuse the semantics.

Note from the relational model that, in order for the database logical schema to be in first normal form, every table must have a user-visible set of fields, known as a natural key, that uniquely identifies each row of the table. In most cases such a natural key is readily identified, but on occasion one must be constructed, whether as a tie breaker field or otherwise. However such a constructed key is always still user visible, and thus always resides in the logical schema of the database.

By contrast any surrogate key on a table resides purely in the physical schema for the database (and thus must always, both for security reasons and for maintenance of database integrity, be entirely invisible to database users). The sole reason for introducing a surrogate key is to address performance issues in the physical maintenance and use of the DB whether those be joins, replication, multiple hardware sources for data, or other.

Since the sole reason for the introduction of a surrogate key is performance, let us presume that we wish it to be performant. If the performance issue at hand is joins, then we necessarily wish to make our surrogate key as narrow as can be (without getting in the way of the hardware, so short integers and bytes are usually out). Join performance relies on minimal index height, so a 4-byte integer is a natural solution. If your performance issue is insertion rate a 4-byte integer may also be a natural solution (depending on your RDBMS's internals). If your performance issue for a table is replication or multiple data sources than some other surrogate key technology, be it a GUID or a two-part key (Host ID + integer) may be more suitable. I am not personally a favourite of GUIDs but they are convenient.

To sum up, not all tables will require a surrogate key (of any type) they should only be used when deemed necessary for the performance of the table under consideration. Regardless of which common surrogate key technology you prefer, think carefully about the actual needs of the table before making a choice changing the surrogate key technology choice for a table will be exhausting work. Document the key performance metric for your table so that your successors will understand the choices made.

Special Cases

If your business requirements mandate a sequential numbering of transactions for audit (or other) purposes than that field is ne pas a surrogate key it is a natural key (with extra requirements). From the documentation an auto-incrementing integer only generates surrogate keys, so find another mechanism to generate it. Obviously some sort of monitor will be necessary, and if you are sourcing your transactions from multiple sites then one site will be special, by virtue of being the designated host site for the monitor.

If your table will never be more than about a hundred rows then index height is irrelevant every access will be by a table scan. However string comparisons on long strings will still be much more expensive than comparison of a 4-byte integer, and more expensive than comparison of a GUID.

A table of code values keyed by a char(4) code field should be as performant as one with a 4-byte integer. Although I have no proof of this I use the assumption frequently and have never had reason to rue it.


Renumbering an Existing Sequence

You're determined to resequence a column, despite my advice not to.

Drop the column from the table. Then put it back. MySQL will renumber the values in the column in unbroken sequence.

If you determine that resequencing an AUTO_INCREMENT column is unavoidable, the way to do it is to drop the column from the table, then add it again. The following example shows how to renumber the identifiant values in the insect table using this technique:

La première ALTER TABLE statement gets rid of the identifiant column (and as a result also drops the PRIMARY KEY, because the column to which it refers is no longer present.) The second statement restores the column to the table and establishes it as the PRIMARY KEY. (Le PREMIÈRE keyword places the column first in the table, which is where it was originally. Normally, AJOUTER puts columns at the end of the table.) When you add an AUTO_INCREMENT column to a table, MySQL automatically numbers all the rows consecutively, so the resulting contents of the insect table look like this:

One problem with resequencing a column using separate ALTER TABLE statements is that the table will be without that column for the interval between the two operations. This may cause difficulties for other clients that try to access the table during that time. To prevent this from happening, perform both operations with a single ALTER TABLE déclaration:

MySQL permits multiple actions to be done with ALTER TABLE (something not true for all database systems). However, notice that this multiple-action statement is not simply a concatenation of the two single-action ALTER TABLE statements. It differs in two ways:


Is it good practice to keep 2 related tables (using auto_increment PK) to have the same Max of auto_increment ID when table1 got modified?

This question is about good design practice in programming.

Let see this example, we have 2 interrelated tables:

rID is auto_increment primary key & textID is foreign key

The relationship is that 1 rID will have 1 and only 1 textID but 1 textID can have a few rID .

So, when table1 got modification then table2 should be updated accordingly.

Ok, here is a fictitious example. You build a very complicated system. When you modify 1 record in table1, you need to keep track of the related record in table2. To keep track, you can do like this:

Option 1: When you modify a record in table1, you will try to modify a related record in table 2. This could be quite hard in term of programming expecially for a very very complicated system.

Option 2: instead of modifying a related record in table2, you decided to delete old record in table 2 & insert new one. This is easier for you to program.

For example, suppose you are using option2, then when you modify record 1,2,3. 100 in table1, the table2 will look like this:

This means the Max of auto_increment IDs in table1 is still the same (100) but the Max of auto_increment IDs in table2 already reached 200.

what if the user modify many times? if they do then the table2 may run out of records? we can use BigInt but that make the app run slower?

Note: If you spend time to program to modify records in table2 when table1 got modified then it will be very hard & thus it will be error prone. But if you just clear the old record & insert new records into table2 then it is much easy to program & thus your program is simpler & less error prone.

So, is it good practice to keep 2 related tables (using auto_increment PK) to have the same Max of auto_increment ID when table1 got modified?


Using auto increment code with counter - Geographic Information Systems

The AUTO_INCREMENT attribute can be used to generate a unique identity for new rows:

No value was specified for the AUTO_INCREMENT column, so MySQL assigned sequence numbers automatically. You can also explicitly assign 0 to the column to generate sequence numbers, unless the NO_AUTO_VALUE_ON_ZERO SQL mode is enabled. Par exemple:

If the column is declared NOT NULL , it is also possible to assign NULL to the column to generate sequence numbers. Par exemple:

When you insert any other value into an AUTO_INCREMENT column, the column is set to that value and the sequence is reset so that the next automatically generated value follows sequentially from the largest column value. Par exemple:

Updating an existing AUTO_INCREMENT column value in an InnoDB table does not reset the AUTO_INCREMENT sequence as it does for MyISAM and NDB tables.

You can retrieve the most recent automatically generated AUTO_INCREMENT value with the LAST_INSERT_ID() SQL function or the mysql_insert_id() C API function. These functions are connection-specific, so their return values are not affected by another connection which is also performing inserts.

Use the smallest integer data type for the AUTO_INCREMENT column that is large enough to hold the maximum sequence value you need. When the column reaches the upper limit of the data type, the next attempt to generate a sequence number fails. Use the UNSIGNED attribute if possible to allow a greater range. For example, if you use TINYINT , the maximum permissible sequence number is 127. For TINYINT UNSIGNED , the maximum is 255. See Integer Types (Exact Value) - INTEGER, INT, SMALLINT, TINYINT, MEDIUMINT, BIGINT for the ranges of all the integer types.

For a multiple-row insert, LAST_INSERT_ID() and mysql_insert_id() actually return the AUTO_INCREMENT key from the première of the inserted rows. This enables multiple-row inserts to be reproduced correctly on other servers in a replication setup.

To start with an AUTO_INCREMENT value other than 1, set that value with CREATE TABLE or ALTER TABLE , like this: