﻿<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:dc="http://purl.org/dc/elements/1.1/" xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/" xmlns:wfw="http://wellformedweb.org/CommentAPI/" xmlns:slash="http://purl.org/rss/1.0/modules/slash/"><channel><title>C++博客-PeakGao-随笔分类-数据库开发</title><link>http://www.cppblog.com/PeakGao/category/1932.html</link><description>别读成痞子高</description><language>zh-cn</language><lastBuildDate>Mon, 19 May 2008 14:15:13 GMT</lastBuildDate><pubDate>Mon, 19 May 2008 14:15:13 GMT</pubDate><ttl>60</ttl><item><title>MySQL索引分析和优化解决方案</title><link>http://www.cppblog.com/PeakGao/archive/2007/07/02/27371.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Mon, 02 Jul 2007 08:50:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2007/07/02/27371.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/27371.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2007/07/02/27371.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/27371.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/27371.html</trackback:ping><description><![CDATA[<strong>一、什么是索引？</strong> <br><br>　　索引用来快速地寻找那些具有特定值的记录，所有MySQL索引都以B-树的形式保存。如果没有索引，执行查询时MySQL必须从第一个记录开始扫描整个表的所有记录，直至找到符合要求的记录。表里面的记录数量越多，这个操作的代价就越高。如果作为搜索条件的列上已经创建了索引，MySQL无需扫描任何记录即可迅速得到目标记录所在的位置。如果表有1000个记录，通过索引查找记录至少要比顺序扫描记录快100倍。<br><br>　　假设我们创建了一个名为people的表：<br><br>
<table borderColor=#111111 cellSpacing=0 cellPadding=2 align=center bgColor=#e9e9e9 border=1>
    <tbody>
        <tr>
            <td>CREATE TABLE people ( peopleid SMALLINT NOT NULL, name CHAR(50) NOT NULL );</td>
        </tr>
    </tbody>
</table>
<br>　　然后，我们完全随机把1000个不同name值插入到people表。下图显示了people表所在数据文件的一小部分：<br><br>
<center><br><a href="http://www.phpe.net/%22../uploads/images/article_1043248393.gif/%22" target=_blank><img height=115 alt=点击查看原图 hspace=3 src="http://www.phpe.net/uploads/images/article_1043248393.gif" width=232 vspace=3 border=0></a><br></center><br>　　可以看到，在数据文件中name列没有任何明确的次序。如果我们创建了name列的索引，MySQL将在索引中排序name列： <br>
<center><br><a href="http://www.phpe.net/%22../uploads/images/article_1043248412.gif/%22" target=_blank><img height=119 alt=点击查看原图 hspace=3 src="http://www.phpe.net/uploads/images/article_1043248412.gif" width=162 vspace=3 border=0></a><br></center><br>　　对于索引中的每一项，MySQL在内部为它保存一个数据文件中实际记录所在位置的&#8220;指针&#8221;。因此，如果我们要查找name等于&#8220;Mike&#8221;记录的peopleid（SQL命令为&#8220;SELECT peopleid FROM people WHERE name=\'Mike\';&#8221;），MySQL能够在name的索引中查找&#8220;Mike&#8221;值，然后直接转到数据文件中相应的行，准确地返回该行的peopleid（999）。在这个过程中，MySQL只需处理一个行就可以返回结果。如果没有&#8220;name&#8221;列的索引，MySQL要扫描数据文件中的所有记录，即1000个记录！显然，需要MySQL处理的记录数量越少，则它完成任务的速度就越快。<br><br><strong>　　二、索引的类型</strong><br><br>　　MySQL提供多种索引类型供选择：<br>
<ul>
    <li>普通索引<br><br>这是最基本的索引类型，而且它没有唯一性之类的限制。普通索引可以通过以下几种方式创建： <br><br>
    <ul>
        <li type=circle>创建索引，例如CREATE INDEX &lt;索引的名字&gt; ON tablename (列的列表);
        <li type=circle>修改表，例如ALTER TABLE tablename ADD INDEX [索引的名字] (列的列表);
        <li type=circle>创建表的时候指定索引，例如CREATE TABLE tablename ( [...], INDEX [索引的名字] (列的列表) ); </li>
    </ul>
    <br>
    <li>唯一性索引<br><br>这种索引和前面的&#8220;普通索引&#8221;基本相同，但有一个区别：索引列的所有值都只能出现一次，即必须唯一。唯一性索引可以用以下几种方式创建： <br><br>
    <ul>
        <li type=circle>创建索引，例如CREATE UNIQUE INDEX &lt;索引的名字&gt; ON tablename (列的列表);
        <li type=circle>修改表，例如ALTER TABLE tablename ADD UNIQUE [索引的名字] (列的列表);
        <li type=circle>创建表的时候指定索引，例如CREATE TABLE tablename ( [...], UNIQUE [索引的名字] (列的列表) ); </li>
    </ul>
    <br>
    <li>主键<br><br>主键是一种唯一性索引，但它必须指定为&#8220;PRIMARY KEY&#8221;。如果你曾经用过AUTO_INCREMENT类型的列，你可能已经熟悉主键之类的概念了。主键一般在创建表的时候指定，例如&#8220;CREATE TABLE tablename ( [...], PRIMARY KEY (列的列表) ); &#8221;。但是，我们也可以通过修改表的方式加入主键，例如&#8220;ALTER TABLE tablename ADD PRIMARY KEY (列的列表); &#8221;。每个表只能有一个主键。 <br>&nbsp;<br>
    <li>全文索引<br><br>MySQL从3.23.23版开始支持全文索引和全文检索。在MySQL中，全文索引的索引类型为FULLTEXT。全文索引可以在VARCHAR或者TEXT类型的列上创建。它可以通过CREATE TABLE命令创建，也可以通过ALTER TABLE或CREATE INDEX命令创建。对于大规模的数据集，通过ALTER TABLE（或者CREATE INDEX）命令创建全文索引要比把记录插入带有全文索引的空表更快。本文下面的讨论不再涉及全文索引，要了解更多信息，请参见<u><font color=#0000ff>MySQL documentation</font></u>。 </li>
