Pourquoi historiquement les gens utilisent-ils 255 et non 256 pour les magnitudes des champs de base de données?


193

Vous voyez souvent des champs de base de données définis pour avoir une magnitude de 255 caractères, quelle est la raison traditionnelle / historique pour laquelle? Je suppose que c'est quelque chose à voir avec les limites de pagination / mémoire et les performances, mais la distinction entre 255 et 256 m'a toujours confondu.

varchar(255)

Considérant qu'il s'agit d'une capacité ou d'une ampleur, et non d'un indexeur , pourquoi 255 est-il préférable à 256? Un octet est-il réservé à certaines fins (terminateur ou nul ou autre)?

Vraisemblablement varchar (0) est un non-sens (a une capacité nulle)? Dans quel cas 2 ^ 8 d'espace devrait-il être égal à 256?

Y a-t-il d'autres grandeurs qui offrent des avantages de performance? Par exemple, varchar (512) est-il moins performant que varchar (511) ou varchar (510)?

Cette valeur est-elle la même pour toutes les bases de données de relations, anciennes et nouvelles?

avertissement - Je suis un développeur et non un DBA, j'utilise des tailles et des types de champs qui correspondent à ma logique métier là où cela est connu, mais j'aimerais connaître la raison historique de cette préférence, même si elle n'est plus pertinente (mais même plus si elle est toujours d'actualité).

Éditer:

Merci pour les réponses, il semble y avoir un consensus sur le fait qu'un octet est utilisé pour stocker la taille, mais cela ne règle pas définitivement le problème dans mon esprit.

Si les métadonnées (longueur de chaîne) sont stockées dans la même mémoire / disque contigu, cela a du sens. 1 octet de métadonnées et 255 octets de données de chaîne, conviendraient très bien et s'inséreraient dans 256 octets contigus de stockage, ce qui est vraisemblablement propre et ordonné.

Mais ... Si les métadonnées (longueur de la chaîne) sont stockées séparément des données de chaîne réelles (dans une table maître peut-être), alors contraindre la longueur des données de la chaîne d'un octet, simplement parce qu'il est plus facile de stocker seulement un entier de 1 octet des métadonnées semble un peu étrange.

Dans les deux cas, cela semble être une subtilité qui dépend probablement de l'implémentation DB. La pratique de l'utilisation de 255 semble assez répandue, donc quelqu'un quelque part a dû plaider une bonne cause pour cela au début, est-ce que quelqu'un peut se rappeler ce qu'était / est ce cas? Les programmeurs n'adopteront aucune nouvelle pratique sans raison, et cela a dû être nouveau une fois.


3
Parce que le nombre de caractères commence de 0 à N-1. Donc, 256 caractères seront déclarés varchar (255). Sauf si je me trompe.
Buhake Sindi le

3
Peut-être parce que les informaticiens commencent à compter avec 0, pas 1;)?
Romain Linsolas le

Je pense que cela a à voir avec les programmeurs de la vieille école, je ne me souviens même pas pourquoi nous l'avons fait.
Grumpy

7
@Elite Gentleman: non, le nombre entre parenthèses est la vraie longueur ... Comme dans les déclarations de tableau C: x [256] donne x [0] ... x [255].
RedPandaCurios

@romaintaz - mais considérez un tableau qui peut stocker 1 élément. Vous le déclarez quelque chose [1] et y accédez quelque chose [0]. La question est de savoir pourquoi en SQL déclarons-nous la capacité inférieure de 1 octet à ce qui semble logique à première vue.
Andrew M

Réponses:


171

Avec une longueur maximale de 255 caractères, le SGBD peut choisir d'utiliser un seul octet pour indiquer la longueur des données dans le champ. Si la limite était de 256 ou plus, deux octets seraient nécessaires.

Une valeur de longueur zéro est certainement valide pour les varchardonnées (sauf contrainte contraire). La plupart des systèmes traitent une telle chaîne vide comme distincte de NULL, mais certains systèmes (notamment Oracle) traitent une chaîne vide de la même manière que NULL. Pour les systèmes où une chaîne vide n'est pas NULL, un bit supplémentaire quelque part dans la ligne serait nécessaire pour indiquer si la valeur doit être considérée comme NULL ou non.

Comme vous le notez, il s'agit d'une optimisation historique et n'est probablement pas pertinente pour la plupart des systèmes actuels.


Réserver un octet pour la longueur a du sens, mais WRT votre deuxième paragraphe, vraisemblablement un / value / de longueur zéro est valide, mais est-ce qu'un / capacité / de longueur zéro est valide?
Andrew M

1
@Andrew: Je viens d'essayer et PostgreSQL rejette varchar(0). Ce n'est probablement pas très utile car la valeur ne peut être que deux choses, la chaîne vide ou NULL, et vous pouvez donc aussi bien utiliser a bitpour cela.
Greg Hewgill

Est-il donc vrai de supposer que les métadonnées de capacité sont stockées dans le même bloc contigu que les données elles-mêmes, et par conséquent, il y a un avantage pour la base de données à conserver le total de ces deux choses (données et métadonnées) sur une page (vraisemblablement 256 octets)?
Andrew M

