web-dev-qa-db-fra.com

Quels sont les avantages des bases de données relationnelles en définissant un type de données prédéfini pour chaque colonne?

Je travaille avec une base de données SQL en ce moment, et cela m'a toujours rendu curieux, mais les recherches Google ne se révèlent pas beaucoup: pourquoi les types de données stricts?

Je comprends pourquoi vous auriez quelques types de données différents, par exemple comme l'importance de différencier les données binaires et les données en texte brut . Plutôt que de stocker les 1 et les 0 des données binaires sous forme de texte en clair, je comprends maintenant qu'il est plus efficace de stocker les données binaires dans son propre format.

Mais ce que je ne comprends pas , c'est l'avantage d'avoir autant différents types de données:

  • Pourquoi mediumtext, longtext et text?
  • Pourquoi decimal, float et int?
  • etc.

Quel est l'avantage de dire à la base de données "Il n'y aura que 256 octets de données en texte brut dans les entrées de cette colonne." ou "Cette colonne peut contenir jusqu'à 16 777 215 octets de texte"?

Est-ce un avantage de performance? Dans l'affirmative, pourquoi la connaissance de la taille de l'entrée avant la main améliore-t-elle les performances? Ou plutôt est-ce autre chose?

44
john doe

SQL est une langue de type statique . Cela signifie que vous devez savoir de quel type est une variable (ou un champ, dans ce cas) avant de pouvoir l'utiliser. C'est l'opposé des langages à typage dynamique, où ce n'est pas nécessairement le cas.

À sa base, SQL est conçu pour définir les données ( DDL ) et accéder aux données ( DML ) dans un moteur base de données relationnelle . Le typage statique présente plusieurs avantages par rapport au typage dynamique pour ce type de système.

  • Index , utilisé pour accéder rapidement à des enregistrements spécifiques, fonctionne très bien lorsque la taille est fixe. Considérons une requête qui utilise un index, éventuellement avec plusieurs champs: si les types et tailles de données sont connus à l'avance, je peux comparer très rapidement mon prédicat (clause WHERE ou critères JOIN) aux valeurs de l'index et trouver plus rapidement les enregistrements souhaités .

  • Considérez deux valeurs entier . Dans un système de type dynamique, ils peuvent être de taille variable (pensez Java BigInteger, ou les entiers de précision arbitraire intégrés de Python). Si je veux comparer les entiers, Je dois d'abord connaître leur longueur en bits. Il s'agit d'un aspect de la comparaison d'entiers qui est largement masqué par les langages modernes, mais qui est très réel au niveau du processeur. Si les tailles sont fixes et connues à l'avance, une étape entière est supprimée de Encore une fois, les bases de données sont censées être en mesure de traiter des millions de transactions le plus rapidement possible.

  • SQL a été conçu dans les années 1970. Dans les premiers jours de la micro-informatique, la mémoire était précieuse. La limitation des données a permis de contrôler les exigences de stockage. Si un entier ne dépasse jamais un octet, pourquoi lui allouer plus de stockage? C'est de l'espace perdu à l'ère de la mémoire limitée. Même dans les temps modernes, ces octets supplémentaires gaspillés peuvent s'additionner et tuer les performances du cache d'un processeur. N'oubliez pas que ce sont des moteurs de base de données qui peuvent traiter des centaines de transactions par seconde, pas seulement votre petit environnement de développement.

  • Dans le cadre d'un stockage limité, il est utile de pouvoir tenir un seul enregistrement dans une seule page en mémoire. Une fois que vous avez parcouru une page, il y a plus de sauts de page et un accès mémoire plus lent. Les moteurs plus récents ont des optimisations pour rendre cela moins problématique, mais il est toujours là. En dimensionnant correctement les données, vous pouvez atténuer ce risque.

  • Moreso dans les temps modernes, SQL est utilisé pour se connecter à d'autres langues via ORM ou ODBC ou une autre couche. Certaines de ces langues ont des règles sur la nécessité de types statiques forts. Il est préférable de se conformer aux exigences les plus strictes, car les langages à typage dynamique peuvent traiter les types statiques plus facilement que l'inverse.

  • SQL prend en charge le typage statique car les moteurs de base de données en ont besoin pour les performances, comme indiqué ci-dessus.

Il est intéressant de noter qu'il existe des implémentations de SQL qui ne sont pas fortement typées. SQLite est probablement l'exemple le plus populaire d'un tel moteur de base de données relationnelle. Là encore, il est conçu pour une utilisation à un seul thread sur un seul système, de sorte que les problèmes de performances peuvent ne pas être aussi prononcés que par ex. une base de données Oracle d'entreprise traitant des millions de demandes par minute.

50
user22815

Premièrement: le texte brut est binaire (ce n'est même pas l'UTF8 ou ASCII caractères "0" et "1" mais bits marche/arrêt réels)

