AskOverflow.Dev

AskOverflow.Dev Logo AskOverflow.Dev Logo

AskOverflow.Dev Navigation

  • 主页
  • 系统&网络
  • Ubuntu
  • Unix
  • DBA
  • Computer
  • Coding
  • LangChain

Mobile menu

Close
  • 主页
  • 系统&网络
    • 最新
    • 热门
    • 标签
  • Ubuntu
    • 最新
    • 热门
    • 标签
  • Unix
    • 最新
    • 标签
  • DBA
    • 最新
    • 标签
  • Computer
    • 最新
    • 标签
  • Coding
    • 最新
    • 标签
主页 / dba / 问题 / 386
Accepted
Derek Downey
Derek Downey
Asked: 2011-01-08 06:52:24 +0800 CST2011-01-08 06:52:24 +0800 CST 2011-01-08 06:52:24 +0800 CST

MySQL VARCHAR 和 TEXT 数据类型有什么区别?

  • 772

在 5.0.3 版之后(允许 VARCHAR 为 65,535 字节并停止截断尾随空格),这两种数据类型之间是否有任何重大区别?

我正在阅读差异列表,唯一值得注意的两个是:

对于 BLOB 和 TEXT 列上的索引,您必须指定索引前缀长度。对于 CHAR 和 VARCHAR,前缀长度是可选的。请参阅第 7.5.1 节,“列索引”。

和

BLOB 和 TEXT 列不能有 DEFAULT 值。

那么,由于对 TEXT 数据类型的这两个限制,为什么要在 varchar(65535) 上使用它呢?两者之间是否存在性能影响?

mysql database-design
  • 2 2 个回答
  • 39237 Views

2 个回答

  • Voted
  1. Best Answer
    Joe
    2011-01-09T04:49:26+08:002011-01-09T04:49:26+08:00

    划分链接到一些解释基本问题的信息(存在性能差异),但要说一个总是比另一个更好还不够简单。(否则,没有理由同时拥有两者。)此外,在 MyISM 中,VARCHAR 的 64k 最大大小不是每个字段 - 它是每个记录。

    基本上,有 4 种方法可以将字符串存储在数据库记录中:

    1. 固定长度
    2. C 样式字符串(在字符串末尾标有 NULL 或类似字符)
    3. Pascal 风格的字符串(几个字节表示长度,然后是字符串)
    4. 指针(将字符串存储在其他地方)

    MyISM 对 VARCHAR 使用类似于 #3 的东西,对 TEXT 使用混合方法,它将字符串的开头存储在记录中,然后将字符串的其余部分存储在其他地方。InnoDB 与 VARCHAR 类似,但将完整的 TEXT 字段存储在记录之外。

    使用 1&4 时,记录中的内容总是相同的长度,因此如果您不需要字符串但需要后面的内容,则更容易跳过。#2 和 #3 对于短字符串来说都不算太糟糕...... #2 必须继续寻找标记,而 #3 可以向前跳过......随着字符串变长,#2 对于这种特殊用途会变得更糟案子。

    如果您确实需要读取字符串,#4 会更慢,因为您必须读取记录,然后读取可能存储在磁盘上其他位置的字符串,具体取决于该数据库如何处理它。#1 总是很简单,你会再次遇到类似的问题,其中 #2 越长字符串越差,而对于非常小的字符串,#3 比 #2 稍差一些,但随着字符串越长越好。

    然后是存储要求......#1始终是固定长度,因此如果大多数字符串不是最大长度,它可能会膨胀。#2 有 1 个额外字节;如果最大长度 = 255,#3 通常有 2 个额外字节,如果最大长度为 64k,则通常有 4 个额外字节。#4 具有指针长度,加上 #3 通常的规则。

    对于 MySQL 5.1 中的具体实现,MyISM state的文档:

    • 支持真正的 VARCHAR 类型;VARCHAR 列以存储在一个或两个字节中的长度开始。
    • 具有 VARCHAR 列的表可能具有固定或动态的行长度。
    • 表中 VARCHAR 和 CHAR 列的长度之和可能高达 64KB。

    而对于 InnoDB:

    • 记录头的可变长度部分包含一个位向量,用于指示 NULL 列。如果索引中可以为NULL的列数为N,则位向量占用CEILING(N/8)个字节。(例如,如果有 9 到 15 列可以为 NULL,则位向量使用两个字节。)为 NULL 的列不占用此向量中的位以外的空间。标题的可变长度部分还包含可变长度列的长度。每个长度占用一个或两个字节,具体取决于列的最大长度。如果索引中的所有列都不是 NULL 并且具有固定长度,则记录头没有可变长度部分。
    • 对于每个非 NULL 可变长度字段,记录头包含一个或两个字节的列长度。仅当列的一部分存储在溢出页的外部或最大长度超过 255 字节且实际长度超过 127 字节时才需要两个字节。对于外部存储的列,两字节长度表示内部存储部分的长度加上指向外部存储部分的 20 字节指针。内部部分为768字节,所以长度为768+20。20 字节指针存储列的真实长度。

    ...

    与处理数据库时的许多其他事情一样,如果您不确定什么最适合您的需求,请尝试使用类似的数据和用法对其进行基准测试,并查看它们的行为方式。

    • 16
  2. Rick James
    2012-04-06T11:51:09+08:002012-04-06T11:51:09+08:00

    当一个 SELECT 需要创建一个临时表(例如对结果进行排序)时,它要么创建一个 MEMORY 表,要么创建一个 MyISAM 表。内存更有效。MEMORY 有一些限制——一个是禁止 TEXT 和 BLOB。因此,使用 TEXT 的 SELECT运行速度可能比使用 VARCHAR 慢。

    • 3