</ul>
　　<strong>三、单列索引与多列索引</strong><br><br>　　索引可以是单列索引，也可以是多列索引。下面我们通过具体的例子来说明这两种索引的区别。假设有这样一个people表：<br><br>
<table borderColor=#111111 cellSpacing=0 cellPadding=2 bgColor=#e9e9e9 border=1>
    <tbody>
    </tbody>
</table>
<table borderColor=#111111 cellSpacing=0 cellPadding=5 align=center bgColor=#e9e9e9 border=1>
    <tbody>
        <tr>
            <td>ALTER TABLE people ADD INDEX fname_lname_age (firstname,lastname,age);</td>
        </tr>
    </tbody>
</table>
<br>　　由于索引文件以B-树格式保存，MySQL能够立即转到合适的firstname，然后再转到合适的lastname，最后转到合适的age。在没有扫描数据文件任何一个记录的情况下，MySQL就正确地找出了搜索的目标记录！<br><br>　　那么，如果在firstname、lastname、age这三个列上分别创建单列索引，效果是否和创建一个firstname、lastname、age的多列索引一样呢？答案是否定的，两者完全不同。当我们执行查询的时候，MySQL只能使用一个索引。如果你有三个单列的索引，MySQL会试图选择一个限制最严格的索引。但是，即使是限制最严格的单列索引，它的限制能力也肯定远远低于firstname、lastname、age这三个列上的多列索引。<br><br><strong>　　四、最左前缀</strong><br><br>　　多列索引还有另外一个优点，它通过称为最左前缀（Leftmost Prefixing）的概念体现出来。继续考虑前面的例子，现在我们有一个firstname、lastname、age列上的多列索引，我们称这个索引为fname_lname_age。当搜索条件是以下各种列的组合时，MySQL将使用fname_lname_age索引：<br>
<ul>
    <li>firstname，lastname，age
    <li>firstname，lastname
    <li>firstname </li>
</ul>
　　从另一方面理解，它相当于我们创建了(firstname，lastname，age)、(firstname，lastname)以及(firstname)这些列组合上的索引。下面这些查询都能够使用这个fname_lname_age索引：<br>&nbsp;<br>
<table borderColor=#111111 cellSpacing=0 cellPadding=5 bgColor=#e9e9e9 border=1>
    <u><font color=#0000ff>
    <tbody>
    </tbody>
    </font></u>
</table>
<table borderColor=#111111 cellSpacing=0 cellPadding=5 align=center bgColor=#e9e9e9 border=1>
    <tbody>
        <tr align=middle bgColor=#dbdbdb>
            <td>table</td>
            <td>type</td>
            <td>possible_keys</td>
            <td>key</td>
            <td>key_len</td>
            <td>ref</td>
            <td>rows</td>
            <td>Extra</td>
        </tr>
        <tr>
            <td>people</td>
            <td>ref</td>
            <td>fname_lname_age</td>
            <td>fname_lname_age</td>
            <td>102</td>
            <td>const,const,const</td>
            <td>1</td>
            <td>Where used</td>
        </tr>
    </tbody>
