为什么阿里巴巴的 Java 开发手册说 text 要独立出来一张表?

2020-08-27 17:57:51 +08:00
 JasonLaw

p3c/Java 开发手册(嵩山版).pdf at master · alibaba/p3c中,它说:

[强制] varchar 是可变长字符串,不预先分配存储空间,长度不要超过 5000,如果存储长度大于此值,定义字段类型为 text,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

它说的“避免影响其它字段索引效率”到底是什么?

关于 varchar 和 text,我找了相关的资料。

建表规约 text 类型独立出一张表避免影响其他字段索引效率? · Issue #641 · alibaba/p3c:这是相关人员的回复,但是并没有解答我的问题。

MySQL :: MySQL 8.0 Reference Manual :: 15.10 InnoDB Row Formats - COMPACT Row Format中,它说“Tables that use the COMPACT row format store the first 768 bytes of variable-length column values (VARCHAR, VARBINARY, and BLOB and TEXT types) in the index record within the B-tree node, with the remainder stored on overflow pages.”。mysql - In what cases are BLOB and TEXT stored in-line on InnoDB? - Database Administrators Stack Exchange也讨论了这个问题。

那么,阿里巴巴所说的到底是什么?真的有必要这么做吗?

7685 次点击
所在节点    MySQL
40 条回复
PopRain
2020-08-27 18:05:01 +08:00
如果记录太大,这种一般都不是每次查询都要访问到的数据,放在主表增加了数据库 IO ( 需要访问更多的 Page)
chanywn1
2020-08-27 18:11:17 +08:00
使用 select 指定字段可显著提高查询速度
nekolr
2020-08-27 18:16:26 +08:00
MySQL 的数据页默认为 16 KB,而行记录最大为 65535 字节,如果某些字段较大可能会导致一页放不下一条记录而导致行记录溢出。

它的意思大概是,如果字段过长,可能会导致一页放不了很多条记录(如果使用的是 Compact Row Format,即使通过页分裂也需要至少存储 768 字节的数据和一个溢出页地址 ),不如直接把长字段放到别的表中,这样该表中的字段都是短字段,一页中可以放更多的数据。
nekolr
2020-08-27 18:19:44 +08:00
对,我说了这么多,其实根本原因就是一楼说的那样。
statement
2020-08-27 18:29:12 +08:00
这种手册有看的必要?
JasonLaw
2020-08-27 18:31:48 +08:00
@PopRain
@nekolr

我明白你们所说的,将不常用字段放在附加表可以让一页可以存储主表更多的纪录。可能我没有表达清楚我的问题,我最大的疑问是为什么要将 varchar 换为 text 呢?它们的表现基本是一样的。
JasonLaw
2020-08-27 18:33:56 +08:00
@statement 其实我是没怎么看的,因为它只说了应该怎么做,但是没有解释为什么这么做好,为什么这么做不好。
CRUD
2020-08-27 18:36:14 +08:00
varchar 有最大长度限制的,最大长度不够用才换 text
JasonLaw
2020-08-27 18:46:25 +08:00
@CRUD https://dev.mysql.com/doc/refman/8.0/en/string-type-syntax.html 关于 varchar:A variable-length string. M represents the maximum column length in characters. The range of M is 0 to 65,535. 关于 text:A TEXT column with a maximum length of 65,535 (216 − 1) characters.
OysterQAQ
2020-08-27 19:07:05 +08:00
除非你查询直接到落到表上 而不是索引上,我记得大字段是会自己独立出去的 高性能 mysql 上有瞄一眼
CRUD
2020-08-27 19:28:05 +08:00
@CRUD #8 丢人了 比 varchar 存储空间更大的是 longtext,查了一下,看到的比较也只是说明索引的问题和在不知道长度的情况下使用 text,没找到与长度超过 5000 时 varchar 换 text 的答案..
cnoder
2020-08-27 19:43:48 +08:00
为什么超过 5000 要改为 text ?
varchar 会算在行记录 65535 字节中,text 不占用
为什么 text,独立出来一张表?
我也不懂
JasonLaw
2020-08-27 19:53:30 +08:00
@cnoder 你说“ varchar 会算在行记录 65535 字节中,text 不占用”,text 不占用是什么?能具体解释一下吗?
zsdroid
2020-08-27 20:23:23 +08:00
SELECT `desc` FROM `table` GROUP BY `other_id` ORDER BY `id`;

desc 字段如果是 text 类型,会创建磁盘临时表
BQsummer
2020-08-27 23:09:52 +08:00
1. 用 text 一般是长度限制
2. 分表是因为会影响 io,哪怕你 select 的时候不选这一列(1 楼是对的)
JasonLaw
2020-08-27 23:30:35 +08:00
@BQsummer #15

你说“用 text 一般是长度限制”,什么长度限制?我在 9 楼已经回复了关于 varchar 和 text 容量的问题,它们的最大容量是一样的。

关于“使用附加表存储 text”,如果不是顺序获取 clustered index 中的 index record 之类的话,其实根本没有什么影响,比如直接通过主键 id 获取唯一的一行数据的时候。
littlewing
2020-08-28 00:03:20 +08:00
估计是怕有人老是 select *
crclz
2020-08-28 07:47:10 +08:00
因为其他字段相当于元数据,TEXT 相当于数据。
JasonLaw
2020-08-28 07:56:02 +08:00
@crclz 你在说什么?能够详细解释一下吗?
atonku
2020-08-28 08:35:06 +08:00
因为他们都不遵循这个规定

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/701984

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX