web-dev-qa-db-fra.com

Quand utiliser TINYINT sur INT?

En général, j'utilise toujours Ints. Je sais qu'en théorie, ce n'est pas la meilleure pratique, car vous devriez utiliser le plus petit type de données qui sera garanti pour stocker les données.

Par exemple, il est préférable d'utiliser tinyint lorsque vous savez que les seules données que vous stockerez sont 1, 0 ou null (avec une très petite chance de les étendre à 2 ou 3 plus tard).

Cependant, la seule raison que je connais pour cela est à des fins de stockage - en utilisant 1 octet sur une ligne au lieu de 4 octets.

Quels sont les impacts de l'utilisation de tinyint (ou smallint ou même bigint) sur seulement int, à part économiser de l'espace sur votre disque dur?

92
Richard

L'espace disque est bon marché ... ce n'est pas la question!

Arrêtez de penser en termes d'espace de stockage, pensez plutôt au pool de mémoire tampon et bande passante de stockage . À l'extrême, le cache CPU et bande passante du bus mémoire . L'article lié fait partie de la série mettant en évidence les problèmes de mauvaise sélection de clé en cluster (INT vs GUID vs Sequential GUID) mais il met en évidence la différence que les octets peuvent faire.

Le message primordial concerne les questions de conception. La différence n'apparaîtra pas dans une base de données individuelle sur un serveur correctement spécifié jusqu'à ce que vous atteigniez le territoire VLDB, mais si vous pouvez économiser quelques octets, pourquoi ne pas le faire.

Je me souviens de l'environnement décrit dans une question précédente . Plus de 400 bases de données, dont la taille varie de 50 Mo à 50 Go, par instance SQL. Le nettoyage de quelques octets par enregistrement, par table, par base de données dans cet environnement pourrait faire une différence significative.

92
Mark Storey-Smith

En plus des autres réponses ...

Les lignes et les entrées d'index sont stockées dans 8 000 pages. Ainsi, un million de lignes à 3 octets par ligne ne représente pas 3 Mo sur le disque: cela affecte le nombre de lignes par page ("densité de page").

La même chose s'applique à nvarchar à varchar, smalldatetime à datetime, int à tinyint, etc.

Edit, juin 2013

http://sqlblog.com/blogs/joe_chang/archive/2013/06/16/load-test-manifesto.aspx

Cet article déclare

Les critères importants sont la cardinalité et le rapport page/ligne.

Donc, le choix du type de données est important

29
gbn

Ce n'est pas seulement le stockage de table qui est une considération. Si vous utilisez des index où la colonne int fait partie d'une clé composée, vous souhaiterez naturellement que les pages d'index soient aussi complètes que possible, ceci étant le résultat d'entrées d'index aussi petites que possible.

Je m'attendrais certainement à trouver que l'examen des entrées d'index dans les pages BTREE serait un peu plus rapide avec des types de données plus petits. Cependant, tous les VARCHAR impliqués dans les entrées d'index compenseraient (annuleraient) les gains de performances résultant de l'utilisation de TINYINT sur INT.

Néanmoins, si les entrées d'index ont des entrées composées et que toutes sont des entiers, plus les entiers sont petits octets, mieux et plus vite.

14
RolandoMySQLDBA

Tout devient de plus en plus complexe lorsque les bases de données grossissent:

  • les fenêtres de maintenance doivent être agrandies ou reprogrammées
  • sauvegardes (la sauvegarde complète de fin de journée devient un mangeur de temps absurde, vous avez donc besoin d'une sauvegarde différentielle ou même de journaux et effectuez la sauvegarde complète une fois par semaine, peut-être une fois par mois)
  • la maintenance des performances devient un mangeur de temps (la création d'un index sur une table de plusieurs millions de lignes ne prend pas un temps trivial à exécuter) et doit être reprogrammée et s'aggrave si la table est large ...
  • Et transmettre cette sauvegarde de 100 Go via le réseau n'est pas ce que j'appelle un morceau de gâteau - surtout si le réseau (pour une raison inconnue) est obstiné à abandonner la connexion sur la marque 75 Go ... (arrivé avec une installation que je travaillais qui sauvegardait sur un lecteur mappé sur le réseau - réseau) ...

Et quels types de données ont à voir avec ça? TOUT. L'utilisation de tailles de ligne plus grandes que nécessaire fait que les pages de la base de données se remplissent avant que nécessaire ou même gaspille de l'espace si la taille de la ligne est telle qu'aucun enregistrement ne peut être enregistré sur la page. Le résultat est plus de pages nécessaires pour l'écriture et la lecture, plus RAM est utilisée pour mettre en cache cela (les enregistrements plus gros nécessitent plus de mémoire). Et puisque vos types de données sont spécifiés plus gros que nécessaire à partir du disque, vos index subira le même problème - spécialement si vous regroupez cette clé primaire composée de 2 colonnes BIGINT car tout autre index créé copiera cette clé primaire implicitement dans leur définition.

Si vous savez que certaines colonnes d'une table qui auront des millions de lignes ou même une petite table qui seront FK à plusieurs millions de lignes qui n'ont pas besoin d'un entier de 4 octets pour stocker leurs données, mais un 2 octets le ferait suffit - utilisez SMALLINT . Si des valeurs comprises entre 0 et 255 sont suffisantes, TINYINT . Un drapeau Oui/Non? Il y a BIT .

13
Fabricio Araujo

Alors que pour tinyint vs int, il existe des différences évidentes telles que l'espace disque, le fractionnement des pages et le temps de maintenance, il n'y en aurait pas pour varchar.

Alors pourquoi ne pas déclarer tous les champs de texte comme varchar(4000), car il n'utilisera de toute façon que l'espace nécessaire? Encore plus, vous aurez la garantie que vos données ne seront jamais tronquées.

La réponse est bien sûr:

  1. Clarification de vos intentions (car personne ne comprendra pourquoi un champ de nom doit contenir 4 000 caractères)
  2. Validation comme vous voulez vous assurer que personne n'entre une biographie entière comme nom.

Ces mêmes raisons s'appliquent également à tinyint.

9
yoel halb