<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>
<channel>
	<title>超群.com的博客 &#187; data_types</title>
	<atom:link href="http://www.fuchaoqun.com/tag/data_types/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.fuchaoqun.com</link>
	<description></description>
	<lastBuildDate>Thu, 08 Sep 2011 15:08:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2.1</generator>
		<item>
		<title>MySQL数据类型迷惑之整型xxxINT</title>
		<link>http://www.fuchaoqun.com/2008/11/mysql-data-types-int/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-data-types-int</link>
		<comments>http://www.fuchaoqun.com/2008/11/mysql-data-types-int/#comments</comments>
		<pubDate>Fri, 07 Nov 2008 03:54:50 +0000</pubDate>
		<dc:creator>超群.com</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[data_types]]></category>
		<guid isPermaLink="false">http://chaoqun.17348.com/?p=100</guid>
		<description><![CDATA[本博客所有原创文章采用知识共享署名-非商业性使用-相同方式共享，转载请保留链接http://chaoqun.17348.com/2008/11/mysql-data-types-int/ 最近在做一些利用MySQL进行数据挖掘方面的尝试，处理的大多是海量的数据（一般是5000W条以上），由于数据量巨大，数据库表字段数据类型的选择就显示出重要性来了。 比如有下面的一个表： mysql&#62; desc test; +--------+---------+------+-----+---------+-------+ &#124; Field  &#124; Type    &#124; Null &#124; Key &#124; Default &#124; Extra &#124; +--------+---------+------+-----+---------+-------+ &#124; uid    &#124; int(11) &#124; NO   &#124;     &#124; NULL    &#124;       &#124; &#124; cid    &#124; int(11) &#124; NO   &#124;     &#124; NULL    &#124;       &#124; &#124; rating &#124; int(11) &#124; NO   &#124;     &#124; NULL    &#124;       &#124; &#124; [...]]]></description>
			<content:encoded><![CDATA[<blockquote><p>本博客所有原创文章采用<a href="http://creativecommons.org/licenses/by-nc-sa/2.5/cn/" target="_blank"><span style="color: #356aa0;">知识共享署名-非商业性使用-相同方式共享</span></a>，转载请保留链接<a href="http://chaoqun.17348.com/2008/11/mysql-data-types-int/">http://chaoqun.17348.com/2008/11/mysql-data-types-int/</a></p></blockquote>
<p>最近在做一些利用MySQL进行数据挖掘方面的尝试，处理的大多是海量的数据（一般是5000W条以上），由于数据量巨大，数据库表字段数据类型的选择就显示出重要性来了。</p>
<p>比如有下面的一个表：</p>
<blockquote>
<pre>mysql&gt; desc test;
+--------+---------+------+-----+---------+-------+
| Field  | Type    | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| uid    | int(11) | NO   |     | NULL    |       |
| cid    | int(11) | NO   |     | NULL    |       |
| rating | int(11) | NO   |     | NULL    |       |
| day    | date    | NO   |     | NULL    |       |
+--------+---------+------+-----+---------+-------+
4 rows in set (0.00 sec)</pre>
</blockquote>
<p>其中uid是用户ID，cid是内容ID，rating是打分值，取值是1～5，day是打分日期，就是这样一个表，往里面导入数据，大概1亿条，然后执行：</p>
<blockquote><p>mysql&gt; show table status like &#8216;test&#8217;;</p></blockquote>
<p>数据库大概1.5G大小，注意里面的Avg_row_length字段，这个字段的意思平均每行占用的字节数，test表每行占用字节数（行大小）是16（3个int是12个字节，一个date是3个字节，然后再加1就是16个字节）。好大的数据，我们的优化开始了。</p>
<p>查看最大的一个uid是多少</p>
<blockquote><p>mysql&gt; select max(uid) from test;</p></blockquote>
<p>发现最大的uid是2 649 429，只有7位数</p>
<p>查看最大的一个aid是多少</p>
<p>mysql&gt; select max(cid) from test;</p>
<p>发现最大的cid是17 770，区区5位数</p>
<p>rating字段只有1～5这5个值，一位就搞定了</p>
<p>于是更改了test表设计</p>
<blockquote>
<pre>mysql&gt; desc test;
+--------+---------+------+-----+---------+-------+
| Field  | Type    | Null | Key | Default | Extra |
+--------+---------+------+-----+---------+-------+
| uid    | int(7)  | NO   |     | NULL    |       |
| cid    | int(5)  | NO   |     | NULL    |       |
| rating | int(1)  | NO   |     | NULL    |       |
| day    | date    | NO   |     | NULL    |       |
+--------+---------+------+-----+---------+-------+
4 rows in set (0.00 sec)</pre>
</blockquote>
<p>重新测试一下，大状况了，还是1.5G，每行还是16个字节，怎么会这样？查了一下手册得知：<strong>int(m) m表示最大显示宽度，注意是显示宽度，不会影响它的取值范围</strong>，你大可以在int(1)的字段中插入9999的数字，m不会影响此列的取值范围，也就是说int(1)和int(11)占用的字节数是一样多的，你是不是和我一样想当然了？下面是手册上关于xxxINT类型的详细说明：</p>
<table class="FCK__ShowTableBorders" border="0" cellspacing="0" cellpadding="0" width="600">
<tbody>
<tr>
<td style="width: 160px;">
<pre> MySQL数据类型</pre>
</td>
<td>
<pre> 含义</pre>
</td>
</tr>
<tr>
<td>
<pre> TINYINT(m)</pre>
</td>
<td>
<pre> 8位整数（1字节，取值范围-128～+127）；可选参数m表示最大显示宽度，对取值范围无影响，如果使用了UNSIGNED，则取值范围为0~255</pre>
</td>
</tr>
<tr>
<td>
<pre> SMALLINT(m)</pre>
</td>
<td>
<pre> 16位整数（2字节，取值范围-32 768～+32 767）</pre>
</td>
</tr>
<tr>
<td>
<pre> MEDIUMINT(m)</pre>
</td>
<td>
<pre> 24位整数（3字节，取值范围-8 388 608～+8 388 607）</pre>
</td>
</tr>
<tr>
<td>
<pre> INT(m)、INTERGER(m)</pre>
</td>
<td>
<pre> 32位整数（4字节，取值范围-2 147 483 648～+2 147 483 647）</pre>
</td>
</tr>
<tr>
<td>
<pre> BIGINT(m)</pre>
</td>
<td>
<pre> 64位整数（8字节，取值范围±9.22*1018</pre>
</td>
</tr>
<tr>
<td>
<pre> SERIAL</pre>
</td>
<td>
<pre> BIGINT AUTO_INCREMENT NOT NULL PRIMARY KEY的缩写</pre>
</td>
</tr>
</tbody>
</table>
<p>于是再次更改表的设计：</p>
<blockquote>
<pre>mysql&gt; desc test;
+--------+-----------------------+------+-----+---------+-------+
| Field  | Type                  | Null | Key | Default | Extra |
+--------+-----------------------+------+-----+---------+-------+
| uid    | mediumint(8) unsigned | NO   |     | NULL    |       |
| cid    | smallint(5) unsigned  | NO   |     | NULL    |       |
| rating | tinyint(1)            | NO   |     | NULL    |       |
| day    | date                  | NO   |     | NULL    |       |
+--------+-----------------------+------+-----+---------+-------+</pre>
</blockquote>
<p>再执行</p>
<p>mysql&gt; show table status like &#8216;test&#8217;;</p>
<p>test表大小变成不到960MB了，行大小变成10字节（3＋2＋1＋3＋1），苗条了许多。</p>
<p>另外，手册上说<strong>两个UNSIGNED的字段相减，值还是UNSIGNED</strong>，这就意味着如果用3-5的话，最后得到的结果肯定不是-2而是一个溢出的超大整数，注意安全。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.fuchaoqun.com/2008/11/mysql-data-types-int/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
	</channel>
</rss>
<!-- WP Super Cache is installed but broken. The path to wp-cache-phase1.php in wp-content/advanced-cache.php must be fixed! -->