Cela dit, certaines des raisons sont les suivantes:

  • Contraintes commerciales/de conception: autoriser le nombre 7626355112 dans la colonne HAUTEUR de la table PERSON serait erroné. Autoriser "Howya" dans la colonne DATE d'une FACTURE serait une erreur.
  • Code moins sujet aux erreurs: vous n'avez pas à écrire de code pour vous assurer que les données extraites d'une colonne de date sont vraiment une date. Si les types de colonne étaient dynamiques, vous devrez effectuer de nombreuses vérifications de type lors de leur lecture.
  • Efficacité informatique: Si une colonne est de type INTEGER, et que vous la SUM (), le SGBDR n'a pas à appliquer d'arithmétique à virgule flottante.
  • Efficacité du stockage: indiquant qu'une colonne est VARCHAR (10) permet au SGBDR d'allouer plus précisément l'espace.
  • Intégrité et unicité référentielles: PK (ou FK) d'une table ne devrait pas autoriser les flottants, car l'égalité en virgule flottante est délicate, vous devez donc les déclarer dans un type non flottant, comme des caractères ou un entier.
  • Il existe des SGBDR avec des types de colonnes dynamiques (non stricts) (SQLite) . Il utilise le concept de "type affinité" tout en vous permettant d'insérer pratiquement n'importe quoi dans n'importe quelle colonne sans vous plaindre. Il y a des compromis qui ne seront pas discutés ici. Voir cette question .
24
Tulains Córdova

C'est pour que le code sous-jacent dans lequel la base de données est écrite puisse allouer et utiliser des enregistrements de taille fixe, s'il sait qu'un champ spécifique peut contenir 0 à 256 caractères de texte, il peut allouer un bloc de 256 octets pour le stocker.

Cela rend les choses beaucoup plus rapides, par exemple vous n'avez pas à allouer de stockage supplémentaire au fur et à mesure que l'utilisateur tape, car un champ donné commence toujours x octets dans l'enregistrement, une recherche ou une sélection sur ce champ sait toujours vérifier x octets dans chaque enregistrement, etc.

8
Steve Barnes

Lorsque les colonnes d'une base de données reçoivent des types définis, les types sont généralement définis eux-mêmes pour avoir une certaine taille en bits. Par conséquent:

1) lorsque le moteur de base de données parcourt les lignes d'une table, il n'a pas à effectuer d'analyse syntaxique pour déterminer où se termine chaque enregistrement, il peut simplement savoir que chaque ligne se compose, disons, de 32 octets, et donc pour obtenir le enregistrement suivant, il suffit d'ajouter 32 octets à l'emplacement actuel des enregistrements.

2) lorsque vous recherchez un champ dans une ligne, il est possible de connaître à nouveau un décalage exact pour ce champ sans analyser quoi que ce soit, de sorte que les recherches de colonnes sont une opération arithmétique simple plutôt qu'une opération de traitement de données potentiellement coûteuse.

6
UserNotFound

Vous avez demandé pourquoi Les SGBD ont des types de données statiques.

  1. Vitesse de recherche. L'intérêt d'un SGBD est de stocker beaucoup plus de données que vous ne pourriez en charger dans un programme. Pensez "à tous les bordereaux de cartes de crédit générés dans le monde au cours des dix dernières années". Afin de rechercher efficacement ces données, des types de données de longueur fixe sont utiles. Cela est particulièrement vrai pour les données structurées comme les horodatages et les numéros de compte. Si vous savez à quoi vous avez affaire à l'avance, il est plus facile de charger dans des index efficaces.

  2. Intégrité et contraintes. Il est plus facile de garder les données propres si elles ont des types de données fixes.

  3. Histoire. Les SGBDR ont commencé lorsque les ordinateurs ne disposaient que de quelques mégaoctets de RAM et le stockage à l'échelle du téraoctet était extrêmement coûteux. L'enregistrement d'une douzaine d'octets dans chaque ligne d'une table pourrait permettre d'économiser des milliers de dollars et des heures dans ces circonstances.

  4. La malédiction de la clientèle. Les SGBDR sont aujourd'hui des progiciels très complexes et hautement optimisés, et ils sont utilisés depuis des décennies pour accumuler des données. Ils sont matures. Ils travaillent. Un crash du SGBDR entraînant une perte de données à grande échelle est d'une rare vanité ces jours-ci. Passer à quelque chose avec un système de saisie de données plus flexible ne vaut ni le coût ni le risque pour la plupart des organisations.

Analogie: il peut être évident que les systèmes de métro urbains fonctionneraient mieux (plus silencieux, plus rapidement, plus économes en énergie) sur une voie ferrée plus étroite. Mais comment allez-vous changer tous les Rails dans le système de métro de New York pour réaliser ces améliorations? Vous ne le faites pas, alors vous optimisez ce que vous avez.

3
O. Jones

En général, plus vous expliquez à la base de données ce que vous stockez, plus elle peut essayer d'optimiser diverses mesures de performances liées à ces données, tels que la quantité d'espace à allouer sur le disque ou la quantité de mémoire à allouer lors de sa récupération.

Pourquoi mediumtext, longtext et text?

