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

varchar(255)

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

想必varchar(0)是一个胡说八道(有零容量)?在哪种情况下2^8的空间应该是256 ?

是否存在其他提供性能好处的级别?例如,varchar(512)的性能是否低于varchar(511)或varchar(510)?

这个值是否适用于所有的关系数据库,无论是旧的还是新的?

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

编辑:

感谢你的回答,似乎有一些共识,字节是用来存储大小的,但这并不能确定地解决这个问题。

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

但是…如果元数据(字符串长度)与实际的字符串数据分开存储(可能在主表中),那么仅仅因为存储1字节整数的元数据更容易,就将字符串数据的长度限制为1字节,这似乎有点奇怪。

在这两种情况下,这似乎都是一个微妙的问题,可能取决于DB实现。使用255的做法似乎很普遍,所以一开始肯定有人在某个地方提出了一个很好的例子,有人记得那个例子是什么吗?程序员不会无缘无故地采用任何新的实践,而这一定曾经是新的。


当前回答

It used to be that all strings required a NUL terminator, or "backslash-zero". Updated databases don't have that. It was "255 characters of text" with a "\0" added automatically at the end so the system knew where the string ended. If you said VARCHAR(256), it would end up being 257 and then you'd be in the next register for one character. Wasteful. That's why everything was VARCHAR(255) and VARCHAR(31). Out of habit the 255 seems to have stuck around but the 31's became 32's and the 511's became 512's. That part is weird. It's hard to make myself write VARCHAR(256).

其他回答

我想这也许能回答你的问题。看起来这是早期系统中varchar的最大限制。我从另一个stackoverflow问题上偷来的。

当然,很难知道最长的邮政地址是什么,这就是为什么许多人选择一个长VARCHAR,它肯定比任何地址都长。255是常用的,因为它可能是早期某些数据库中VARCHAR的最大长度(PostgreSQL直到最近也是如此)。

对所有基于文本的字段使用通用varchar(255)是否有缺点?

是否存在其他提供性能好处的级别?例如,varchar(512)的性能是否低于varchar(511)或varchar(510)?

回顾一下位/字节存储的基本原理,存储256以下的整数需要一个字节,存储256到65536之间的整数需要两个字节。 因此,它需要相同的空间(两个字节)来存储511或512或65535.... 因此,对于varchar(512)或varchar(511),上面讨论中提到的this参数显然是N/A。

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

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

正如你所注意到的,这是一个历史优化,可能与今天的大多数系统无关。

8位unsigned = 256字节

长度为255个字符+字节0

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