@Andrew: C'est une hypothèse qui peut être vraie ou non, selon les détails d'implémentation du SGBD en question. Les tailles de page sont généralement bien supérieures à 256 octets. Comme je l'ai mentionné, ce type d'optimisation est parfois important (par exemple, si vous stockez des milliards de petites lignes), mais la plupart du temps, cela ne vaut pas la peine de s'inquiéter.
Greg Hewgill

3
L'importance de l'espace disque (et de l'espace d'index) n'est pas parce que 256 peuvent tenir dans une page mais parce que 1 octet vs 2 octets (pour des millions / milliards / billion de lignes) fait une grande différence.
ypercubeᵀᴹ

35

255 était la limite varchar dans mySQL4 et versions antérieures.

Aussi 255 caractères + terminateur nul = 256

Ou un descripteur de longueur d'octet donne une plage possible de 0 à 255 caractères


Et la lecture char foo[256]est importante car la gestion de la mémoire aime les puissances de 2. voir: stackoverflow.com/questions/3190146/… L' allocation char foo[257]fragmentera la mémoire ou prendra 512 octets.
ebyrob

4
Varchar ne stocke-t-il pas la longueur de la chaîne et n'a donc pas besoin d'un terminateur nul?
Cruncher

19

255 est la plus grande valeur numérique qui peut être stockée dans un entier non signé à un octet (en supposant des octets de 8 bits) - par conséquent, les applications qui stockent la longueur d'une chaîne dans un certain but préféreraient 255 à 256 car cela signifie qu'elles n'ont qu'à allouez 1 octet pour la variable "taille".


17

À partir du manuel MySQL:

Type de données:
VARCHAR (M), VARBINARY (M)

Stockage requis:
L + 1 octets si les valeurs de colonne nécessitent de 0 à 255 octets, L + 2 octets si les valeurs peuvent nécessiter plus de 255 octets

Comprenez et faites un choix.


Oui, mais M represents the declared column length in characters for nonbinary string types and bytes for binary string types. L represents the actual length in bytes of a given string value. dev.mysql.com/doc/refman/5.7/en/storage-requirements.html
DLight


7

Une longueur maximale de 255 permet au moteur de base de données d'utiliser seulement 1 octet pour stocker la longueur de chaque champ. Vous avez raison de dire qu'un octet d'espace vous permet de stocker 2 ^ 8 = 256 valeurs distinctes pour la longueur de la chaîne.

Mais si vous autorisez le champ à stocker des chaînes de texte de longueur nulle, vous devez pouvoir stocker zéro dans la longueur. Ainsi, vous pouvez autoriser 256 valeurs de longueur distinctes, à partir de zéro: 0-255.


6

Souvent, les varchars sont implémentés comme des chaînes pascal: contenant la longueur réelle dans l'octet # 0. La longueur était donc liée à 255. (La valeur d'un octet varie de 0 à 255.)


5

<<

Rappelé les fondamentaux du stockage des bits / octets, il nécessite un octet pour stocker les entiers inférieurs à 256 et deux octets pour tout entier compris entre 256 et 65536. Par conséquent, il nécessite le même espace (deux octets) pour stocker 511 ou 512 ou d'ailleurs 65535 .... Ainsi, il est clair que cet argument mentionné dans la discussion ci-dessus est N / A pour varchar (512) ou varchar (511).


4

8 bits non signés = 256 octets

255 caractères + octet 0 pour la longueur


3

Auparavant, toutes les chaînes nécessitaient un terminateur NUL, ou "backslash-zero". Les bases de données mises à jour n'ont pas cela. C'était "255 caractères de texte" avec un "\ 0" ajouté automatiquement à la fin pour que le système sache où la chaîne se terminait. Si vous disiez VARCHAR (256), cela finirait par être 257 et vous seriez alors dans le registre suivant pour un caractère. Gaspilleur. C'est pourquoi tout était VARCHAR (255) et VARCHAR (31). Par habitude, le 255 semble être resté mais les 31 sont devenus des 32 et les 511 sont devenus des 512. Cette partie est bizarre. C'est difficile de me faire écrire VARCHAR (256).


0

Je pense que cela pourrait répondre à votre question. On dirait que c'était la limite maximale de varchar dans les systèmes précédents. Je l'ai enlevé une autre question de stackoverflow.

Il est difficile de savoir quelle est l'adresse postale la plus longue, bien sûr, c'est pourquoi de nombreuses personnes choisissent un VARCHAR long qui est certainement plus long que n'importe quelle adresse. Et 255 est habituel car il peut avoir été la longueur maximale d'un VARCHAR dans certaines bases de données à l'aube des temps (ainsi que PostgreSQL jusqu'à plus récemment).

Y a-t-il des inconvénients à utiliser un varchar générique (255) pour tous les champs textuels?


0

Les données sont enregistrées en mémoire dans le système binaire et 0 et 1 sont des chiffres binaires. Le plus grand nombre binaire pouvant tenir dans 1 octet (8 bits) est 11111111 qui se convertit en décimal 255.

En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.