【问题标题】:Is there a good reason I see VARCHAR(255) used so often (as opposed to another length)?我看到 VARCHAR(255) 经常使用(而不是另一个长度)有充分的理由吗?
【发布时间】:2010-11-16 02:11:24
【问题描述】:

在多个课程、书籍和工作中,我看到定义为 VARCHAR(255) 的文本字段是“短”文本的默认值。除了a nice round number 之外,还有什么好的理由经常选择 255 的长度?它是否是过去某个时候有充分理由的坚持(无论今天是否适用)?

我当然知道,如果你知道字符串的最大长度,更严格的限制会更理想。但是,如果您使用 VARCHAR(255),这可能表明您不知道最大长度,只是它是一个“短”字符串。


注意:我发现了这个问题 (varchar(255) v tinyblob v tinytext),它说 VARCHAR(n) 需要 n+1 个字节的存储空间用于 n em>n+2 个字节的存储空间用于 n>255。这是唯一的原因吗?这似乎有点武断,因为与 VARCHAR(256) 相比,您只会节省两个字节,并且您可以通过将其声明为 VARCHAR(253) 来轻松节省另外两个字节。

【问题讨论】:

    标签: database database-design types varchar


    【解决方案1】:

    注意:我发现了这个问题 (varchar(255) v tinyblob v tinytext),它说 VARCHAR(n) 需要 n+1 字节的存储空间用于 n em>n+2 个字节的存储空间用于 n>255。这是唯一的原因吗?这似乎有点武断,因为与 VARCHAR(256) 相比,您只会节省两个字节,并且您可以通过将其声明为 VARCHAR(253) 来轻松节省另外两个字节。

    没有。您不会通过声明 253 来节省两个字节。 varchar 的实现很可能是一个长度计数器和一个可变长度、非终止数组。这意味着如果您将“hello”存储在 varchar(255) 中,您将占用 6 个字节:一个字节用于长度(数字 5),5 个字节用于五个字母。

    【讨论】:

    • 此说法并非对所有数据库都适用。许多数据库在表中使用给定大小的 varchar 字段,因此当该字段更改为一行时,它们不必移动行。
    • 是的,你是对的。它依赖于实现。您必须查看供应商手册以了解情况
    • 这可能是允许的,但以这种方式实现VARCHAR 会破坏使用VARCHAR 而不是CHAR 的整个要点
    【解决方案2】:

    0000 0000 -> 这是一个 8 位二进制数。一个数字代表一个位。

    你这样算:

    0000 0000 → (0)

    0000 0001 → (1)

    0000 0010 → (2)

    0000 0011 → (3)

    每个位可以是以下两个值之一:开或关。总的最高数可以用乘法表示:

    2 * 2 * 2 * 2 * 2 * 2 * 2 * 2 - 1 = 255
    

    或者

    2^8 - 1. 
    

    我们减去一个,因为第一个数字是 0。

    255 可以容纳相当多的值(不是双关语)。

    随着我们使用更多位,最大值呈指数增长。因此,出于许多目的,添加更多位是多余的。

    【讨论】:

      【解决方案3】:

      另一个原因可能是在 Windows 上非常古老的数据访问库中,例如 RDO 和 ADO(COM 版本不是 ADO.NET),您必须调用特殊方法 GetChunk,才能从超过 255 个字符的列中获取数据.如果您将 varchar 列限制为 255,则不需要此额外代码。

      【讨论】:

        【解决方案4】:

        从历史上看,在某些 DBMS 中,VARCHAR 的最大长度通常是 255 个字符,如果您想使用 UTF-8 并对列进行索引,有时它仍然是有效的最大值(因为索引长度限制)。

        【讨论】:

        • @CharlesBretana:如果您阅读您引用的其余句子,您会找到您要求的确切解释。
        • @CharlesBretana:“假 UTF-8”是指 MySQL 的“utf8”编码,正如我所提到的,每个字符保留(并且仅限于)3 个字节。这不是一个很好的 UTF-8 版本;如果你想在 MySQL 中使用像样的 UTF-8,你必须使用它的“utf8mb4”编码。但是人们更可能不知道这一点并使用“utf8”,并且更可能需要 UTF-8 而不是任何其他编码,因此,他们在 VARCHAR 中的最大可索引长度为 255 个字符。尽管你很惊讶。
        • @CharlesBretana:我现在已经解释了三遍,没有任何改变。 MySQL的索引长度限制仍然是767字节,编码一个3字节UTF-8字符需要的字节数仍然是3,而floor(767 / 3)仍然是255。你决心找点糊涂的信仰.
        • @CharlesBretana(很抱歉迟到了整个聚会)我不是数据库专家,但我认为混乱的意思是:是的,“假 UTF-8”列可以超过255 个字符长,但索引仅适用于 varchar 的前 255 个字符,如果您希望它被完全索引,它实际上是一列的最大值。现在这只是我对他的解释的理解,我可能错了,我根本不是 SQL 索引方面的专家。
        • @CharlesBretana 如果您正确查看 Chaos 的回答,您会注意到它分为两部分:1. Varchar(255) 背后的历史原因如此普遍(它曾经是最大在一些较旧的 DBMS 上),2. 即使在今天,由于前面讨论的索引限制,它仍然是一些限制,第 1 部分和第 2 部分没有链接。第 1 部分是问题的实际答案,第 2 部分是一个与问题仍然相关的旁注,因为它解释了为什么即使在今天它仍然可能是一个限制。 (续 ->)
        【解决方案5】:

        当您说2^8 时,您会得到256,但计算机术语中的数字是从数字0 开始的。所以,然后你得到了255,你可以在 IP 的互联网掩码或 IP 本身中探测它。

        255 是 8 位整数的最大值:11111111 = 255

        这有帮助吗?

        【讨论】:

        • 对于整数,你从 0 开始计数,到 255 结束。但是对于字符串中的位置,你从第 1 位开始计数,所以从第 256 位结束没有意义,因为您从 1 而不是 0 开始?由于 string_length() 结果,我还不完全同意 varchar(256),但我真的不确定。
        • @HoldOffHunger 数据库中的字符串可以有零个字符的长度,所以当长度存储为八位时,允许的长度范围在 0 到 255 之间。如果你想说字符串都是必须至少有一个字符,然后才能支持 8 位长度的 256 个字符的字符串。
        【解决方案6】:

        在许多应用程序中,例如 MsOffice(直到版本 2000 或 2002),每个单元格的最大字符数为 255。将数据从能够处理每个字段超过 255 个字符的程序移入/移出这些应用程序是一场噩梦。目前,限制越来越少。

        【讨论】:

          【解决方案7】:

          可能是因为 SQL Server 和 Sybase(仅举两个我熟悉的)过去在 VARCHAR 列中的字符数最多为 255 个字符。对于 SQL Server,这在 1996/1997 年左右的版本 7 中发生了变化……但旧习惯有时很难改掉。

          【讨论】:

          • +1 用于引用特定的数据库和版本。而“旧习惯难改”可能是最真实的答案。
          【解决方案8】:

          我将回答字面上的问题:,你看到 VARCHAR(255) 经常被使用并不是一个很好的理由(确实有原因 ,正如其他答案中所讨论的,只是不好的)。由于架构师选择了 VARCHAR(300) 而不是 VARCHAR(255),因此您不会找到许多灾难性失败的项目示例。即使您谈论的是 CHAR 而不是 VARCHAR,这也是一个几乎完全无关紧要的问题。

          【讨论】:

          • 255 个字节中的 1 个字节为 0.4%。有时你关心最后半个百分点左右。有时你不知道。如果您的托管和性能成本达到数十美元,您可能不在乎。如果他们达到数百万,他们可能会这样做。
          • @EdwardBrey:如果摩尔定律仍然成立,那么我在这里的回答的有效性是我写它时的 16 倍。
          • 除非我们发现计算机可以帮助我们的方式多出 16 倍。速度仍然是一个特点。
          【解决方案9】:

          使用 255 是因为它是 8 位数字可以计算的最大字符数。它最大限度地利用了 8 位计数,而无需轻率地需要另一个完整字节来计算 255 以上的字符。

          当以这种方式使用时,VarChar 仅使用字节数 + 1 来存储您的文本,因此您最好将其设置为 255,除非您想要对字段中的字符数进行硬限制(例如 50) .

          【讨论】:

          • 我喜欢这句话:“轻率地需要另一个完整的字节”。 =)
          • 这是否适用于 varchars 为 UTF-8 的数据库?
          • @antak:在 MySQL 中,使用 InnoDB,任何键列都不能大于 767 字节。如果 VARCHAR 列是 UTF8(意味着每个 char 最多可能占用 3 个字节),则该列的最大允许长度为 floor(767/3) = 255。我假设正是出于这个原因选择了“767”。
          • 如果字符集是utf8varchar(85) 是交叉提示长度字节从一字节到二字节的限制。如果是utf8mb4,则为varchar(63)。这些很重要,因为它们是VARCHAR's length can be extended through the use of online ALTER TABLE 的最大值。因此,我通过创建一个包含varchar(2) charset utf8 列的表并查看在给定ALGORITHM=INPLACE 的情况下我能够将其扩展多远来得出这些数字。
          • 当您考虑到许多“数据库”过去都存储在磁带上时,这就更有意义了。在大小为 2 的倍数的“块”中读取数据是很常见的。这样,数据的存储效率最高(当您在旧大型机上运行时,像这样的小效率就是“成败”优化)。
          【解决方案10】:

          一个无符号的 1 字节数字可以包含 [0-255] 范围,包括在内。因此,当您看到 255 时,主要是因为程序员以10 为基础思考(明白这个笑话吗?):)

          实际上,在一段时间内,255 是您在 MySQL 中可以提供 VARCHAR 的最大大小,并且在索引和其他问题上使用 VARCHAR 优于 TEXT。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 2013-06-04
            • 1970-01-01
            • 1970-01-01
            • 2018-02-11
            • 2010-11-18
            • 2013-02-07
            • 2011-05-31
            • 2011-02-11
            相关资源
            最近更新 更多