web-dev-qa-db-fra.com

Vous partagez une séquence de clés primaires unique dans une base de données?

Est-ce une pratique acceptable d'utiliser une seule séquence comme clé primaire dans toutes les tables (au lieu qu'une clé primaire soit unique pour une table donnée, elle est unique pour toutes les tables)? Si tel est le cas, est-il objectivement préférable à l'utilisation d'une seule séquence de clés primaires entre les tables.

Je suis un développeur de logiciels junior, pas un DBA, donc j'apprends encore bon nombre des bases d'une bonne conception de base de données.

Edit: au cas où quelqu'un se poserait la question, j'ai récemment lu une critique d'une conception de base de données par l'un des administrateurs de base de données de notre entreprise qui a mentionné que le design n'utilisait pas une seule clé primaire dans toute la base de données, ce qui semblait différent de ce que J'ai appris jusqu'ici.

Edit2: Pour répondre à une question dans les commentaires, c'est pour Oracle 11g, mais je me demandais à un niveau non spécifique à la base de données. Si cette question dépend de la base de données, je serais intéressé de savoir pourquoi, mais dans un tel cas, je chercherais une réponse spécifique à Oracle.

14
Lawtonfogle

Acceptable? Sûr. Commun? Non. Bénéfique? Douteux.

Lors de mon ancien travail, nous avons hérité d'un système où ils avaient un générateur de séquence central (c'était un système SQL Server bien avant que SEQUENCE soit introduit dans SQL Server 2012). Ce n'était pas vraiment un goulot d'étranglement des performances et ne devrait pas l'être sauf si vous générez des centaines de milliers de valeurs par seconde. Mais cela a rendu tout le code beaucoup plus complexe qu'il ne devait l'être, sans raison valable. Le but de la conception était de s'assurer que si quelque chose dans le système se voyait attribuer une valeur ID de 12, une seule chose dans le système pouvait avoir l'ID 12. Cela me semblait assez obtus et je ne l'ai jamais compris. Si j'ai un client avec CustomerID = 12, pourquoi cela m'empêche-t-il d'avoir une commande avec OrderID = 12?

Je vois l'utilité d'un générateur de séquence central si vous avez plusieurs systèmes et que vous générez des ID pour un certain type d'entité (par exemple, un client ou une commande) à partir de ces multiples systèmes. Une séquence centrale peut distribuer de nouvelles valeurs à plusieurs systèmes sans être un goulot d'étranglement (juste un seul point de défaillance) et sans craindre que deux systèmes génèrent le même ID.

13
Aaron Bertrand

L'idée a du mérite dans une base de données très complexe où les gens pourraient accidentellement se joindre à une table en utilisant la mauvaise colonne et obtenir des lignes invalides simplement parce que les ID INT sont les mêmes.

Nous avons choisi d'avoir des GUID séquentiels comme clés primaires afin d'éviter certains des pièges de fragmentation d'index des GUID. Malheureusement, ils sont assez grands.

Le serveur SQL peut générer des GUID séquentiels via un appel par défaut de la fonction newSequentialID (), il n'y a donc pas de table de clés émises à maintenir et pas de goulot d'étranglement de blocage.

Cela nous a donné des identifiants uniques sur l'ensemble des bases de données, sur l'ensemble de notre entreprise, car ils sont vraiment uniques.

Le prix, bien sûr, est l'espace et sa problématique lorsque vous essayez de transférer les données vers un entrepôt de données/cube où la vitesse/la taille est basée sur l'utilisation de petites clés entières.

Je suis convaincu que nous avons évité de nombreux bugs dans notre application suite à leur utilisation.

7
RayG

Je ne peux pas imaginer quelle pourrait être la raison derrière la séquence unique à travers toutes les tables. Il ne fait que créer un goulot d'étranglement lors de la génération de nouvelles valeurs.

Quelle que soit la taille de la surcharge engendrée par la génération de valeurs de clé séquentielles, le générateur est une ressource unique dont l'accès doit être synchronisé. Plus il reçoit de demandes, plus les chances que certains demandeurs attendent leur tour au robinet sont élevées. Il est évident que le générateur de séquence unique partagé entre toutes les tables sera consulté plus fréquemment par plus de clients, produisant ainsi plus de conflits, que n'importe lequel des générateurs multiples. L'affirmation peut devenir plus prononcée si les règles métier imposent des contraintes sur les valeurs générées, telles que l'absence de lacunes ou un ordre strict, ou dans une base de données en cluster.

Même avec le générateur de séquence le plus efficace, il sera une charge de travail qui provoque des conflits intolérables.

4
mustaccio

l'objectif de PrimaryKey dans les tables de base de données est principalement de faire en sorte que les données supposées uniques soient uniques, car tous les flux de travail ne peuvent pas être couverts et garantissent qu'ils n'entraîneront pas de duplication des données. La deuxième raison est que, souvent, PK est également le principal candidat pour l'index clusterisé sur la table, ce qui stimule également la récupération des données lorsque/où ces colonnes sont correctement utilisées dans la requête de sélection.

l'utilisation d'un numéro de séquence comme clé primaire est la même que chaque table a une colonne d'identité et seule cette colonne est utilisée dans PrimaryKey. avoir un numéro de séquence unique dans la base de données doit avoir une utilisation spécifique, mais du point de vue de PrimaryKey, je ne comprends pas la raison. Par exemple, dans l'un des projets Datawarehouse sur lequel j'ai travaillé, nous avons une colonne appelée LoadBatchID et d'ETL à signaler que 50% de tous les tableaux ont cette colonne, mais à certains endroits, elle a une signification différente. nous avons utilisé le proc unique comme générateur de nombres pour nous assurer que nous ne trouvons pas de conflits et nous aidons également à retrouver le fichier d'origine d'où proviennent les données et ce qui se passe à chaque étape d'ETL.

2
Anup Shah

Je suppose qu'une raison de le faire serait que toutes les entités héritent d'une entité parent. Disons par exemple que vous vouliez pouvoir mettre un commentaire sur tout type d'entité:

create table god_entity (
  id bigserial primary key
);

create table some_table (
  id bigint primary key references god_entity(id),
  ...
);

create table some_other_table (
  id bigint primary key references god_entity(id),
  ...
);

create table comment (
  id bigint primary key references god_entity(id),
  ...
);

create table entity_comment (
  entity_id bigint not null references god_entity(id),
  comment_id bigint not null references god_entity(id),

  primary key (entity_id, comment_id)
);

Habituellement, cela ne se fait pas. .

Je ne connais pas les caractéristiques de performance.

2
Neil McGuigan