带有TEXT列的MySQL InnoDB行限制

问题描述

我有一个aurora MysqL 5.6实例,我试图在其中创建一个包含约200个TEXT列和其他一些列的表。我收到臭名昭著的错误“行大小太大(> 8126)。将某些列更改为TEXT或BLOB可能会有所帮助。在当前行格式中,将0字节的BLOB前缀内联存储。”但是根据我的计算,我的表使用的方式应该少于此。根据{{​​3}},每个TEXT字段仅需要20个字节,因此我看不到为什么会收到此错误。有什么想法吗?

这是声明:

create table IF NOT EXISTS danstest ( entry_id bigint(20) not null,date_created timestamp(3),date_modified timestamp(3),created_by bigint(20),modified_by bigint(20),container_id bigint(20),archived bit(1) not null default 0,`geometry` GEOMETRY,owner bigint(20),mode tinyint(1) default 0,field_0 TEXT comment 'Column 1',field_1 TEXT comment 'Column 2',field_2 TEXT comment 'Column 3',field_3 TEXT comment 'Column 4',field_4 TEXT comment 'Column 5',field_5 TEXT comment 'Column 6',field_6 TEXT comment 'Column 7',field_7 TEXT comment 'Column 8',field_8 TEXT comment 'Column 9',field_9 TEXT comment 'Column 10',field_10 TEXT comment 'Column 11',field_11 TEXT comment 'Column 12',field_12 TEXT comment 'Column 13',field_13 TEXT comment 'Column 14',field_14 TEXT comment 'Column 15',field_15 TEXT comment 'Column 16',field_16 TEXT comment 'Column 17',field_17 TEXT comment 'Column 18',field_18 TEXT comment 'Column 19',field_19 TEXT comment 'Column 20',field_20 TEXT comment 'Column 21',field_21 TEXT comment 'Column 22',field_22 TEXT comment 'Column 23',field_23 TEXT comment 'Column 24',field_24 TEXT comment 'Column 25',field_25 TEXT comment 'Column 26',field_26 TEXT comment 'Column 27',field_27 TEXT comment 'Column 28',field_28 TEXT comment 'Column 29',field_29 TEXT comment 'Column 30',field_30 TEXT comment 'Column 31',field_31 TEXT comment 'Column 32',field_32 TEXT comment 'Column 33',field_33 TEXT comment 'Column 34',field_34 TEXT comment 'Column 35',field_35 TEXT comment 'Column 36',field_36 TEXT comment 'Column 37',field_37 TEXT comment 'Column 38',field_38 TEXT comment 'Column 39',field_39 TEXT comment 'Column 40',field_40 TEXT comment 'Column 41',field_41 TEXT comment 'Column 42',field_42 TEXT comment 'Column 43',field_43 TEXT comment 'Column 44',field_44 TEXT comment 'Column 45',field_45 TEXT comment 'Column 46',field_46 TEXT comment 'Column 47',field_47 TEXT comment 'Column 48',field_48 TEXT comment 'Column 49',field_49 TEXT comment 'Column 50',field_50 TEXT comment 'Column 51',field_51 TEXT comment 'Column 52',field_52 TEXT comment 'Column 53',field_53 TEXT comment 'Column 54',field_54 TEXT comment 'Column 55',field_55 TEXT comment 'Column 56',field_56 TEXT comment 'Column 57',field_57 TEXT comment 'Column 58',field_58 TEXT comment 'Column 59',field_59 TEXT comment 'Column 60',field_60 TEXT comment 'Column 61',field_61 TEXT comment 'Column 62',field_62 TEXT comment 'Column 63',field_63 TEXT comment 'Column 64',field_64 TEXT comment 'Column 65',field_65 TEXT comment 'Column 66',field_66 TEXT comment 'Column 67',field_67 TEXT comment 'Column 68',field_68 TEXT comment 'Column 69',field_69 TEXT comment 'Column 70',field_70 TEXT comment 'Column 71',field_71 TEXT comment 'Column 72',field_72 TEXT comment 'Column 73',field_73 TEXT comment 'Column 74',field_74 TEXT comment 'Column 75',field_75 TEXT comment 'Column 76',field_76 TEXT comment 'Column 77',field_77 TEXT comment 'Column 78',field_78 TEXT comment 'Column 79',field_79 TEXT comment 'Column 80',field_80 TEXT comment 'Column 81',field_81 TEXT comment 'Column 82',field_82 TEXT comment 'Column 83',field_83 TEXT comment 'Column 84',field_84 TEXT comment 'Column 85',field_85 TEXT comment 'Column 86',field_86 TEXT comment 'Column 87',field_87 TEXT comment 'Column 88',field_88 TEXT comment 'Column 89',field_89 TEXT comment 'Column 90',field_90 TEXT comment 'Column 91',field_91 TEXT comment 'Column 92',field_92 TEXT comment 'Column 93',field_93 TEXT comment 'Column 94',field_94 TEXT comment 'Column 95',field_95 TEXT comment 'Column 96',field_96 TEXT comment 'Column 97',field_97 TEXT comment 'Column 98',field_98 TEXT comment 'Column 99',field_99 TEXT comment 'Column 100',field_100 TEXT comment 'Column 101',field_101 TEXT comment 'Column 102',field_102 TEXT comment 'Column 103',field_103 TEXT comment 'Column 104',field_104 TEXT comment 'Column 105',field_105 TEXT comment 'Column 106',field_106 TEXT comment 'Column 107',field_107 TEXT comment 'Column 108',field_108 TEXT comment 'Column 109',field_109 TEXT comment 'Column 110',field_110 TEXT comment 'Column 111',field_111 TEXT comment 'Column 112',field_112 TEXT comment 'Column 113',field_113 TEXT comment 'Column 114',field_114 TEXT comment 'Column 115',field_115 TEXT comment 'Column 116',field_116 TEXT comment 'Column 117',field_117 TEXT comment 'Column 118',field_118 TEXT comment 'Column 119',field_119 TEXT comment 'Column 120',field_120 TEXT comment 'Column 121',field_121 TEXT comment 'Column 122',field_122 TEXT comment 'Column 123',field_123 TEXT comment 'Column 124',field_124 TEXT comment 'Column 125',field_125 TEXT comment 'Column 126',field_126 TEXT comment 'Column 127',field_127 TEXT comment 'Column 128',field_128 TEXT comment 'Column 129',field_129 TEXT comment 'Column 130',field_130 TEXT comment 'Column 131',field_131 TEXT comment 'Column 132',field_132 TEXT comment 'Column 133',field_133 TEXT comment 'Column 134',field_134 TEXT comment 'Column 135',field_135 TEXT comment 'Column 136',field_136 TEXT comment 'Column 137',field_137 TEXT comment 'Column 138',field_138 TEXT comment 'Column 139',field_139 TEXT comment 'Column 140',field_140 TEXT comment 'Column 141',field_141 TEXT comment 'Column 142',field_142 TEXT comment 'Column 143',field_143 TEXT comment 'Column 144',field_144 TEXT comment 'Column 145',field_145 TEXT comment 'Column 146',field_146 TEXT comment 'Column 147',field_147 TEXT comment 'Column 148',field_148 TEXT comment 'Column 149',field_149 TEXT comment 'Column 150',field_150 TEXT comment 'Column 151',field_151 TEXT comment 'Column 152',field_152 TEXT comment 'Column 153',field_153 TEXT comment 'Column 154',field_154 TEXT comment 'Column 155',field_155 TEXT comment 'Column 156',field_156 TEXT comment 'Column 157',field_157 TEXT comment 'Column 158',field_158 TEXT comment 'Column 159',field_159 TEXT comment 'Column 160',field_160 TEXT comment 'Column 161',field_161 TEXT comment 'Column 162',field_162 TEXT comment 'Column 163',field_163 TEXT comment 'Column 164',field_164 TEXT comment 'Column 165',field_165 TEXT comment 'Column 166',field_166 TEXT comment 'Column 167',field_167 TEXT comment 'Column 168',field_168 TEXT comment 'Column 169',field_169 TEXT comment 'Column 170',field_170 TEXT comment 'Column 171',field_171 TEXT comment 'Column 172',field_172 TEXT comment 'Column 173',field_173 TEXT comment 'Column 174',field_174 TEXT comment 'Column 175',field_175 TEXT comment 'Column 176',field_176 TEXT comment 'Column 177',field_177 TEXT comment 'Column 178',field_178 TEXT comment 'Column 179',field_179 TEXT comment 'Column 180',field_180 TEXT comment 'Column 181',field_181 TEXT comment 'Column 182',field_182 TEXT comment 'Column 183',field_183 TEXT comment 'Column 184',field_184 TEXT comment 'Column 185',field_185 TEXT comment 'Column 186',field_186 TEXT comment 'Column 187',field_187 TEXT comment 'Column 188',field_188 TEXT comment 'Column 189',field_189 TEXT comment 'Column 190',field_190 TEXT comment 'Column 191',field_191 TEXT comment 'Column 192',field_192 TEXT comment 'Column 193',field_193 TEXT comment 'Column 194',field_194 TEXT comment 'Column 195',field_195 TEXT comment 'Column 196',field_196 TEXT comment 'Column 197',field_197 TEXT comment 'Column 198',field_198 TEXT comment 'Column 199',field_199 TEXT comment 'Column 200',primary key (entry_id),KEY date_modified (date_modified),KEY modified_by (modified_by),KEY archived (archived),KEY created_by (created_by),KEY mode (mode)) row_format=dynamic;

