TINYTEXT 作为 MySQL 中的主键?

Kir*_*kan 3 mysql tinytext

表中的条目由 5-10 个字符长的单词唯一标识,并且我对列使用 TINYTEXT(10)。但是,当我尝试将其设置为主键时,我收到size丢失的错误。

根据我对文档的有限理解,Size主键可用于简化检测唯一值的方法,即当前几个字符(由 指定Size)足以将其视为唯一匹配时。在我的例子中,长度size从 5 到 10 不等(它们都是 latin1,所以它们是每个字符的精确字节 + 1 的长度)。两个问题:

  1. 如果我想使用 TINYTEXT 作为主键,size我应该指定哪个?在本例中最多可用 - 10?或者应该是size 严格精确的,例如,如果我的密钥是 6 个字符长的单词,但我将SizePK 指定为 10 - 它会尝试读取所有 10 个字符,并且会失败并抛出异常?
  2. 使用 [TINY]TEXT 进行 PK 性能会有多差?所有 Google 结果都让我得出意见和声明“这很糟糕,你被解雇了”,但考虑到 TINYTEXT 的最大长度为 255 并且我已经将最大长度指定为 10,在这种情况下真的是这样吗?

Phi*_*rov 5

  1. MySQL/MariaDB 只能索引文本字段的第一个字符,但如果文本太大则不能索引整个文本。最大密钥大小为 3072 字节,任何大于此大小的文本字段都不能用作 KEY。因此,对于长度超过 3072 字节的文本字段,您必须明确指定它将索引多少个字符。当使用 VARCHAR 或 CHAR 时,可以直接完成,因为您在声明数据类型时显式设置了它。*TEXT 的情况并非如此 - 他们没有这个选项。解决方案是像这样创建主键:

    CREATE TABLE mytbl (
        name TEXT NOT NULL,
        PRIMARY KEY idx_name(name(255))
    );
    
    Run Code Online (Sandbox Code Playgroud)

    如果您需要在大于 3072 字节的 VARCHAR 字段、BINARY 字段和 BLOB 上创建主键,可以使用相同的技巧。不管怎样,你可以想象,如果两个大的、不同的文本在开头的前 3072 字节处以相同的字符开头,那么它们将被系统视为相等。这可能是个问题。

  2. 使用文本字段作为主键通常是个坏主意。原因有二:

    2.1. 与使用整数在表中搜索(WHERE、JOINS 等)相比,它需要更多的处理时间。该链接已旧,但仍然相关;

    2.2. 另一个表中的任何外键必须与主键具有相同的数据类型。当您使用文本时,这会浪费磁盘空间;

注意:*TEXT 和 VARCHAR 之间的区别在于 *TEXT 字段的内容不存储在表内部,而是存储在外部内存位置。通常,当我们需要存储非常大的文本时,我们会这样做。