相关问题

  • 是否有任何 MySQL 基准测试工具?[关闭]

  • 我在哪里可以找到mysql慢日志?

  • 如何优化大型数据库的 mysqldump?

  • 什么时候是使用 MariaDB 而不是 MySQL 的合适时机,为什么?

  • 组如何跟踪数据库架构更改?

Sidebar

Stats

  • 问题 205573
  • 回答 270741
  • 最佳答案 135370
  • 用户 68524
  • 热门
  • 回答
  • Marko Smith

    你如何mysqldump特定的表?

    • 4 个回答
  • Marko Smith

    您如何显示在 Oracle 数据库上执行的 SQL?

    • 2 个回答
  • Marko Smith

    如何选择每组的第一行?

    • 6 个回答
  • Marko Smith

    使用 psql 列出数据库权限

    • 10 个回答
  • Marko Smith

    我可以查看在 SQL Server 数据库上运行的历史查询吗?

    • 6 个回答
  • Marko Smith

    如何在 PostgreSQL 中使用 currval() 来获取最后插入的 id?

    • 10 个回答
  • Marko Smith

    如何在 Mac OS X 上运行 psql?

    • 11 个回答
  • Marko Smith

    如何从 PostgreSQL 中的选择查询中将值插入表中?

    • 4 个回答
  • Marko Smith

    如何使用 psql 列出所有数据库和表?

    • 7 个回答
  • Marko Smith

    将数组参数传递给存储过程

    • 12 个回答
  • Martin Hope
    Manuel Leduc PostgreSQL 多列唯一约束和 NULL 值 2011-12-28 01:10:21 +0800 CST
  • Martin Hope
    markdorison 你如何mysqldump特定的表? 2011-12-17 12:39:37 +0800 CST
  • Martin Hope
    Stuart Blackler 什么时候应该将主键声明为非聚集的? 2011-11-11 13:31:59 +0800 CST
  • Martin Hope
    pedrosanta 使用 psql 列出数据库权限 2011-08-04 11:01:21 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 对 SQL 查询进行计时? 2011-06-04 02:22:54 +0800 CST
  • Martin Hope
    Jonas 如何从 PostgreSQL 中的选择查询中将值插入表中? 2011-05-28 00:33:05 +0800 CST
  • Martin Hope
    Jonas 如何使用 psql 列出所有数据库和表? 2011-02-18 00:45:49 +0800 CST
  • Martin Hope
    BrunoLM Guid vs INT - 哪个更好作为主键? 2011-01-05 23:46:34 +0800 CST
  • Martin Hope
    bernd_k 什么时候应该使用唯一约束而不是唯一索引? 2011-01-05 02:32:27 +0800 CST
  • Martin Hope
    Patrick 如何优化大型数据库的 mysqldump? 2011-01-04 13:13:48 +0800 CST

热门标签

sql-server mysql postgresql sql-server-2014 sql-server-2016 oracle sql-server-2008 database-design query-performance sql-server-2017

Explore

  • 主页
  • 问题
    • 最新
    • 热门
  • 标签
  • 帮助

Footer

AskOverflow.Dev

关于我们

  • 关于我们
  • 联系我们

Legal Stuff

  • Privacy Policy

Language

  • Pt
  • Server
  • Unix

© 2023 AskOverflow.DEV All Rights Reserve