11
votes

Question sur la manière dont les données de clé étrangère sont stockées dans SQL

Je sais que c'est ultra-basique, mais c'est une hypothèse que j'ai toujours tenue et souhaite valider que c'est vrai (en général, avec les détails spécifiques à diverses implémentations)

Disons que j'ai une table qui a une colonne de texte "fruit". Dans cette colonne, une seule des quatre valeurs apparaît jamais: poire, pomme, banane et fraise. J'ai un million de lignes.

au lieu de répéter que des données (en moyenne) un quart de fois de fois chacune, si je l'extrait dans une autre table qui a une colonne de fruits et que ces quatre rangées, puis faites la colonne d'origine une clé étrangère, elle enregistre-t-elle espace?

Je suppose que les quatre noms de fruits sont stockés une seule fois et que les millions de lignes ont maintenant des pointeurs ou des index ou une sorte de référence dans la deuxième table.

Si mes valeurs de ligne sont plus longues que les noms de fruits courts, je suppose que les économies / optimisation sont encore plus grandes.


1 commentaires

Je comprends que vous n'avez pas vraiment vouloir utiliser des clés étrangères. Aaah, Marc B vient de poster les implications sur FKS. Mais en utilisant une deuxième table en tant que "nom de nom de nom" externe sauverrait définitivement de l'espace. Vous aurez besoin d'un index supplémentaire sur fruit.fruit_id. Celui-ci sera plutôt petit et ce sera numérique. Plus rapide que les indices sur char ou varchar.


6 Réponses :


9
votes

Les types de données des champs des deux côtés d'une relation de clé étrangère doivent être identiques.

Si le champ Key de la table parent est (dire) varchar (20) , alors les champs de clé étrangère dans la table dépendante devront également être varchar (20) . Ce qui signifie, oui, vous devez avoir x millions de rangées de "pomme" et "poire" et "banane" répétant dans chaque table qui a une clé étrangère pointant sur la table des fruits.

Généralement, il est plus efficace d'utiliser des champs numériques sous forme de touches (INT, de Bigint), car celles-ci peuvent avoir des comparaisons effectuées avec très peu d'instructions de CPU (généralement une comparaison d'instructions de la CPU directe est possible). Des cordes, d'autre part, nécessitent des boucles et des configurations relativement coûteuses. Donc, oui, vous feriez mieux de stocker les noms de fruits dans une table quelque part et utilisez leurs champs d'identification numérique associés comme clé étrangère.

Bien sûr, vous devez comparer les deux configurations. Ce ne sont là que des règles générales des pouces, et votre configuration / configuration spécifique peut réellement fonctionner plus rapidement avec la version Strings-AS-Key.


2 commentaires

Pensez à une variable de type de référence 3gl telle que c # .NET: sa valeur se déroule dans un emplacement en mémoire mais peut avoir de nombreuses variables de référence qui sont simplement entier (ou autre) des pointeurs à cet endroit. Le même principe peut être appliqué à la SGBD: logiquement les deux tables d'une FK Stocker le fruit comme texte, mais sous les couvertures, le texte est enregistré une seule fois et chaque table stocke physiquement uniquement un pointeur entier (ou autre) à la même valeur. MySQL fait-il cela? Je pense que c'est ce que le questionneur se fait.


Je ne comparerais pas les pratiques de stockage de données de MySQL contre un langage de programmation. Il serait logique de stocker une seule copie, mais les clés étrangères ne sont pas des références. Ils ne sont qu'un champ comme n'importe quel autre qui arrive à contenir des données correspondant au champ / données équivalentes dans une autre table. Après tout, laissez tomber une clé étrangère sur une grande table est presque instantanée. Si c'était une référence, le SGBD devrait copier sur les données réelles maintenant que la référence est partie.



6
votes

c'est correct.

Vous devez avoir xxx

où ID est une clé primaire. Dans votre deuxième table, vous utiliserez uniquement l'identifiant de cette table. Cela vous permettra d'économiser de l'espace physique et de faire fonctionner vos déclarations de sélection plus rapidement. de
En outre, cette structure vous rendrait très facile pour vous d'ajouter de nouveaux fruits.


0 commentaires

4
votes

au lieu de répéter que les données (en moyenne) un quart de fois chacun, si je l'extrait dans une autre table qui a une colonne de fruits et juste ces quatre rangées, puis rendez la colonne originale une clé étrangère, Cela fait-il gagner de l'espace?

Non si le "fruit" est la clé primaire de la table "Recherche", il doit également être la clé étrangère dans la "grande" table.

Toutefois, si vous faites une petite clé primaire de substitution (telle que "ID" entier ") dans la table" Recherche "et utilisez-la comme la clé étrangère de la table" Grande ", vous économiserez de l'espace.


0 commentaires

2
votes

Au début Oui, il sauvera l'espace car int - 4 octets, Tinyint - 1 octet. Deuxièmement, la recherche de ce champ avec le type INT sera plus rapide que par Varchar. En plus de cela, vous pouvez utiliser Enum si vos données ne changent pas à l'avenir. Avec Enum, vous obtiendrez le même résultat plus rapide que de la table secondaire et vous éviterez une jointure supplémentaire.


0 commentaires

2
votes

La normalisation ne concerne pas seulement l'espace, il s'agit souvent de la redondance et de la modélisation du comportement des données et de la mise à jour d'une seule ligne pour une modification - et de réduire la portée des verrous en mettant à jour la quantité minimale de données.


0 commentaires

1
votes

Malheureusement, vous supposez mal: les valeurs sont physiquement stockées à plusieurs reprises pour chaque table de référencement. Certains produits SQL stockent la valeur juste une fois que la plupart ne le font pas, notamment les plus populaires qui sont basés sur un stockage contigu sur le disque.

Ceci est la raison pour laquelle les utilisateurs finaux ressentent la nécessité de mettre en œuvre leurs propres points dans la bande d'utilisation des «clés de substitution» entier. Un service de substitution système serait préférable par exemple. ne serait pas visible pour les utilisateurs, de la même manière, les «valeurs» d'un indice sont maintenues par le système et ne peuvent pas être manipulées directement par les utilisateurs. Le problème de rouler le vôtre est qu'ils font partie du modèle logique.


0 commentaires