</table>
<br>　　下面我们就来看看这个EXPLAIN分析结果的含义。<br>
<ul>
    <li><strong>table</strong>：这是表的名字。 <br><br>
    <li><strong>type</strong>：连接操作的类型。下面是MySQL文档关于ref连接类型的说明：<br><br>&#8220;对于每一种与另一个表中记录的组合，MySQL将从当前的表读取所有带有匹配索引值的记录。如果连接操作只使用键的最左前缀，或者如果键不是UNIQUE或PRIMARY KEY类型（换句话说，如果连接操作不能根据键值选择出唯一行），则MySQL使用ref连接类型。如果连接操作所用的键只匹配少量的记录，则ref是一种好的连接类型。&#8221;<br><br>在本例中，由于索引不是UNIQUE类型，ref是我们能够得到的最好连接类型。<br><br>如果EXPLAIN显示连接类型是&#8220;ALL&#8221;，而且你并不想从表里面选择出大多数记录，那么MySQL的操作效率将非常低，因为它要扫描整个表。你可以加入更多的索引来解决这个问题。预知更多信息，请参见MySQL的手册说明。<br><br>
    <li><strong>possible_keys</strong>：<br><br>可能可以利用的索引的名字。这里的索引名字是创建索引时指定的索引昵称；如果索引没有昵称，则默认显示的是索引中第一个列的名字（在本例中，它是&#8220;firstname&#8221;）。默认索引名字的含义往往不是很明显。<br><br>
    <li><strong>Key</strong>：<br><br>它显示了MySQL实际使用的索引的名字。如果它为空（或NULL），则MySQL不使用索引。<br><br>
    <li><strong>key_len</strong>：<br><br>索引中被使用部分的长度，以字节计。在本例中，key_len是102，其中firstname占50字节，lastname占50字节，age占2字节。如果MySQL只使用索引中的firstname部分，则key_len将是50。<br><br>
    <li><strong>ref</strong>：<br><br>它显示的是列的名字（或单词&#8220;const&#8221;），MySQL将根据这些列来选择行。在本例中，MySQL根据三个常量选择行。<br><br>
    <li><strong>rows</strong>：<br><br>MySQL所认为的它在找到正确的结果之前必须扫描的记录数。显然，这里最理想的数字就是1。<br><br>
    <li><strong>Extra</strong>：<br><br>这里可能出现许多不同的选项，其中大多数将对查询产生负面影响。在本例中，MySQL只是提醒我们它将用WHERE子句限制搜索结果集。<br></li>
