VARCHAR(255) - 或不

建议最大 len

首先,我将提到一些常见的字符串,这些字符串总是十六进制,或者限制为 ASCII。对于这些,你应该指定 CHARACTER SET asciilatin1 没问题),这样就不会浪费空间:

UUID CHAR(36) CHARACTER SET ascii -- or pack into BINARY(16)
country_code CHAR(2) CHARACTER SET ascii
ip_address CHAR(39) CHARACTER SET ascii -- or pack into BINARY(16)
phone VARCHAR(20) CHARACTER SET ascii -- probably enough to handle extension
postal_code VARCHAR(20) CHARACTER SET ascii -- (not 'zip_code') (don't know the max

city VARCHAR(100) -- This Russian town needs 91:
    Poselok Uchebnogo Khozyaystva Srednego Professionalno-Tekhnicheskoye Uchilishche Nomer Odin
country VARCHAR(50) -- probably enough
name VARCHAR(64) -- probably adequate; more than some government agencies allow

**为什么不简单 255?**有两个原因可以避免对所有事物使用(255)的常见做法。

  • 当一个复杂的 SELECT 需要创建临时表(对于子查询,UNIONGROUP BY 等)时,首选的选择是使用 MEMORY 引擎,它将数据放入 RAM 中。但是 VARCHARs 在这个过程中变成了 CHAR。这使得 VARCHAR(255) CHARACTER SET utf8mb4 占用 1020 个字节。这可能导致需要溢出到磁盘,这是较慢的。
  • 在某些情况下,InnoDB 将查看表中列的可能大小,并确定它将太大,中止了一个 CREATE TABLE

VARCHARTEXT

*TEXTCHARVARCHAR 的使用提示,以及一些最佳实践:

  • 永远不要使用 TINYTEXT
  • 几乎从不使用 CHAR - 它是固定长度; 每个字符是 CHARACTER SET 的最大长度(例如,utf8mb4 的 4 个字节/字符)。
  • 使用 CHAR,除非另有说明,否则请使用 CHARACTER SET ascii
  • VARCHAR(n) 将截断 n 个字符 ; TEXT 将截断一些字节数。 (但是,你想截断吗?)
  • 由于如何处理临时表,*TEXT 可能会减慢复杂的 SELECTs