Je ne sais pas quelle base de données vous utilisez donc je vais devoir deviner: Je suppose que deux de ces types de données ont des limites supérieures, l'un d'eux ne l'est pas. L'utilisation de types de données pour du texte ayant des limites supérieures indique à la base de données l'espace de stockage dont elle aura besoin pour chaque enregistrement. Il est également possible que certaines bases de données aient différentes façons de stocker du texte volumineux (éventuellement illimité) par rapport à du texte de petite taille fixe (cela peut varier selon la base de données, consultez votre manuel pour voir le vôtre).

Pourquoi décimal, float et int?

Différents niveaux de précision nécessitent différentes quantités de stockage, et chaque utilisation ne nécessite pas les plus hauts degrés de précision. Par exemple, voir ici: https://docs.Oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF5095

Oracle a un certain nombre de types numériques différents avec des exigences de stockage et des capacités différentes en termes de niveau de précision et de taille de nombre qui peuvent être représentés.

Dans une certaine mesure, c'est historique.

Il était une fois, des données tabulaires étaient stockées dans des fichiers composés d'enregistrements de longueur fixe à leur tour composés de champs prédéfinis de sorte qu'un champ donné était toujours du même type et au même endroit dans chaque enregistrement. Cela a rendu le traitement efficace et a limité la complexité du codage.

Ajoutez quelques index à un tel fichier et vous avez les débuts d'une base de données relationnelle.

Au fur et à mesure de l'évolution des bases de données relationnelles, ils ont commencé à introduire davantage de types de données et d'options de stockage, notamment du texte de longueur variable ou des champs binaires. Mais cela a introduit des enregistrements de longueur variable et a rompu la possibilité de localiser de manière cohérente les enregistrements via des calculs ou des champs via un décalage fixe. Peu importe, les machines sont beaucoup plus puissantes aujourd'hui qu'elles ne l'étaient à l'époque.

Parfois, il est utile de définir une taille spécifique pour un champ pour aider à appliquer un peu de logique métier - par exemple 10 chiffres pour un numéro de téléphone nord-américain. La plupart du temps, il s'agit simplement d'un héritage informatique.

2
Zenilogix

Pour beaucoup de ce que vous faites en tant que développeur Web, il n'est pas nécessaire de comprendre ce qui se passe "sous le capot". Il y a des moments, cependant, où cela aide.

Quel est l'avantage de dire à la base de données "Il n'y aura que 256 octets de données en texte brut dans les entrées de cette colonne." ou "Cette colonne peut contenir jusqu'à 16 777 215 octets de texte"?

Comme vous le pensez, la raison est liée à l'efficacité. La fuite des abstractions . Une requête comme SELECT author FROM books peut s'exécuter assez rapidement lorsque la taille de tous les champs de la table est connue.

Comme le dit Joel,

Comment une base de données relationnelle met-elle en œuvre SELECT author FROM books? Dans une base de données relationnelle, chaque ligne d'une table (par exemple la table des livres) a exactement la même longueur en octets, et chaque champ est toujours à un décalage fixe depuis le début de la ligne. Ainsi, par exemple, si chaque enregistrement de la table livres fait 100 octets et que le champ auteur est à l'offset 23, il y a des auteurs stockés à l'octet 23, 123, 223, 323, etc. Quel est le code vers lequel se déplacer le prochain enregistrement dans le résultat de cette requête? Fondamentalement, c'est ceci:

pointer += 100;

Une instruction CPU. Faaaaaaaaaast.

La plupart du temps, vous travaillez suffisamment loin des fondements solides pour ne pas avoir à vous en soucier. En tant que développeur Web basé sur PHP, vous souciez-vous du nombre d'instructions CPU que votre code utilise? La plupart du temps, non, pas vraiment. Mais il est parfois utile de le savoir, pour deux raisons: il peut expliquer les décisions prises par vos bibliothèques; et parfois vous devez vous soucier de la vitesse dans votre propre code.

1
TRiG

Si une base de données utilise des enregistrements de taille fixe, tout enregistrement de la base de données continuera de tenir, au même emplacement, même si son contenu est modifié. En revanche, si une base de données essaie de stocker des enregistrements en utilisant exactement la quantité de stockage nécessaire pour leurs champs, le changement du nom d'Emma Smith en Emma Johnson peut rendre son enregistrement trop volumineux pour tenir dans son emplacement actuel. Si l'enregistrement est déplacé vers un endroit avec suffisamment de place, tout index qui garde la trace de l'endroit où il se trouve devra être mis à jour pour refléter le nouvel emplacement.

Il existe différentes manières de réduire les coûts associés à ces mises à jour. Par exemple, si le système conserve une liste de numéros d'enregistrement et d'emplacements de données, cette liste sera la seule chose qui devra être mise à jour si un enregistrement se déplace. Malheureusement, de telles approches ont toujours un coût important (par exemple, pour conserver une correspondance entre les numéros d'enregistrement et les emplacements, il faudrait que la récupération des enregistrements nécessite une étape supplémentaire pour récupérer les données associées à un numéro d'enregistrement donné). L'utilisation d'enregistrements de taille fixe peut sembler inefficace, mais cela rend les choses beaucoup plus simples.

1
supercat