我知道在 MySql 表中使用文本类型字段时,数据不是内联存储的,而只有一个“指针”存储在行中。我只想不经常检索文本字段,所以最好将它保存在同一个表中但从查询结果中省略它,或者将它保存在一个单独的表中并在我想阅读它时加入该表?
该表可能有数十亿行,被分区并且具有大的(100k -> 1Mb)文本字段值。
我知道在 MySql 表中使用文本类型字段时,数据不是内联存储的,而只有一个“指针”存储在行中。我只想不经常检索文本字段,所以最好将它保存在同一个表中但从查询结果中省略它,或者将它保存在一个单独的表中并在我想阅读它时加入该表?
该表可能有数十亿行,被分区并且具有大的(100k -> 1Mb)文本字段值。
至少可以说,具有 100k 字段的十亿行很大。这相当于 100 TB 的数据(使用美国对“太字节”的定义)。根据文档:
InnoDB 存储引擎在可以从多个文件创建的表空间中维护 InnoDB 表。这使表能够超过单个文件的最大大小。表空间可以包括原始磁盘分区,这允许非常大的表。最大表空间大小为 64TB。
换句话说,您可能会遇到比性能更大的问题。您可能会将表分布在多个分区中。
如果您只是偶尔检索文本并且从不使用它进行搜索,我建议您将其存储在单独的表中。这样,您可以自定义该表以访问这些记录。您将拥有一个用于参考的主键,所有参考都将通过该 ID。
如果您使用文本进行搜索,特别是与“固定”数据结合的搜索,那么我的架构偏好是将其包含在基表中以方便跨字段搜索。
然而,即使有这种偏好,将它放在不同的表中可能更安全。例如,MySQL 实例化子查询。*
用于子查询是非常典型的。考虑一个简单的例子:一个查询以获取按用户 ID 排序的 1000 条最新记录:
select t.*
from (select t.*
from t
order by createddate
limit 1000
) t
order by userid
的使用t.*
意味着文本列也将被检索。因此,可能需要几分之一秒(带有索引)的查询必须读取和写入 1000*100k = 100 MB 的数据(至少)。这可能需要更长的时间。
总之,我主张将文本列放在一个经常与其他列一起搜索的表格中——例如,放在科学论文摘要的数据库中。对于非常大的数据,我会把它放在一个单独的字段中,这样在极端情况下我可以更好地管理存储。
My take on it:
normally, I would say it is unnecessary complicated to have a reference to a pointer to the text, especially when dealing with multiple joins, potential partitioning etc.
on the other hand, that's quite a monster of a table. If you ever forget to exclude the text field or maybe have someone, that is not well informed about your data structure, working on the same database, who may issue a simple SELECT * FROM monstertable
...well, depending on your server, it could kill/stall it for quite some time.
In short: for performance, one single table should be a bit better, for security/stability it may be better to separate.
a sidenode: I would ask myself if MySQL or even a relational database at all is the right tool for this task (and spend endless hours searching for alternatives, get yelled at and just use MySQL, as it is already installed everywhere and well integrated ;) )