当你在 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:
很长的值也存储在后台表中,这样它们就不会影响对较短列值的快速访问。
所以一个大的字符列(例如TEXT
或VARCHAR
没有指定的大小限制)存储在远离主表数据的地方。因此,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 字段时,你应该把它放在一个单独的表中吗?的主要内容,如果未能解决你的问题,请参考以下文章
phpadmin4 支持 postgresql 8.3 吗?