当你在 MySQL 或 PostgreSQL 中有一个 TEXT 字段时,你应该把它放在一个单独的表中吗?

Posted

技术标签:

【中文标题】当你在 MySQL 或 PostgreSQL 中有一个 TEXT 字段时,你应该把它放在一个单独的表中吗?【英文标题】:When you have a TEXT field in MySQL or PostgreSQL, should you put it in a separate table? 【发布时间】:2011-07-13 05:11:15 【问题描述】:

我听说,如果您有一个包含大量文本数据的 TEXT 列的表,最好将该列移动到一个单独的表中并通过 JOIN 将其获取到基本记录。

这是真的吗?如果是,为什么?

【问题讨论】:

【参考方案1】:

不适用于 PostgreSQL,来自the manual:

很长的值也存储在后台表中,这样它们就不会影响对较短列值的快速访问。

所以一个大的字符列(例如TEXTVARCHAR 没有指定的大小限制)存储在远离主表数据的地方。因此,PostgreSQL 内置了“将其放在单独的表中”优化。如果您使用的是 PostgreSQL,请合理安排表并将数据布局留给 PostgreSQL。

我不知道 mysql 或其他 RDBM 是如何排列它们的数据的。

这种优化背后的原因是,数据库通常会将每一行的数据保存在磁盘上的连续块中,以减少需要读取或更新行时的查找。如果一行中有一个 TEXT(或其他可变长度类型)列,那么行的大小是可变的,因此需要更多的工作来逐行进行。类比是访问链表中的某些内容与访问数组之间的区别。对于链表,您必须一次读取三个元素才能到达第四个元素,而对于数组,您只需从开头偏移 3 * element_size 个字节,然后一步到位。

【讨论】:

【参考方案2】:

来自MySQL Manual:

对于有多个列的表,要 减少查询的内存需求 不使用 BLOB 列, 考虑拆分 BLOB 列 放入单独的表并引用 在需要时使用连接查询。

【讨论】:

【参考方案3】:

在某些情况下,这可能是真的。原因是假设您的表是:

create table foo (
    id serial primary key,
    title varchar(200) not null,
    pub_date datetime not null,
    text_content text
);

然后你做这样的查询:

select id, title, pub_date
  from foo;

如果您在该表中没有text_content 字段,您将不得不从磁盘加载更多页面。查询优化主要是为了尽可能减少磁盘 I/O。

【讨论】:

以上是关于当你在 MySQL 或 PostgreSQL 中有一个 TEXT 字段时,你应该把它放在一个单独的表中吗?的主要内容,如果未能解决你的问题,请参考以下文章

当你在太空中死亡时,你身体会发生什么?

KMP详解

phpadmin4 支持 postgresql 8.3 吗?

怎样设置PostgreSQL中字段和表名对大小写敏感

当你在firstVC时如何在secondVC中运行一个函数?

MySQL:ID号自动递增的不一致