web-dev-qa-db-fra.com

Utilisation de Timeestamp Plus entier comme clé primaire

Dans SQL Server, quels seraient les inconvénients et inconvénients d'utiliser une clé primaire:

Deux caractères identifiant + année + mois + jour + heure + minute + milliseconde + entier aléatoire entre 0 et 100?

Pourquoi cela serait-il préférable d'utiliser un champ entier Auto_Incrimated? (Sauf si ce ne serait pas, alors je veux le savoir aussi.)

J'adorerais des raisons pour lesquelles il s'agit d'une très mauvaise pratique de design. Casting tout afin de revenir que la valeur entière est également une douleur totale dans le cul.

Je supporte essentiellement une chance d'obtenir ma petite équipe de développeurs à accéder à l'accès à l'amélioration de la base de données de notre application, qu'elle nécessite mal - d'éviter les situations telles que les champs principaux de Varcharchar (50) à zéro à gauche, ou de commencer à améliorer les non-éventuels. -sablaformalisation de la base de données ou des listes séparées par des virgules dans un champ.

5
user44371

Bien sûr, vous pouvez le faire, mais pourquoi voudriez-vous? Pour enregistrer quelques expressions de moulage? Cela semble un peu faible.

Les raisons d'incrémenter automatiquement les substances substitutives des PC sont nombreuses:

  1. Vous n'avez pas à peu près les gérer avec des bases de données normales. Déjà. Sauf si vous reconstruisez des tables ou insérez des données dans lesquelles vous devez éteindre l'identité et sur. Mais de manière opérationnelle, cela fonctionne bien avec peu de frais généraux. Si vous le faites comme si vous le suggérez, cela provoque beaucoup plus de frais généraux avec la nécessité d'avoir un UDF pour créer la clé qui implique beaucoup plus de cycles de processeur à créer qu'un incrément automatique Int.
  2. Ils sont la solution de stockage la plus efficace. La manière dont vous suggérez nécessiterait un Varchar (20)/Char (20) ou signifie donc 20 octets par ligne juste pour la clé. Un INT normal n'est que de 4 octets. Cela pourrait ne pas sembler beaucoup, mais mettre 100 millions de lignes là-bas et vous augmentez la taille d'environ 1,5 Go. Pas cool. Ensuite, vous devez le mettre comme le FK dans une autre table, une autre 1,5 Go. Ou dans 3 autres tables et votre DB est inutilement de près de 5 Go plus grand. Vous avez eu l'idée...
  3. Les tables devraient vraiment être liées à quelque chose que les utilisateurs ne se soucient pas ou ne comprennent pas. C'est ainsi que vous avez une faible granularité de contrôle en tant que DBA, une valeur que vous pouvez faire référence à laquelle les utilisateurs ne savent rien ne devient important lorsque vous effectuez des modifications très granulaires, une réglage précis de la table ou de la gestion de la structure de données. Je peux simplement vous dire cela de l'expérience de travailler avec des DBS qui ont des clés composites comme vous le suggérez. Ils deviennent de manière frustrante et vous êtes toujours tenté de simplement mettre dans une auto incrémentation de l'int et être fait avec la complexité et la frustration. Imaginez par exemple, vous souhaitez insérer rapidement un tas d'enregistrements qui proviennent d'une source différente. Avec une incrémentation automatique, facile avec un succès minimal sur les ressources du serveur. Avec une clé composite ... Vous devez exécuter un UDF qui crée la clé de chaque insert ... et dans votre exemple, le Randomiser pour 100 clés par ms pourrait ne pas suffire, SQL Server peut fonctionner trop vite pour vous et vous donner le même identifiant pour 2 enregistrements. Bon sang, vous avez besoin d'une approche différente qui ne violait pas la contrainte unique. Ou imaginez que l'utilisateur souhaite démarrer la "réutilisation" une clé pour une raison quelconque (cela se produit, parfois sur une idée erronée de "recyclage en faisant la base de données plus rapide"). Les utilisateurs finissent par essayer d'accorder la DB elles-mêmes, une recette pour la catastrophe. Leur dire (et avoir) derrière les scènes des choses qui se produisent qu'elles ne comprennent pas donnent un niveau de séparation qui évite souvent la situation. Ils n'essayent rien d'optimiser quoi que ce soit, prenant leurs petits doigts collants de votre côté de l'entreprise, ce qui signifie que vous pouvez optimiser la façon dont cela devrait être fait. Tout comme un adolescent sans idée de tenter de changer le calendrier électronique d'une voiture moderne avec leur téléphone intelligent et un marteau ... un travail bien mieux fait par un professionnel avec les bonnes connaissances et les outils.
  4. SQL Server s'attend à des incréments d'auto PK-FK et est optimisé pour celui-ci. Cela signifiera un traitement plus rapide globalement en raison des contrôles FK lors de l'insertion des enregistrements.
  5. Enfin, je trouve des clés naturelles pour être absolument bien avec de petites bases de données avec peu d'utilisateurs nécessitant peu d'optimisation et de gestion. Ils peuvent également utiliser des requêtes plus propres (en utilisant la clé composite dans les instructions) lorsque les requêtes sont simples, ce qui signifie que vous avez des tables de jointure moins, mais dès que la base de données commence à devenir grande et complexe ... Gérer l'incrémentation automatique des INTS Les clés de substitution devient beaucoup plus facile.