</ul>
　　<strong>七、索引的缺点</strong><br><br>　　到目前为止，我们讨论的都是索引的优点。事实上，索引也是有缺点的。<br><br>　　首先，索引要占用磁盘空间。通常情况下，这个问题不是很突出。但是，如果你创建每一种可能列组合的索引，索引文件体积的增长速度将远远超过数据文件。如果你有一个很大的表，索引文件的大小可能达到操作系统允许的最大文件限制。<br><br>　　第二，对于需要写入数据的操作，比如DELETE、UPDATE以及INSERT操作，索引会降低它们的速度。这是因为MySQL不仅要把改动数据写入数据文件，而且它还要把这些改动写入索引文件。<br><br>　　<strong>【结束语】</strong><br><br>　　在大型数据库中，索引是提高速度的一个关键因素。不管表的结构是多么简单，一次500000行的表扫描操作无论如何不会快。如果你的网站上也有这种大规模的表，那么你确实应该花些时间去分析可以采用哪些索引，并考虑是否可以改写查询以优化应用。要了解更多信息，请参见<a href="http://www.yesky.com/imagesnew/software/mysql/manual_toc.html" target=_blank><u><font color=#0000ff>MySQL manual</font></u></a>。另外注意，本文假定你所使用的MySQL是3.23版，部分查询不能在3.22版MySQL上执行。
<img src ="http://www.cppblog.com/PeakGao/aggbug/27371.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2007-07-02 16:50 <a href="http://www.cppblog.com/PeakGao/archive/2007/07/02/27371.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL数据库中修改密码方法总结</title><link>http://www.cppblog.com/PeakGao/archive/2007/04/27/23012.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Fri, 27 Apr 2007 01:18:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2007/04/27/23012.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/23012.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2007/04/27/23012.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/23012.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/23012.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: 首先要声明一点，大部分情况下，修改MySQL是需要有mysql里的root权限的，所以一般用户无法更改密码，除非请求管理员。 &nbsp;&nbsp;<a href='http://www.cppblog.com/PeakGao/archive/2007/04/27/23012.html'>阅读全文</a><img src ="http://www.cppblog.com/PeakGao/aggbug/23012.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2007-04-27 09:18 <a href="http://www.cppblog.com/PeakGao/archive/2007/04/27/23012.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>MySQL数据库基础：数据类型及列类型</title><link>http://www.cppblog.com/PeakGao/archive/2007/04/24/22759.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Tue, 24 Apr 2007 13:03:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2007/04/24/22759.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/22759.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2007/04/24/22759.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/22759.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/22759.html</trackback:ping><description><![CDATA[<p style="TEXT-INDENT: 2em"><strong>【 服务器学院】</strong>我们要把现实世界中的各种信息转换成计算机能理解的东西，这些转换后的信息就形成了数据。例如，某人的出生日期是&#8220;1987年5月23日&#8221;，他的身高是170厘米，等等。数据不仅包括数字、字母、文字和其他特殊字符组成的文本形式的数据，而且还包括图形、图像、动画、影像、声音等多媒体数据。但使用最多、最基本的仍然是文本数据。<br><br><strong>&nbsp;&nbsp;&nbsp; 1. MySQL的数据类型&nbsp;<br></strong><br>&nbsp;&nbsp;&nbsp; 在MySQL中有如下几种数据类型：&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （1）数值型&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 数值是诸如32 或153.4 这样的值。MySQL 支持科学表示法，科学表示法由整数或浮点数后跟&#8220;e&#8221;或&#8220;E&#8221;、一个符号（&#8220;+&#8221;或&#8220;-&#8221;）和一个整数指数来表示。1.24E+12 和23.47e-1 都是合法的科学表示法表示的数。而1.24E12 不是合法的，因为指数前的符号未给出。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 浮点数由整数部分、一个小数点和小数部分组成。整数部分和小数部分可以分别为空，但不能同时为空。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 数值前可放一个负号&#8220;-&#8221;以表示负值。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （2）字符（串）型&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 字符型（也叫字符串型，简称串）是诸如&#8220;Hello, world!&#8221;或&#8220;一个馒头引起的血案&#8221;这样的值，或者是电话号码87398413这样的值。既可用单引号也可用双引号将串值括起来。<br>&nbsp;<br>&nbsp;&nbsp;&nbsp; 初学者往往分不清数值87398143和字符串87398143的区别。都是数字啊，怎么一个要用数值型，一个要用字符型呢？关键就在于：数值型的87398143是要参与计算的，比如它是金融中的一个货款总额；而字符型的87398143是不参与计算的，只是表示电话号码，这样的还有街道号码、门牌号码等等，它们都不参与计算。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （3）日期和时间型&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 日期和时间是一些诸如&#8220;2006-07-12&#8221;或&#8220;12:30:43&#8221;这样的值。MySQL还支持日期/时间的组合，如&#8220;2006-07-12 12:30:43&#8221;。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （4）NULL值&nbsp;<br><br>&nbsp;&nbsp;&nbsp; NULL表示未知值。比如填写表格中通讯地址不清楚留空不填写，这就是NULL值。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 我们用Create Table语句创建一个表（参看前面的章节），这个表中包含列的定义。例如我们在前面创建了一个joke表，这个表中有content和writer两个列：<br>
<p>&nbsp;&nbsp;
<center><ccid_nobr>
<pre><ccid_code>CREATE TABLE
（
content varchar(20) NOT NULL,
writer varchar(10) NULL
）</ccid_code></pre>
</ccid_nobr></center>&nbsp;
<p>&#160;</p>
<p>&nbsp; &nbsp;定义一个列的语法如下：<br></p>
<p>
<center><ccid_nobr>
<pre><ccid_code>col_name col_typy [col_attributes] <br>[general_attributes]</ccid_code></pre>
</ccid_nobr></center>&nbsp;
<p>&#160;</p>
<p>&nbsp;&nbsp; 其中列名由col_name 给出。列名可最多包含64个字符，字符包括字母、数字、下划线及美元符号。列名可以名字中合法的任何符号（包括数字）开头。但列名不能完全由数字组成，因为那样可能使其与数据分不开。MySQL保留诸如SELECT、DELETE和CREATE这样的词，这些词不能用做列名，但是函数名（如POS 和MIN）是可以使用的。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 列类型col_type表示列可存储的特定值。列类型说明符还能表示存放在列中的值的最大长度。对于某些类型，可用一个数值明确地说明其长度。而另外一些值，其长度由类型名蕴含。例如，CHAR(10) 明确指定了10个字符的长度，而TINYBLOB值隐含最大长度为255个字符。有的类型说明符允许指定最大的显示宽度（即显示值时使用多少个字符）。浮点类型允许指定小数位数，所以能控制浮点数的精度值为多少。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 可以在列类型之后指定可选的类型说明属性，以及指定更多的常见属性。属性起修饰类型的作用，并更改其处理列值的方式，属性有以下类型：&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （1）专用属性用于指定列。例如，UNSIGNED 属性只针对整型，而BINARY属性只用于CHAR 和VARCHAR。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; （2）通用属性除少数列之外可用于任意列。可以指定NULL 或NOT NULL 以表示某个列是否能够存放NULL。还可以用DEFAULT，def_value 来表示在创建一个新行但未明确给出该列的值时，该列可赋予值def_value。def_value 必须为一个常量；它不能是表达式，也不能引用其他列。不能对BLOB 或TEXT 列指定缺省值。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 如果想给出多个列的专用属性，可按任意顺序指定它们，只要它们跟在列类型之后、通用属性之前即可。类似地，如果需要给出多个通用属性，也可按任意顺序给出它们，只要将它们放在列类型和可能给出的列专用属性之后即可。&nbsp;</p>
[NextPage] &nbsp; <strong>&nbsp;</strong>&nbsp;&nbsp;&nbsp; <strong>2. MySQL的列（字段）类型 <br><br></strong>&nbsp;&nbsp;&nbsp; 数据库中的每个表都是由一个或多个列（字段）构成的。在用CREATE TABLE语句创建一个表时，要为每列（字段）指定一个类型。列（字段）的类型比数据类型更为细化，它精确地描述了给定表列（字段）可能包含的值的种类，如是否带小数、是否文字很多。 <br><br><strong>&nbsp;&nbsp;&nbsp; 2.1数值列类型 <br></strong><br>&nbsp;&nbsp;&nbsp; MySQL有整数和浮点数值的列类型，如表1所示。整数列类型可以有符号也可无符号。有一种特殊的属性允许整数列值自动生成，这对需要唯一序列或标识号的应用系统来说是非常有用的。<br>
<p>
<p align=center><strong>类型</strong></p>
<p align=center><strong>说明</strong></p>
TINYINT 非常小的整数 SMALLINT 较小整数 MEDIUMINT 中等大小整数 INT 标准整数 BIGINT 较大整数 FLOAT 单精度浮点数 DOUBLE 双精度浮点数 DECIMAL 一个串的浮点数
<p>&#160;</p>
<p align=center>表1：数值列类型</p>
<p align=left>&nbsp;&nbsp;&nbsp; 每种数值类型的名称和取值范围如表2所示。<br></p>
<p align=left>
<p align=center><strong>类型说明</strong></p>
<p align=center><strong>取值范围</strong></p>
TINYINT[(M)] 有符号值：-128 到127（- 27 到27 - 1） <br>无符号值：0到255（0 到28 - 1） <br>SMALLINT[(M)] 有符号值：-32768 到32767（- 215 到215 - 1） <br>无符号值：0到65535（0 到21 6 - 1） <br>MEDIUMINT[(M)] 有符号值：-8388608 到8388607（- 22 3 到22 3 - 1 ） <br>无符号值：0到16777215（0 到22 4 - 1） <br>INT[(M)] 有符号值：-2147683648 到2147683647（- 231 到231- 1） <br>无符号值：0到4294967295（0 到232 - 1） <br>BIGINT[(M)] 有符号值：-9223372036854775808 到9223373036854775807（- 263到263-1） <br><br>无符号值：0到18446744073709551615（0到264 &#8211; 1） <br>FLOAT[(M, D)] 最小非零值：&#177;1.175494351E - 38 DOUBLE[(M,D)] 最小非零值：&#177;2.2250738585072014E - 308 DECIMAL (M, D) 可变；其值的范围依赖于M 和D
<p>&#160;</p>
<p align=center><br>表2：数值列类型的取值范围</p>
<p align=left>&nbsp;&nbsp;&nbsp; 各种类型值所需的存储量如表3所示。<br></p>
<p align=left>
<p align=center><strong>类型说明</strong></p>
<p align=center><strong>存储需求</strong></p>
TINYINT[(M)] 1字节 SMALLINT[(M)] 2字节 MEDIUMINT[(M)] 3字节 INT[(M)] 4字节 BIGINT[(M)] 8字节 FLOAT[(M, D)] 4字节 DOUBLE[(M, D)] 8字节 DECIMAL (M, D) M字节（MySQL &lt; 3.23），M+2字节（MySQL &gt; 3.23 ）
<p>&#160;</p>
<p align=center>表3：数值列类型的存储需求</p>
[NextPage] &nbsp;
<p style="TEXT-INDENT: 2em">MySQL提供了五种整型： TINYINT、SMALLINT、MEDIUMINT、INT和BIGINT。INT为INTEGER的缩写。这些类型在可表示的取值范围上是不同的。整数列可定义为UNSIGNED从而禁用负值；这使列的取值范围为0以上。各种类型的存储量需求也是不同的。取值范围较大的类型所需的存储量较大。 <br><br>&nbsp;&nbsp;&nbsp; MySQL 提供三种浮点类型： FLOAT、DOUBLE和DECIMAL。与整型不同，浮点类型不能是UNSIGNED的，其取值范围也与整型不同，这种不同不仅在于这些类型有最大值，而且还有最小非零值。最小值提供了相应类型精度的一种度量，这对于记录科学数据来说是非常重要的（当然，也有负的最大和最小值）。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 在选择了某种数值类型时，应该考虑所要表示的值的范围，只需选择能覆盖要取值的范围的最小类型即可。选择较大类型会对空间造成浪费，使表不必要地增大，处理起来没有选择较小类型那样有效。对于整型值，如果数据取值范围较小，如人员年龄或兄弟姐妹数，则TINYINT最合适。MEDIUMINT能够表示数百万的值并且可用于更多类型的值，但存储代价较大。BIGINT在全部整型中取值范围最大，而且需要的存储空间是表示范围次大的整型INT类型的两倍，因此只在确实需要时才用。对于浮点值，DOUBLE占用FLOAT的两倍空间。除非特别需要高精度或范围极大的值，一般应使用只用一半存储代价的FLOAT型来表示数据。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 在定义整型列时，可以指定可选的显示尺寸M。如果这样，M应该是一个1 到255的整数。它表示用来显示列中值的字符数。例如，MEDIUMINT(4)指定了一个具有4个字符显示宽度的MEDIUMINT列。如果定义了一个没有明确宽度的整数列，将会自动分配给它一个缺省的宽度。缺省值为每种类型的&#8220;最长&#8221;值的长度。如果某个特定值的可打印表示需要不止M个字符，则显示完全的值；不会将值截断以适合M个字符。&nbsp;<br><br>&nbsp;&nbsp;&nbsp; 对每种浮点类型，可指定一个最大的显示尺寸M 和小数位数D。M 的值应该取1 到255。D的值可为0 到3 0，但是不应大于M - 2（如果熟悉ODBC 术语，就会知道M 和D 对应于ODBC 概念的&#8220;精度&#8221;和&#8220;小数点位数&#8221;）。M和D对FLOAT和DOUBLE 都是可选的，但对于DECIMAL是必须的。在选项M 和D时，如果省略了它们，则使用缺省值。 </p>
<p><br><strong>&nbsp;&nbsp;&nbsp; 2.2字符串列类型</strong> <br><br>&nbsp;&nbsp;&nbsp; MySQL提供了几种存放字符数据的串类型，其类型如下：<br></p>
<p>
<p align=center><strong>类型名</strong></p>
<p align=center><strong>说明</strong></p>
CHAR 定长字符串 VARCHAR 可变长字符串 TINYBLOB 非常小的BLOB（二进制大对象） BLOB 小BLOB MEDIUMBLOB 中等的BLOB LONGBLOB 大BLOB TINYTEXT 非常小的文本串 TEXT 小文本串 MEDIUMTEXT 中等文本串 LONGTEXT 大文本串 ENUM 枚举；列可赋予某个枚举成员 SET 集合；列可赋予多个集合成员
<p>&#160;</p>
<p align=center>表4：字符串列类型</p>
<p align=left>&nbsp;&nbsp;&nbsp; 下表给出了MySQL 定义串值列的类型，以及每种类型的最大尺寸和存储需求。对于可变长的列类型，各行的值所占的存储量是不同的，这取决于实际存放在列中的值的长度。这个长度在表中用L 表示。<br></p>
<p align=left>
<p align=center><strong>类型说明</strong></p>
<p align=center><strong>最大尺寸</strong></p>
<p align=center><strong>存储需求</strong></p>
CHAR( M) M 字节 M 字节 VARCHAR(M) M 字节 L + 1字节 TINYBLOB, TINYTEXT 2<sup>8</sup>- 1字节 L + 1字节 BLOB, TEXT 2<sup>16</sup> - 1 字节 L + 2字节 MEDIUMBLOB, MEDIUMTEXT 2<sup>24</sup>- 1字节 L + 3字节 LONGBLOB, LONGTEXT 2<sup>32</sup>- 1字节 L + 4字节 ENUM(&#8220;value1&#8221;, &#8220;value2&#8221;, ...) 65535 个成员 1 或2字节 SET (&#8220;value1&#8221;, &#8220;value2&#8221;, ...) 64个成员 1、2、3、4 或8字节
<p>&#160;</p>
<p align=center>表5：串列类型最大尺寸及存储需求</p>
<p align=left>&nbsp;&nbsp;&nbsp; L 以外所需的额外字节为存放该值的长度所需的字节数。MySQL 通过存储值的内容及其长度来处理可变长度的值。这些额外的字节是无符号整数。请注意，可变长类型的最大长度、此类型所需的额外字节数以及占用相同字节数的无符号整数之间的对应关系。例如，MEDIUMBLOB 值可能最多224 - 1字节长并需要3 个字节记录其结果。3 个字节的整数类型MEDIUMINT 的最大无符号值为224 - 1。这并非偶然。</p>
[NextPage] &nbsp; <strong>&nbsp;</strong>&nbsp;&nbsp;&nbsp; <strong>2.3日期时间列类型 <br><br></strong>&nbsp;&nbsp;&nbsp; MySQL 提供了几种时间值的列类型，它们分别是： DATE、DATETIME、TIME、TIMESTAMP和YEAR。下表给出了MySQL 为定义存储日期和时间值所提供的这些类型，并给出了每种类型的合法取值范围。<br><br>
<p>
<p align=center><strong>类型名</strong></p>
<p align=center><strong>说明</strong></p>
DATE &#8220;YYYY-MM-DD&#8221;格式表示的日期值 TIME &#8220;hh:mm:ss&#8221;格式表示的时间值 DATETIME &#8220;YYYY-MM-DD hh:mm:ss&#8221;格式 TIMESTAMP &#8220;YYYYMMDDhhmmss&#8221;格式表示的时间戳值 YEAR &#8220;YYYY&#8221;格式的年份值
<p>&#160;</p>
<p align=center>表6：日期时间列类型</p>
<p align=left>
<p align=center><strong>类型名</strong></p>
<p align=center><strong>取值范围</strong></p>
<p align=center><strong>存储需求</strong></p>
DATE &#8220;1000-01-01&#8221;到&#8220;9999-12-31&#8221; 3字节 TIME &#8220;-838:59:59&#8221;到&#8220;838:59:59&#8221; 3字节 DATETIME &#8220;1000-01-01 00:00:00&#8221; 到&#8220;9999-12-31 23:59:59&#8221; 8字节 TIMESTAMP 19700101000000 到2037 年的某个时刻 4字节 YEAR 1901 到2155 1字节
<p>&#160;</p>
<p align=center>表7： 日前时间列类型的取值范围和存储需求</p>
<p align=left>&nbsp;&nbsp;&nbsp; 下面举个例子：<br></p>
<p align=left>
<center><ccid_nobr>
<pre><ccid_code>CREATE TABLE student
(
Name varchar(20) NOT NULL，
Chinese TINYINT(3)，
Maths TINYINT(3)，
English TINYINT(3)，
Birthday DATE
)</ccid_code></pre>
</ccid_nobr></center>
<p>&#160;</p>
<p align=left>&nbsp;&nbsp;&nbsp; 这个例子创建一个student表，这个表中有name字段，字符类型列，不允许NULL（空值）。有Chinese、Maths和English三个整数类型列。还有个Birthday日期类型列。<br></p>
<img src ="http://www.cppblog.com/PeakGao/aggbug/22759.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2007-04-24 21:03 <a href="http://www.cppblog.com/PeakGao/archive/2007/04/24/22759.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>老外用php写的一个MySQL类</title><link>http://www.cppblog.com/PeakGao/archive/2007/04/03/21187.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Tue, 03 Apr 2007 10:43:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2007/04/03/21187.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/21187.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2007/04/03/21187.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/21187.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/21187.html</trackback:ping><description><![CDATA[&nbsp;&nbsp;&nbsp;&nbsp; 摘要: &nbsp;Description:Extremely&nbsp;easy&nbsp;to&nbsp;use&nbsp;and&nbsp;full-featured&nbsp;MySQL&nbsp;class&nbsp;with&nbsp;measured&nbsp;queries.&nbsp;Code:&lt;?/***************************************...&nbsp;&nbsp;<a href='http://www.cppblog.com/PeakGao/archive/2007/04/03/21187.html'>阅读全文</a><img src ="http://www.cppblog.com/PeakGao/aggbug/21187.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2007-04-03 18:43 <a href="http://www.cppblog.com/PeakGao/archive/2007/04/03/21187.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>asp.net中操作Access数据库时碰到的一些问题</title><link>http://www.cppblog.com/PeakGao/archive/2007/01/05/17339.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Fri, 05 Jan 2007 10:29:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2007/01/05/17339.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/17339.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2007/01/05/17339.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/17339.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/17339.html</trackback:ping><description><![CDATA[刚学用asp.net操作Access数据库，不料问题一个接一个的出：<br />1、Insert时提示“INSERT INTO”语法错误<br />后来发现是一些字段的名字是关键字，需要在字段名前后加上中括号才行([])；<br />如：string strSql = "INSERT INTO users(username,[password]) VALUES('peakgao','123')";<br /><br />2、“操作必须使用一个可更新的查询”错误<br />查了一下，大家一般都怀疑是权限问题导致数据库没有写入权限，我的也是这种问题，解决如下（参考网上的文章）：<br /><p>以下是原文<br />作者：想飞翔的鱼。</p><p>前几天帮人做一个网站，在做网页计数器的时候发现的问题，无论是用文件来记录访问次数还是用数据库来记录都是提示“操作必须使用一个可更新的查询”的错误。看网上的回答都说是“访问权限”的问题。</p><p>一般来说，这个问题会发生在磁盘格式为NTFS的情况下，由于这个格式加入了安全性的控制，但是在XP的系统下文件夹的被默认为“默认共享”，在“属性”选项卡里是找不到“安全性”这项的。因此应该更改这项设置。方法叙述如下：</p><p>打开任意一个文件目录，点击“工具”-&gt;“文件夹选项”-&gt;“查看”，找到“使用简单文件共享（推荐）”这项，把前面的勾去掉。</p><p>在网站所在文件夹上单击右键，选择“属性”，这时就能找到“安全”的选项卡，添加一个用户Everyone，权限设为“完全控制”，这样任何人都对你的网站目录有读写权限了，问题得以解决。</p><br />先写到这里，碰到问题后再提交<img src ="http://www.cppblog.com/PeakGao/aggbug/17339.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2007-01-05 18:29 <a href="http://www.cppblog.com/PeakGao/archive/2007/01/05/17339.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item><item><title>游戏数据库的思考</title><link>http://www.cppblog.com/PeakGao/archive/2006/06/10/8379.html</link><dc:creator>PeakGao</dc:creator><author>PeakGao</author><pubDate>Sat, 10 Jun 2006 07:46:00 GMT</pubDate><guid>http://www.cppblog.com/PeakGao/archive/2006/06/10/8379.html</guid><wfw:comment>http://www.cppblog.com/PeakGao/comments/8379.html</wfw:comment><comments>http://www.cppblog.com/PeakGao/archive/2006/06/10/8379.html#Feedback</comments><slash:comments>0</slash:comments><wfw:commentRss>http://www.cppblog.com/PeakGao/comments/commentRss/8379.html</wfw:commentRss><trackback:ping>http://www.cppblog.com/PeakGao/services/trackbacks/8379.html</trackback:ping><description><![CDATA[上个周末看了下MySQL，安装了一个试了下，重点看了c测试程序已经mysql.h中的API，发现好简单，目前公司的游戏计划也是用mysql，但是要设计好一个给游戏使用的数据库模块，也不是简单的处理一下api就能了事的，游戏数据库由于存取特别频繁，在我看来，他的设计主要解决下面几个问题：<br /><br />1、数据缓存的功能<br /><br />想想那么平凡的数据存取，完全依赖数据库的直接操作，这个性能是可想而知的，所以应该建立起游戏服务器和数据库之间的一个桥梁（暂且命名为数据库前端），游戏服务器只跟数据库前端交互，数据库前端自己具有数据持久化的策略，不依赖于游戏服务器的操作。数据库前端在第一次取出原始数据后（如一个角色登录时的数据），将进行本地缓存，下次存取数据都是在本地进行，并不需要更新到数据库中，至于何时更新到数据库可以有数据库前端自行决定（当然也不排除游戏服务器发出持久化的通知）。<br /><br />2、增量更新的功能<br /><br />其实好多数据的提交中，有很大一部分的数据是没有改变的，如果在从前端提交数据到数据库的时候采取相应的增量更新的办法，应该对性能会有所提升，尤其是在几个游戏服务器操作同一个数据库的时候，因为异步的原因，增量更新能够保证数据的正确性。<br /><br />3、抛包策略<br /><br />游戏服务器有很多数据实在太过频繁，但是有些类型的数据的重要性一般，所以中途丢失一些也问题不大，在服务器数据交换比较频繁的时候完全可以抛弃一些，加快存取速度（不过有了前端后是不是可以忽略这点）。<br /><br />4、数据分流功能<br /><br />主要体现在游戏服务器的一些不同类型的数据存取可以通过不同的几个异步队列进行处理，这样即使由于数据库的某些操作延时，也只影响到操作所在队列，不会影响其他队列。<br /><br />5、灵活的多前端，多数据库等支持<br /><br />实现游戏服务器，数据库前端，游戏数据库之间的多对多关系，便于灵活的运用。<br /><br />写完后个人感觉达到第1，2点后，这个数据库前端功能就已经比较强劲了。<img src ="http://www.cppblog.com/PeakGao/aggbug/8379.html" width = "1" height = "1" /><br><br><div align=right><a style="text-decoration:none;" href="http://www.cppblog.com/PeakGao/" target="_blank">PeakGao</a> 2006-06-10 15:46 <a href="http://www.cppblog.com/PeakGao/archive/2006/06/10/8379.html#Feedback" target="_blank" style="text-decoration:none;">发表评论</a></div>]]></description></item></channel></rss>