TE
科技回声
首页24小时热榜最新最佳问答展示工作
GitHubTwitter
首页

科技回声

基于 Next.js 构建的科技新闻平台,提供全球科技新闻和讨论内容。

GitHubTwitter

首页

首页最新最佳问答展示工作

资源链接

HackerNews API原版 HackerNewsNext.js

© 2025 科技回声. 版权所有。

Why do database columns have a character length of 191?

124 点作者 andyjih_大约 4 年前

11 条评论

pizza234大约 4 年前
The article is missing important notions (and at risk of being misleading) about index storage and access.<p>It is correct that InnoDB indexes used to have a per-entry limit of 767 bytes; this is however the index <i>left prefix</i>. It means that one can still index longer strings, but infix&#x2F;suffix index access can&#x27;t be performed. Prefix index access can (limited to the number of chars).<p>Now, if one is indexing very long strings, they should really think twice about what they&#x27;re doing, as some other data structures may be more appropriate. Indexing is a balancing act, and this is not a problem of MySQL, it&#x27;s a inherent problem of database systems. One may think they&#x27;re going to add a 2048-bytes index and speed up access, while they may be actually slowing down the system (ie. because full table scan may be faster, and the index slows down writing and query-optimizing).<p>To be noted that nowadays the limit is not 767 bytes, but 3072, at least, for the default row format[¹].<p>¹=<a href="https:&#x2F;&#x2F;docs.oracle.com&#x2F;cd&#x2F;E17952_01&#x2F;mysql-8.0-en&#x2F;innodb-limits.html" rel="nofollow">https:&#x2F;&#x2F;docs.oracle.com&#x2F;cd&#x2F;E17952_01&#x2F;mysql-8.0-en&#x2F;innodb-lim...</a>
评论 #27187796 未加载
jzelinskie大约 4 年前
If you are building software that depends on a SQL database, always specify your encodings (and explicitly name your indexes)! I previously built an enterprise product that didn&#x27;t specify our string encodings in its initial migration and spent years fielding support tickets and dealing with the hell of making migrations that could support the default encodings across platforms until we could justify copying the whole column.<p>Postgres largely avoids this problem by using utf8 as the default pretty much everywhere, but MySQL definitely has platforms that ship with defaults as latin1.
评论 #27187661 未加载
评论 #27187918 未加载
评论 #27190652 未加载
ademarre大约 4 年前
191 is a magic number for VARCHAR columns in MySQL when innodb_large_prefix is disabled, which was the default for MySQL &lt;= 5.7.6.<p>Here is a short list of MySQL magic numbers for column types.<p>Space efficiency and performance:<p>- VARBINARY(255) &#x2F; VARCHAR(255) with single-byte character sets: 255 is the biggest size that requires only 1 byte of storage overhead.<p>- VARCHAR(63) with utf8mb4: 63 is the biggest size that requires only 1 byte of storage overhead because 64 × 4 &gt; 255.<p>- VARBINARY(512) &#x2F; VARCHAR(512): the largest columns of their types that are compatible with <i>in-memory</i> temporary tables when UNION or UNION ALL is used. Larger columns will use <i>on-disk</i> tables instead.<p>Limitations of 3072-byte index keys (innodb_large_prefix enabled; default for MySQL &gt;= 5.7.7):<p>- VARBINARY(3072) &#x2F; VARCHAR(3072) with single-byte character sets: 3072 is the biggest size that can be fully indexed.<p>- VARCHAR(768) with utf8mb4: 768 is the biggest size that can be fully indexed because 769 × 4 &gt; 3072.<p>Limitations of 767-byte index keys (innodb_large_prefix disabled; default for MySQL &lt;= 5.7.6):<p>- VARBINARY(767) &#x2F; VARCHAR(767) with single-byte character sets: 767 is the biggest size that can be fully indexed without enabling innodb_large_prefix.<p>- VARCHAR(191) with utf8mb4: 191 is the biggest size that can be fully indexed without enabling innodb_large_prefix because 192 × 4 &gt; 767. This is what the OP is about. VARCHAR(768), mentioned above, should be more relevant nowadays.<p>Different magic numbers come in if you are using VARCHAR with utf8 (the MySQL character set, not the real UTF-8). I&#x27;ll let you work out the details, but the magic numbers are 85, 255, 1024.
Twisol大约 4 年前
Fascinating! But it replaces one question with another:<p>&gt; The way innodb MySQL databases worked was that you can only have 767 bytes for an index<p>Was somebody a Boeing fan or is there another story behind the 767 figure?<p>EDIT: aaand I figured it out. 256 * 3 is 768, then take away one for the null terminator. Wild.
评论 #27187812 未加载
评论 #27186953 未加载
7steps2much大约 4 年前
These kind of stories are really interesting because they provide so much context to questions that I couldn&#x27;t answer up to now!<p>Like why my MySQL couldn&#x27;t create indexes on data I migrated from PostgreSQL. Granted, that ship has long since sailed and we decided to stick with PostgreSQL, but nice to know the reason none the less!
ipaddr大约 4 年前
This number is based on the character set of the column type. utf8 has more space available so you get 255 with utf8mb4 you get 191 which is mysql&#x27;s default now.
评论 #27187702 未加载
remus大约 4 年前
&gt; All modern popular relational database support (almost) unlimited sized strings with a text or blob-type column, so why not use that? The reason is indexes.<p>Indexes are not the only reason. Typical databases (mysql, mssql etc.) are row oriented so they store rows of data in blocks on disk. If you have a text or blob field it is potentially unbounded in size and if the field does get too big it will typically be moved &#x27;off the row&#x27; and replaced with a pointer to the full object. If instead you have a varchar field then it&#x27;s size is bounded and the db can keep all the data in contiguous blocks on the disk. Having all your data in contiguous blocks can improve read performance (though it&#x27;s less of an issue with SSDs).
评论 #27187610 未加载
TonyTrapp大约 4 年前
This reminds me of the times when I wanted to do things &quot;the right way&quot; so instead of using phpMyAdmin I switched to using MySQL Workbench (which I no longer use now, it was slow and painful). Its default VARCHAR size was an oddly specific 45 characters.<p>Edit: Seems like someone else was wondering about the same thing, with no clear answer: <a href="https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13174307&#x2F;mysql-workbench-why-is-the-default-varchar-45" rel="nofollow">https:&#x2F;&#x2F;stackoverflow.com&#x2F;questions&#x2F;13174307&#x2F;mysql-workbench...</a>
superasn大约 4 年前
Site was not loading for me so here is an archived version to save you guys a click:<p><a href="https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20210517182448if_&#x2F;https:&#x2F;&#x2F;www.grouparoo.com&#x2F;blog&#x2F;varchar-191" rel="nofollow">https:&#x2F;&#x2F;web.archive.org&#x2F;web&#x2F;20210517182448if_&#x2F;https:&#x2F;&#x2F;www.gr...</a>
mfer大约 4 年前
History, like this, is great to understand and learn from.
shadowgovt大约 4 年前
Newbie database question:<p>I&#x27;m surprised the database cares at all about field length for indexing purposes, because I&#x27;d assume for indexing purposes it would hash the field and be done with it; a hash is a great tool for doing quick equality-comparisons.<p>Is this not sufficient because the index also needs to support sorting, so the original values matter to high resolution?
评论 #27187900 未加载
评论 #27187385 未加载
评论 #27187818 未加载
评论 #27189639 未加载