À quoi servent les clés négatives?

12

Un peu nouveau dans l'utilisation des bases de données SQL standard (qui travaille actuellement principalement avec MySQL), je n'ai pas encore utilisé de nombreuses utilisations de cela.

Quand et pourquoi est-il utile d'avoir des clés négatives (ou plutôt signées) pour indexer une table?

Garet Claborn
la source
5
tout d'abord, celui qui vote en aval sans laisser de commentaires, vous faites un mauvais service. Ensuite, la réponse à cette excellente question.
jcolebrand
1
Ce sujet est intrigant. Personnellement, je n'ai jamais entendu parler de ce concept. Cette question n'aurait jamais dû être rejetée. +1 de ma part pour avoir introduit ce concept.
RolandoMySQLDBA

Réponses:

13

Une clé primaire est uniquement une valeur que nous avons déterminée comme étant la valeur la plus importante dans un enregistrement. Que cette clé soit un entier signé, un entier non signé, une chaîne, un blob (en fait, il y a des limites) ou un UUID (ou quel que soit le nom qu'il porte aujourd'hui), le fait est toujours que c'est une clé, et qu'elle est la chose de la plus haute importance.

Comme nous ne sommes pas contraints d'utiliser uniquement des nombres orientés positifs pour nos clés, il est logique de considérer qu'un entier signé n'atteindra que ~ 2 milliards, tandis qu'un entier non signé ira à ~ 4 milliards. Mais il n'y a rien de mal à utiliser un entier signé, en définissant la valeur initiale à ~ -2 milliards et en définissant un incrément de un. Après environ 2 milliards d'enregistrements, vous atteindrez «zéro», puis vous continuerez à environ 2 milliards.

Quant à savoir pourquoi il serait utile d'avoir des "clés négatives" dans une table, c'est la même question que "pourquoi est-il utile d'avoir des clés dans une table". La "valeur" d'une clé n'a aucun impact sur son statut de clé. Une clé est une clé est une clé.

Ce qui est important, c'est si la clé est valide.

Quant à savoir pourquoi il serait utile d'autoriser les clés négatives, je peux suggérer quelques raisons:

Et si vous vouliez indiquer les retours dans un système de vente sous forme de numéros de commande client négatifs, qui correspondaient au numéro de commande client positif, facilitant ainsi la corrélation (c'est naïf et mal conçu, mais cela fonctionnerait dans un sens de «feuille de calcul»).

Et si vous vouliez avoir une table d'utilisateurs et indiquer que ceux avec des nombres négatifs étaient contrôlés par le système (SO fait cela, pour les utilisateurs du fil de discussion).

Je pourrais continuer, mais vraiment la seule raison pour laquelle le nombre étant négatif est important si vous ou moi lui attribuons de l'importance. En dehors de cela, il n'y a pas de grande raison pour que la valeur d'une clé ait une incidence sur la clé elle-même.

jcolebrand
la source
Réduit le bit «occurrence de niche», car il s'agit très probablement d'un malentendu dû à l'inexpérience. Lecture intéressante. J'imaginais quelque peu qu'il y aurait une situation où la valeur négative de la clé serait en quelque sorte utile dans le codage (i, e sans décider que cela signifie une chose particulière) mais c'est une pensée très utile lorsque vous avez une forte division en deux groupes et don veux pas utiliser un bool supplémentaire: p
Garet Claborn
1
@Garet ~ Donc, vous faites un bon point: "la valeur de la clé était en quelque sorte utile dans le codage" et j'utilise mes clés de temps en temps de cette manière, mais cela n'a rien à voir avec l'aspect de la base de données. La base de données est un entrepôt. En revanche, l'application qui consomme les données se soucie des valeurs . Mais oui, ce +/- booléen est une astuce intéressante, je l'ai vu utilisé plusieurs fois pour un tel effet.
jcolebrand
2
-1 pour avoir laissé entendre que des valeurs à double objectif comme celle-ci sont autre chose qu'une mauvaise idée. Vous avez besoin d'un int et d'un bool? Utilisez un int et un bool.
Jack dit d'essayer topanswers.xyz
1
@JackPDouglas Je ne me souviens pas avoir encouragé les gens à le faire, je me souviens strictement avoir laissé entendre que le champ et ses données sont deux choses différentes. Merci d'avoir au moins fourni des commentaires constructifs sur votre downvote, mais je ne peux pas dire que cette observation signifie quoi que ce soit à la lumière du concept de "à quoi servent les clés négatives" car c'est un problème de logique d'application, pas un problème de couche de base de données . Je voulais souligner comment ces choses sont utilisées dans la couche application, mais dans la couche base de données, elles n'ont aucune signification.
jcolebrand
1
@JackPDouglas ~ J'ai utilisé cet exemple particulier parce qu'il y a un site très connu (réseau de sites) dont vous avez peut-être entendu parler qui fait exactement cela, donc je ne veux pas le rejeter, car c'est un "tour". Consultez cet utilisateur dba.stackexchange.com/users/-1/community et dites-moi quel est son ID. Je peux presque vous assurer que l'ID utilisateur est la clé primaire (et dans de nombreux autres tableaux une clé étrangère). Ce n'est pas parce que c'est une mauvaise conception d'application que cela n'est pas valide. Mais encore une fois, ce n'est pas la conception db, c'est la conception de domaine. Certes, la logique db le supporte
jcolebrand
10

Si nous parlons de colonnes d'identité ou de numérotation automatique, la valeur elle-même ne devrait pas avoir de sens. (parfois c'est le cas, selon les utilisateurs de chat de SO mentionnés par drachenstern, ce que j'ai fait avant moi-même)

Cependant, vous perdriez généralement la moitié de votre plage si vous utilisez des entiers signés.
Voir: Que faire lorsqu'un champ dans une table approche de l'entier 32 bits signé ou non signé max?

Autre exemple: dans les petits scénarios de réplication, l'utilisation de valeurs négatives pour un site et positives pour un autre donne une connaissance implicite de la source d'une ligne donnée.

gbn
la source
et assurez-vous que vous contraignez en quelque sorte les valeurs saisies sur chaque site, sinon vous vous retrouverez dans un horrible gâchis lorsque votre "connaissance implicite" se révélera erronée.
Jack dit d'essayer topanswers.xyz
@JackPDouglas: vous utiliseriez NOT FOR REPLICATION pour éviter de générer des valeurs sur le mauvais site
gbn
avec des contraintes de vérification ? De plus, y a-t-il un analogue MySQL (ou autre) NOT FOR REPLICATIONque vous connaissez?
Jack dit d'essayer topanswers.xyz
@JackPDouglas: désolé, pas sûr pour non SQL Server
gbn
8

Tous les systèmes de base de données ne prennent même pas en charge les types entiers non signés, MSSQL étant l'un de ceux qui ne le font pas. Dans ces cas, des valeurs négatives sont possibles dans les champs de clé entière simplement parce qu'elles sont possibles dans le type (vous pouvez utiliser des règles ou des déclencheurs pour les bloquer, comme indiqué dans cet exemple , mais il n'est probablement pas nécessaire d'ajouter la surcharge d'application de ces règles à chaque intersection / mise à jour).

En ce qui concerne la base de données, la valeur réelle d'une clé primaire n'a pas d'importance tant qu'elle est unique dans la table. Pour lui -42 et 42 ne sont que deux nombres différents de la même manière que 42 et 69 - le sens ne sera communiqué que sur la négativité ou non de la valeur par votre code.

Ne pas prendre en charge les types entiers non signés est probablement une décision de conception basée sur la réduction de la complexité - c'est-à-dire ne pas vouloir que deux types entiers 32 bits différents se soucient de vérifier les plages lors de l'affectation de valeurs entre eux. Cela limite le nombre d'index possibles dans un champ d'incrémentation automatique commençant un 0 ou 1 à la moitié de ce qui serait possible dans un type non signé (~ 2e9 plutôt que ~ 4e9) mais c'est rarement un problème important (si vous êtes susceptible d'avoir besoin un certain nombre de valeurs clés de cette ampleur, vous avez probablement opté pour un type 64 bits de toute façon, surtout si vous utilisez une architecture 64 bits où ces valeurs sont traitées non moins efficacement que celles de 32 bits), mais si vous souhaitez la plage complète et le besoin pour s'en tenir à 32 bits pour des raisons d'espace, vous pouvez commencer l'incrément à -2.147.483.647.

David Spillett
la source
Oui, je pense que nous avons déjà couvert ce terrain;) tehehe dba.stackexchange.com/questions/983/…
jcolebrand
tinyint n'est pas signé (0 .. 255). Je crée généralement une contrainte de vérification sur les colonnes entières pour garantir que les valeurs ne sont pas négatives, car inévitablement du code sera écrit qui l'assume implicitement et des bogues étranges se produiront si une valeur négative se glisse.
Ed Avis