为什么人们在历史上为什么使用255而不是256来表示数据库场大小?


189

您经常看到数据库字段设置为255个字符,为什么是传统/历史原因?我认为这与分页/内存限制和性能有关,但是255和256之间的区别始终使我感到困惑。

varchar(255)

考虑到这是容量或大小,而不是索引器为什么255优于256?是否为某个目的保留了一个字节(终止符或null或其他内容)?

大概varchar(0)是废话(容量为零)吗?在这种情况下,2 ^ 8的空间肯定是256?

还有其他提供性能优势的幅度吗?例如,varchar(512)的性能是否比varchar(511)或varchar(510)低?

所有新旧关系数据库的值均相同吗?

免责声明 -我不是DBA开发人员,我使用适合我的业务逻辑的字段大小和类型,但是我想知道这种偏好的历史原因,即使它不再相关(但如果仍然有用,则更多)。

编辑:

感谢您的回答,似乎有人同意使用字节来存储大小,但这在我心中并没有最终解决问题。

如果元数据(字符串长度)存储在相同的连续内存/磁盘中,则是有意义的。1个字节的元数据和255个字节的字符串数据非常适合彼此,并适合256个连续字节的存储,这大概是整齐的。

但是...如果将元数据(字符串长度)与实际的字符串数据分开存储(也许在主表中),则将字符串数据的长度限制为一个字节,只是因为更容易存储一个1字节的整数元数据似乎有点奇怪。

在这两种情况下,似乎都是很微妙的,可能取决于数据库的实现。使用255的做法似乎已经很普遍了,所以某处某人一定在一开始就为它辩护了一个很好的案例,有人能记得那个案例是/是什么吗?程序员将无缘无故地采取任何新做法,而这一定是一次新的。


3
因为字符计数从0开始到N-1。因此,将256个字符声明为varchar(255)。除非我弄错了。
Buhake Sindi

3
也许是因为IT人员从0开始计数,而不是1;)?
罗曼·林索拉斯

我认为这与老派程序员有关,甚至不记得我们为什么这么做。
脾气暴躁

7
@Elite Gentleman:不,括号中的数字是真实长度...就像在C数组声明中一样:x [256]给出x [0] ... x [255]。
RedPandaCurios

@romaintaz-但考虑可以存储1个项目的数组。您声明它为[1],然后访问它为[0]。问题是,为什么在SQL中我们声明容量比乍看之下逻辑上少1个字节。
Andrew M

Answers:


167

DBMS的最大长度为255个字符,可以选择使用单个字节来指示字段中数据的长度。如果限制为256或更大,则需要两个字节。

长度为零的值对于varchar数据当然是有效的(除非另有限制)。大多数系统将这样的空字符串与NULL区别开来,但是某些系统(特别是Oracle)将空字符串与NULL相同。对于空字符串不为NULL的系统,将需要在该行中的某个位置附加一个位,以指示该值是否应被视为NULL。

如您所述,这是历史性的优化,可能与当今的大多数系统无关。


保留一个字节的长度是有意义的,但是WRT您的第二个参数(假定一个/ value /长度为零)是有效的,但是/ capacity /长度为零是有效的吗?
安德鲁·M

1
@Andrew:我刚刚尝试过,而PostgreSQL拒绝了varchar(0)。它可能没有那么有用,因为该值只能是两件事,即空字符串或NULL,因此您也可以仅使用a bit
格雷格·希吉尔

因此,假设容量元数据与数据本身存储在同一连续块中是正确的,因此DB将这两项内容(数据和元数据)的总和保持在一页(大概256个)之内是一个优势。个字节)?
Andrew M

@Andrew:这是一个可能正确或不正确的假设,具体取决于所讨论的DBMS的实现细节。页面大小通常远大于256个字节。正如我提到的那样,这种优化有时很重要(例如,如果您要存储数十亿个小行),但是大多数时候都不用担心。
格雷格·希吉尔

3
磁盘空间(和索引空间)的重要性不是因为256个页面中可以容纳256个字节,而是因为1字节对2字节(对于百万/十亿/万亿行)有很大的不同。
ypercubeᵀᴹ


19

255是可以存储在单字节无符号整数(假设为8位字节)中的最大数值-因此,出于某种目的存储字符串长度的应用程序将首选255而不是256,因为这意味着它们只需要为“ size”变量分配1个字节。


17

从MySQL手册:

数据类型:
VARCHAR(M),VARBINARY(M)

需要存储:
如果列值需要0 – 255字节,则L + 1字节;如果值可能需要超过255字节,则L + 2字节

了解并做出选择。


是的,但是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

最大长度为255,数据库引擎只能使用1个字节来存储每个字段的长度。您是正确的,因为1个字节的空间允许您存储2 ^ 8 = 256个字符串长度的不同值。

但是,如果允许该字段存储长度为零的文本字符串,则需要能够以长度存储零。因此,您可以允许256个不同的长度值,从零开始:0-255。


6

varchar通常以pascal字符串形式实现:将实际长度保留在字节#0中。因此,长度限制为255。(一个字节的值在0到255之间变化。)


5

<<

回顾了位/字节存储的基础知识,它需要一个字节来存储256以下的整数,而对于256和65536之间的任何整数则需要两个字节。因此,它需要相同的空间(两个字节)来存储511或512或就此65535 ....因此,很明显,上面讨论中提到的this参数对于varchar(512)或varchar(511)是N / A。


4

8位无符号= 256字节

255个字符+字节0的长度


3

过去,所有字符串都需要NUL终止符或“反斜杠零”。更新的数据库没有那个。它是“ 255个字符的文本”,最后自动添加了“ \ 0”,因此系统知道字符串的结尾。如果您说VARCHAR(256),它将最终为257,然后您将在下一个寄存器中输入一个字符。浪费。这就是为什么所有内容都是VARCHAR(255)和VARCHAR(31)的原因。出于习惯,255似乎一直存在,但是31变成了32,而511变成了512。那部分很奇怪。让自己写VARCHAR(256)很难。


0

我认为这可能会回答您的问题。看起来这是早期系统中varchar的最大限制。我把它从另一个stackoverflow问题中删除了。

当然,很难知道最长的邮政地址是什么,这就是为什么很多人选择长于任何地址的VARCHAR的原因。通常使用255,因为它可能是某些数据库中VARCHAR的最大长度(在最近的时候以及在PostgreSQL中)。

对所有基于文本的字段使用通用varchar(255)有不利之处吗?


0

数据保存在二进制系统的内存中,0和1是二进制数字。可以容纳1个字节(8位)的最大二进制数是11111111,它将转换为十进制255。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.