PS我知道从数据建模的角度来看,创建具有200个文本列的表不是最佳实践。这不是这个问题的意思。我只是想了解什么是行限制,以及如何计算我的表实际使用的8192个字节中的多少个。

解决方法

“不是最佳实践……不是这个问题是关于什么的”-但这关于答案的问题。

表格是MyISAM还是InnoDB?假设Innodb ...

与此同时,这是该限制的一些“原因”:

  • 行以固定大小(16KB)的块存储在“ BTree”中。
  • 由于各种原因,单行的最大大小需要略小于块的一半,因此为“ 8126”。
  • 为了允许“大” TEXTsBLOBs,甚至是VARCHARs,有一种机制可以“关闭记录”存储此类列。但是,指向该表的“指针”需要一些空间-即20-40字节,主要取决于表的ROW_FORMAT。注意-其他一些row_format可以避免您遇到的问题。

解决方案:

  • 如果这200列实际上是事物的“数组”,那么实际上应该将它们移到另一个表,并以1:many关系连接到该表。
  • 程序员通常只是说TEXT而不是弄清楚什么是实际的数据类型。更改其中一些列(例如,将其更改为较小的VARCHAR)可能会解决此问题。
  • 在客户端中压缩数据 ,然后存储到BLOBsBINARY(...)可以缩小内容以进行修复。
  • 将200项中的部分或全部扔到JSON字符串中,并声明单个列可能会解决此问题(但可能会引起其他问题)。
  • JSON加客户端压缩可同时提供两者的优点。

Varchar? -基本上与TEXT相同。

  • 如果整个行太大,则 some 列将移至off_record存储。
  • 候选人为VARCHARsTEXTsBLOBsBINARYs
  • 根据ROW_FORMAT,要移动的内容的临界值为0或40个字节。但是,与0/20/40无关,还剩下一些字节的开销。它们可能包括NULLness,长度等。
  • 也就是说,对于 any row_format,记录存储中剩余的空间超过20个字节。 (例外:当值足够小时,并且对于某些row_formats)

其他潜在问题:

  • 我不知道GEOMETRY是否被视为TEXT。如果不是,那可能是溢出的原因吗?
  • 如果不需要这么大的值,可以不使用BIGINT来节省一些字节。每个BIGINT占用8个字节(加上开销)。