Ma dernière pensée: les clés composites conviennent parfaitement aux tables de recherche qui ont un faible nombre de membres (ce qui signifie une clé composite plus courte et donc des exigences d'espace faible) qui ne sont pas soumises à beaucoup de changement (ce qui signifie basse gestion de la gestion). Un exemple est des codes d'état de deux lettres aux États-Unis. Ils signifieront potentiellement une jointure de moins et sur de nombreux PROC stockés, cela pourrait faire une amélioration de la performance petite mais mesurable.

5
blobbles

Votre idée n'est pas si folle. Commander La clé primaire réduit la fragmentation, mais cela peut être obtenu avec une colonne d'identité. Cependant, les clés commandées ont également un inconvénient, à savoir celui décrit ici: http://kejser.org/clustered-indexes-vs-heaps .

Maintenant, je peux voir comment vous bénéficierez de savoir lorsque la clé a été générée et que vous souhaitez donc emballer une petite information supplémentaire là-bas. Il brise les règles de normalisation - mais celles-ci sont pour les universitaires, pas pour les concepteurs de systèmes réels.

Je pense aussi que je sais aussi où vous venez de (et corrigez-moi si mal) lorsque vous préfixez la clé avec le nom de la table - cela empêche les utilisateurs de rejoindre les mauvaises touches et d'obtenir de mauvaises données car une telle jointure ne reviendra rien.

Si vous souhaitez conserver votre stratégie et conserver les avantages d'une bonne conception physique, voici comment je le ferais.

  • Faire la clé A 64 bits entier
  • Les 32 bits supérieurs sont construits comme: année * 10000 + mois * 100 + jour (il s'agit de 8 chiffres longs et convient à 32 bits)
  • Les 32 bits inférieurs sont générés à partir d'une séquence de 32 bits (rechercher une séquence de création) qui est globale sur toutes les tables et se roule sur le dessus de la touche Maxint. Cela rend la clé unique sur les tables sans avoir besoin du préfixe du nom de la table.

Avec la stratégie ci-dessus, vous pouvez générer des clés 2b chaque jour, ce qui, espérons-le, suffit. Si ce n'est pas le cas, vous pourriez envisager de raser l'année à 2 chiffres (ouais, oui, je sais ...)

Cette stratégie ci-dessus crée une index de manière séquentielle avec les avantages et les inconvénients. Si vous souhaitez modifier la logique clé pour utiliser une mise en page plus évolutive, vous pouvez retourner la séquence de bits des 32 bits inférieurs à l'aide du truc décrite ici: http://dangèredba.blogspot.co.uk/2011/ 10/séquences de jour-sauvé-world.html .

3
Thomas Kejser

Cela ne serait certainement pas préféré à un champ entier d'incrémentation automatique.

Pour commencer:

  1. La largeur d'index serait considérablement dégradée avec votre proposition.
  2. Comment proposez-vous de gérer tous ces des entiers aléatoires à 2 chiffres Pour faire respecter l'unicité. Avez-vous pensé à la quantité de code qui devrait être écrit et maintenu pour mettre en œuvre ce régime.
  3. Ne tapez pas tous ces champs clés dans Pour chaque jointure de la mise en œuvre Soyez une joie.

En aparté; Pourquoi sur Terre souhaitez-vous insérer un identifiant de table à deux caractères dans chaque instance de ce nouveau champ? La table à laquelle la ligne est venue est immédiatement évidente de la table à inspecter.

Si vous pensez vraiment que votre taux de collision de données sur un grand nombre de sites est très extrême pour justifier un schéma tel que celui-ci, au moins utiliser un GUID, une technologie déjà mise en œuvre, au lieu de cette conception NIH.

Mise à jour

La nature monotonique de la clé d'autocrampe est utilisée dans certains Algorithmes de table de compensation très efficaces pour les totaux d'exécution (au moins) Pour appliquer un séquençage approprié des calculs totaux en cours d'exécution. Ce schéma invaliderait l'utilisation de ces algorithmes.

3
Pieter Geerkens

Ma préférence est d'utiliser une colonne d'identité pour la clé primaire et si nécessaire, ajoutez un index unique sur d'autres champs si vous devez appliquer l'unicité.

À mon avis, une tâche principale des clés est d'identifier de manière unique une seule ligne de données. Les entiers le font plus efficacement sans risque d'ambiguïté.

Je n'aime pas utiliser les varcharars comme des pkets ou des jointures, car ils peuvent être affectés par des espaces, des majuscules/minuscules, un rembourrage, des zéros de premier plan ou des conversions implicites.

Avoir un simple pkure dans un seul champ avec des valeurs sans ambiguïté facilitera le travail de chacun.

1
Sir Swears-a-lot

Hmm, je suis d'accord avec vous, presque et pas avec les gens qui suggèrent d'utiliser un entier arbitraire pour identifier vos rangées.

Votre clé principale devrait être

tid char(2), asof datetime, sequence smallint

où vous contrôlez la séquence. C'est une clé primaire parfaitement fine parce que elle identifie la ligne. Le fardeau est sur la foule de substitution pour expliquer les circonstances sous lesquelles un identifiant "plus granuleux" sera nécessaire.

Cela donne à votre clé de 16 octets. C'est correct, à peine gigantesque, et probablement comme non plus efficace qu'une clé de substitution. Pourquoi?

  • il utilise des valeurs que l'application aura sur la main
  • en tant que clé en cluster, elle sera commandée par des données naturelles
  • une clé de substitution nécessiterait une contrainte unique sur eux, aussi

Utilisez datetime au lieu de données de caractères pour représenter une date. Vous obtenez une validation automatique de la date et une date d'arithmétique est grandement simplifiée.

En outre, le numéro de séquence est-il vraiment nécessaire? Sinon, vous pouvez le laisser tomber. Si c'est le cas, c'est ne autre Raison d'éviter les valeurs auto-incrémentées: elles constituent un point de conflit de ressources, car toutes les insertions doivent obtenir leur valeur d'auto-incrémentation automatique du même endroit.

Si vous avez besoin du numéro de séquence, faites-le de cette façon:

insert into T as t
select /* values ... */ ,  1 + coalesce(max(sequence), 0) as seq 
from T 
where tid = t.tid and asof = t.asof

parce que l'atomicité de insert ... select garantit que chaque processus obtiendra une valeur distincte.

0
James K. Lowden