<?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>StephenChan&#039;s Tech Space &#187; MySQL</title>
	<atom:link href="http://blog.endlesscode.com/category/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.endlesscode.com</link>
	<description>Stay Hungry. Stay Foolish.</description>
	<lastBuildDate>Tue, 25 Oct 2011 01:15:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>MySQL索引基础</title>
		<link>http://blog.endlesscode.com/2010/04/28/mysql-index-intro/</link>
		<comments>http://blog.endlesscode.com/2010/04/28/mysql-index-intro/#comments</comments>
		<pubDate>Wed, 28 Apr 2010 12:34:09 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.endlesscode.com/?p=664</guid>
		<description><![CDATA[看完《High Performance MySQL》前三章了，本来是计划上周总结一下的，但是硬要拖到现在。虽然只比《深入浅出MySQL》多了20+RMB，但是技术含量高太多了。前面三章讲的内容都算是比较琐碎和基础，第二章介绍的基准测试和性能分析工具有时间要去用一下。前两天还想着不总结的，因为都比较基础，但是这两天review了一下，有一些有意思的东西我觉得还是要写下来好点，不能给自己太懒。 MyISAM的索引是直接指向存储的数据行的物理位置，而InnoDB则是指向primary key，即是对于InnoDB而言，Key &#8216;im_a_index&#8217; (id)这样的索引，其索引的数据里面指向的不是数据行的物理位置，而是数据行的primary key，因此使用索引查询其实会产生两次查询，首先是在索引里面获取查询数据的primary key，然后再通过primary key查询到真正的数据。因此，也出现了一个概念叫&#8221;Covering Index&#8221;，这个不是什么新鲜的概念，&#8221; An index that contains (or covers) all the data needed to satisfy a query is called a covering index. &#8220;，正是由于InnoDB要二次查询数据行的原因，covering index就让所有使用这个索引查询的数据都放在索引里面，对于&#8221;select * from table_name where &#8230;&#8221;这些要获取所有列的数据，那么就肯定会用不上这个covering index的好处了。当然，covering index也并不是鼓励所有的查询都新建一个index来体验covering index的好处，太多的index不但会使索引占用的容量增大难以维护，而且也会使update、delete、insert的成本提高很多，具体还是要看项目数据的需求而定，何况，一个数据访问量不大的小项目，就觉得没有什么必要了。对于B-Tree索引，应用索引除了要遵循leftmost &#8230; <a href="http://blog.endlesscode.com/2010/04/28/mysql-index-intro/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>看完《High Performance MySQL》前三章了，本来是计划上周总结一下的，但是硬要拖到现在。虽然只比《深入浅出MySQL》多了20+RMB，但是技术含量高太多了。前面三章讲的内容都算是比较琐碎和基础，第二章介绍的基准测试和性能分析工具有时间要去用一下。前两天还想着不总结的，因为都比较基础，但是这两天review了一下，有一些有意思的东西我觉得还是要写下来好点，不能给自己太懒。</p>
<p>MyISAM的索引是直接指向存储的数据行的物理位置，而InnoDB则是指向primary key，即是对于InnoDB而言，Key &#8216;im_a_index&#8217; (id)这样的索引，其索引的数据里面指向的不是数据行的物理位置，而是数据行的primary key，因此使用索引查询其实会产生两次查询，首先是在索引里面获取查询数据的primary key，然后再通过primary key查询到真正的数据。因此，也出现了一个概念叫&#8221;Covering Index&#8221;，这个不是什么新鲜的概念，&#8221; An index that contains (or covers) all the data needed to satisfy a query is called a covering index. &#8220;，正是由于InnoDB要二次查询数据行的原因，covering index就让所有使用这个索引查询的数据都放在索引里面，对于&#8221;select * from table_name where &#8230;&#8221;这些要获取所有列的数据，那么就肯定会用不上这个covering index的好处了。当然，covering index也并不是鼓励所有的查询都新建一个index来体验covering index的好处，太多的index不但会使索引占用的容量增大难以维护，而且也会使update、delete、insert的成本提高很多，具体还是要看项目数据的需求而定，何况，一个数据访问量不大的小项目，就觉得没有什么必要了。对于B-Tree索引，应用索引除了要遵循leftmost prefix之外，在第一个range condition后面的列都不会应用到索引的，其实也就是索引会匹配这样的(equality, equality, range)这样的条件，但是在(equality, equality, range, equality, range..)这样的条件下，在第一个range后面的都不会享受到index的待遇。<span id="more-664"></span></p>
<p>&#8221; Clustered indexes aren&#8217;t a separate type of index. Rather, they&#8217;re an approach to data storage. The exact details vary between implementations, but InnoDB&#8217;s clustered indexes actually store a B-Tree index and the rows together in the same structure. &#8220;由于clustered index只是一种数据存储的方式，因此对于每个表只能拥有一个clustered index。目前支持这种建立索引的存储方式的只有solidDB和InnoDB支持。如果在InnoDB表中没有定义一个primary key，InnoDB会自动使用一个unique nonnullable index来替代primary key，如果没有这样的index，InnoDB将会隐式定义一个primary key，并此primary key上建立clustered index。&#8221; InnoDB stores each record immediately after the one before, because the primary key values are sequential. When the page reaches its maximum fill factor (InnoDB&#8217;s initial fill factor is only 15/16 full, to leave room for modifications later), the next record goes into a new page. &#8220;。</p>
<p>&#8221; Ordering the results by the index works only when the index&#8217;s order is exactly the same as the ORDER BY clause and all columns are sorted in the same direction(ascending or descending). &#8220;使用索引来排序与使用索引查询的约束差不多，只要WHERE和ORDER BY遵循leftmost prefix就基本可以了，ORDER BY子句的排序列不能是不同方向的排序。</p>
<p>MyISAM可以使用Prefix-Compressed的方式来建立Packed Indexes。&#8221; For example, if the first value is &#8216;perform&#8217; and the second is &#8216;performance&#8217;, the second value will be stored analogously to &#8217;7,ance&#8217;. &#8220;使用这种方式来建立索引，可以节约不少空间，&#8221; Packed indexes can be about one-tenth the size on disk. &#8220;。同时，这样可以使顺序扫描性能表现很好，但是使用反序扫描的话则会成为一个问题。实际上，这种索引的代价就是 CPU&amp;Memory resources vs. disk resources。</p>
<p>对于这样的select语句&#8221; SELECT actor_id FROM table_name WHERE actor_id &lt; 5 AND actor_id &lt;&gt; 1 FOR UPDATE &#8220;，（actor_id是索引）虽然返回的结果不包括actor_id=1的情况，但实际上在事务过程中InnoDB会把actor_id=1的行加锁。这说明了MySQL Server是在存储引擎返回了行之后再应用WHERE filter。关于InnoDB，indexes和locking还有一个鲜为人知的细节是，&#8221; InnoDB can place shared(read) locks on secondary indexes, but exclusive(write) locks require access to the primary key. That eliminates the possibility of using a covering index and can make SELECT FOR UPDATE much slower than LOCK IN SHARE MODE or a nonlocking query. &#8220;</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.endlesscode.com/2010/04/28/mysql-index-intro/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>ibbackup备份与恢复</title>
		<link>http://blog.endlesscode.com/2010/01/30/ibbackup-backup-recovery/</link>
		<comments>http://blog.endlesscode.com/2010/01/30/ibbackup-backup-recovery/#comments</comments>
		<pubDate>Sat, 30 Jan 2010 13:22:56 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.endlesscode.com/?p=211</guid>
		<description><![CDATA[1.备份 ibbackup备份的基本命令： #ibbackup 传入两个配置文件的路径参数 ibbackup /path/to/my.cnf /path/to/my2.cnf #典型的： ibbackup /etc/my.cnf /home/mysql/backup-my.cnf ibbackup会根据第一个参数中的my.cnf文件，获取需要备份的InnoDB的数据文件ibdata和日志文件ib_logfile的位置，并将其备份到第二个参数my2.cnf所指定的位置，ibbackup将读取第一个参数my.cnf中的如下内容： datadir=... innodb_data_home_dir=... innodb_data_file_path=... innodb_log_group_home_dir=... innodb_log_files_in_group=... innodb_log_file_size=... #这里需要注意的是,很多的配置文件 my.cnf 中是没有 innodb_log_group_home_dir 和innodb_data_home_dir,这样ibbackup 会执行失败。 在第二个配置文件my2.cnf中的datadir、innodb_data_home_dir和innodb_log_group_home_dir是填写备份的目录，而且这些目录是要填写绝对路径的，因为ibbackup不识别这些文件中填写的相对路径。两个配置文件my.cnf和my2.cnf中关于数据文件的数量和大小设置必须相同，包括autoextend参数也要保持一致，而日志文件则可以不一样。 my.cnf datadir = /var/lib/mysql innodb_data_home_dir = /var/lib/mysql innodb_data_file_path = ibdata1:1G:autoextend innodb_log_group_home_dir = /var/lib/mysql innodb_log_files_in_group = &#8230; <a href="http://blog.endlesscode.com/2010/01/30/ibbackup-backup-recovery/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<h3>1.备份</h3>
<p>ibbackup备份的基本命令：</p>
<pre class="brush:bash">#ibbackup 传入两个配置文件的路径参数
ibbackup /path/to/my.cnf /path/to/my2.cnf
#典型的：
ibbackup /etc/my.cnf /home/mysql/backup-my.cnf</pre>
<p>ibbackup会根据第一个参数中的my.cnf文件，获取需要备份的InnoDB的数据文件ibdata和日志文件ib_logfile的位置，并将其备份到第二个参数my2.cnf所指定的位置，ibbackup将读取第一个参数my.cnf中的如下内容：</p>
<pre class="brush:bash">datadir=...
innodb_data_home_dir=...
innodb_data_file_path=...
innodb_log_group_home_dir=...
innodb_log_files_in_group=...
innodb_log_file_size=...
#这里需要注意的是,很多的配置文件 my.cnf 中是没有 innodb_log_group_home_dir 和innodb_data_home_dir,这样ibbackup 会执行失败。</pre>
<p>在第二个配置文件my2.cnf中的datadir、innodb_data_home_dir和innodb_log_group_home_dir是填写备份的目录，而且这些目录是要填写绝对路径的，因为ibbackup不识别这些文件中填写的相对路径。两个配置文件my.cnf和my2.cnf中关于数据文件的数量和大小设置必须相同，包括autoextend参数也要保持一致，而日志文件则可以不一样。<br />
<span id="more-211"></span><br />
my.cnf</p>
<pre class="brush:bash">datadir = /var/lib/mysql
innodb_data_home_dir = /var/lib/mysql
innodb_data_file_path = ibdata1:1G:autoextend
innodb_log_group_home_dir = /var/lib/mysql
innodb_log_files_in_group = 2
innodb_log_file_size=256M</pre>
<p>backup-my.cnf</p>
<pre class="brush:bash">datadir = /home/mysql/backup
innodb_data_home_dir = /home/mysql/backup
innodb_data_file_path = ibdata1:1G:autoextend
innodb_log_group_home_dir = /home/mysql/backup
innodb_log_files_in_group = 2
innodb_log_file_size=256M
#innodb_log_arch_dir 是mysql5.0支持的参数，在mysql5.1中已经被innodb_log_group_home_dir替代</pre>
<p>ibbackup备份的只是InnoDB的数据文件和日志文件，而并没有备份.frm文件。因此.frm文件还需手动copy或者是使用mysqldump命令进行备份。</p>
<p>准备好之后，就运行备份命令：</p>
<pre class="brush:bash">ibbackup --compress /etc/my.cnf /home/mysql/backup-my.cnf</pre>
<p>&#8211;compress是压缩备份，恢复的时候也相应添上&#8211;uncompress，压缩备份的数据文件是有.ibz后缀的。成功备份后在备份的目录下就会有ibbackup_logfile和ibdata*.ibz等文件。</p>
<h3>２.恢复</h3>
<p>恢复主要有三个步骤，恢复日志、启动备份的mysql、故障数据恢复。</p>
<ol style="list-style-type:upper-alpha">
<li>进行日志重做<br />
ibbackup在备份期间用日志文件ibbackup_logfile记录了备份期间数据的变化，在恢复的时候是使用此日志对备份的数据进行日志重做。参考手册中说“By applying that file to the backed up data files we can roll forward them so that every page in the data files corresponds to the same log sequence number of the InnoDB log.”，但具体日志重做的细节还没有找到相关的资料。日志重做使用的命令如下：</p>
<pre class="brush:bash">#--uncompress是因为在备份时使用了--compress参数
ibbackup --apply-log --uncompress /home/mysql/backup-my.cnf</pre>
<p>在运行了这个命令之后，ibbackup便开始进行日志恢复，日志重做后会在备份的目录生成ib_logfile*和ibdata*等文件。然后在输出的信息中，有一处比较重要是：</p>
<pre class="brush:plain">#file name后面的路径为mysql的BINLOG目录，其他的输出信息忽略
ibbackup: Last MySQL binlog file position 0 969, file name /var/lib/mysql/.../logs/mysql-bin.000001</pre>
<p>这个是指示了备份时的binlog位置，便于在第三步进行binlog数据恢复时用到。可以看到，在mysql-bin.00001的0-969为备份前binlog的位置。</li>
<li>恢复后重启数据库服务<br />
重启数据库服务器，是指使用backup-my.cnf的配置来启动数据库服务，要注意的是，因此备份的时候只是备份的InnoDB的数据文件和日志文件，如果要重新在另一个目录下启动数据库服务的话，需要将所有在原来mysql的数据目录下的.frm文件目录和mysql目录等文件拷贝到新的目录下。</p>
<pre class="brush:plain">mysqld_safe --defaults-file=/home/mysql/backup-my.cnf &amp;</pre>
</li>
<li>根据BINLOG恢复故障数据<br />
由于在备份后，数据库可能会存在更改，因此要将那些备份后的数据库更改应用到恢复的状态，这个时候就要根据binlog的记录来恢复。在第一步日志重做的时候，记录下备份前的binlog位置为969，因此，我们在恢复binlog时就是指定&#8211;start-position为969，从这个位置开始恢复，同时，如果还有其他的mysql-bin.00000*，也要一起恢复。</p>
<pre class="brush:plain">mysqlbinlog --start-position=969 mysql-bin.00001 | mysql -u root -p***</pre>
</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.endlesscode.com/2010/01/30/ibbackup-backup-recovery/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《深入浅出MySQL》读书拾遗-管理维护</title>
		<link>http://blog.endlesscode.com/2010/01/04/mysql-book-maintainance/</link>
		<comments>http://blog.endlesscode.com/2010/01/04/mysql-book-maintainance/#comments</comments>
		<pubDate>Mon, 04 Jan 2010 15:24:18 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.endlesscode.com/?p=84</guid>
		<description><![CDATA[MySQL常用工具 &#8220;default-character-set&#8221;这个选项作为服务器字符集选项，可以在my.cnf的[mysqld]组中配置，也可以在my.cnf的[mysql]组中配置，并且可以在mysql的命令行中手工指定客户端字符集&#8221;mysql -u user &#8211;default-character-set=charset&#8221;。 在命令行中&#8221;-e(&#8211;execute=)&#8221;选项可以直接执行MySQL脚本，而不用连接到MySQL数据库后再执行。可以按这种方式连续执行多个SQL语句，用英文分号（;）隔开，&#8221;mysql -u root -p -e &#8216;select * from t1;select count(*) from t2&#8242;&#8221;。 命令行中的&#8221;-E&#8221;选项类似于mysql里面执行SQL语句后加&#8221;\G&#8221;来进行格式化输出。 还有几个错误处理选项，&#8221;-f(&#8211;force)&#8221;表示强制执行SQL，&#8221;-v(&#8211;verbose)&#8221;显示更多信息，&#8221;&#8211;show-warnings&#8221;显示警告信息。 myisampack(MyISAM表压缩工具)可以使用很高的压缩率来对MyISAM存储引擎的表进行压缩，使用压缩后的表占用比压缩前小得多的磁盘空间。但是压缩后的表也将成为一个只读表，不能进行DML操作。 mysqlbinlog(日志管理工具)可以检查由服务器生成的二进制日志，其中&#8211;start-datetime/position、&#8211;stop-datetime/position可以查看指定日期间隔或者位置间隔内的所有日志。 mysqlcheck(MyISAM表维护工具)可以检查和修复MyISAM表，还可以优化和分析表。实际上，它集成了mysql工具中check、repair、analyze、optimize的功能。 mysqldump(数据导出工具)用来备份数据库或在不同数据库之间进行数据迁移。备份内容包含创建表或装载表的SQL语句。mysqldump目前是MySQL中最常用和备份工具。 mysqlhotcopy(MyISAM表热备份工具)是一个Perl脚本，它使用了LOCK TABLES、FLUSH TABLES、cp或scp来快速备份数据库。它是备份数据库或单个表的最快途径，其缺点是mysqlhotcopy只用于备份MyISAM，而且它需要运行在Linux/Unix环境中。 mysqlimport(数据导入工具)是客户端数据导入工具，用来导入mysqldump加-T选项后导出的文本文件。它实际上是客户端提供了LOAD DATA INFILE语句的一个命令行接口。 mysqlshow(数据库对象查看工具)客户端对象查找工具，用来很快地查找哪些数据库、数据库中的表、表中的列或索引。其使用方法如下：mysqlshow [-u&#124;-p] [dbname] [table] [col] &#8211;count(显示统计信息)/-k(-keys,显示指定表的所有索引)/-i(-status,显示表的一些状态信息) perror(错误代码查看工具)是用来解释数据库中一些错误代码的详细含义的，&#8221;perror 30 60&#8243;是查看错误号30和60分别指什么错误。 MySQL日志 错误日志：这是MySQL中最重要的日志之一，它记录了当mysqld启动和停止时，以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时，可以首先查看此日志。 &#8230; <a href="http://blog.endlesscode.com/2010/01/04/mysql-book-maintainance/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<ol>
<li>MySQL常用工具
<ul>
<li>&#8220;default-character-set&#8221;这个选项作为服务器字符集选项，可以在my.cnf的[mysqld]组中配置，也可以在my.cnf的[mysql]组中配置，并且可以在mysql的命令行中手工指定客户端字符集&#8221;mysql -u user &#8211;default-character-set=charset&#8221;。</li>
<li>在命令行中&#8221;-e(&#8211;execute=)&#8221;选项可以直接执行MySQL脚本，而不用连接到MySQL数据库后再执行。可以按这种方式连续执行多个SQL语句，用英文分号（;）隔开，&#8221;mysql -u root -p -e &#8216;select * from t1;select count(*) from t2&#8242;&#8221;。</li>
<li>命令行中的&#8221;-E&#8221;选项类似于mysql里面执行SQL语句后加&#8221;\G&#8221;来进行格式化输出。</li>
<li>还有几个错误处理选项，&#8221;-f(&#8211;force)&#8221;表示强制执行SQL，&#8221;-v(&#8211;verbose)&#8221;显示更多信息，&#8221;&#8211;show-warnings&#8221;显示警告信息。</li>
<li>myisampack(MyISAM表压缩工具)可以使用很高的压缩率来对MyISAM存储引擎的表进行压缩，使用压缩后的表占用比压缩前小得多的磁盘空间。但是压缩后的表也将成为一个只读表，不能进行DML操作。</li>
<li>mysqlbinlog(日志管理工具)可以检查由服务器生成的二进制日志，其中&#8211;start-datetime/position、&#8211;stop-datetime/position可以查看指定日期间隔或者位置间隔内的所有日志。</li>
<li>mysqlcheck(MyISAM表维护工具)可以检查和修复MyISAM表，还可以优化和分析表。实际上，它集成了mysql工具中check、repair、analyze、optimize的功能。</li>
<li>mysqldump(数据导出工具)用来备份数据库或在不同数据库之间进行数据迁移。备份内容包含创建表或装载表的SQL语句。mysqldump目前是MySQL中最常用和备份工具。</li>
<li>mysqlhotcopy(MyISAM表热备份工具)是一个Perl脚本，它使用了LOCK TABLES、FLUSH TABLES、cp或scp来快速备份数据库。它是备份数据库或单个表的最快途径，其缺点是mysqlhotcopy只用于备份MyISAM，而且它需要运行在Linux/Unix环境中。</li>
<li>mysqlimport(数据导入工具)是客户端数据导入工具，用来导入mysqldump加-T选项后导出的文本文件。它实际上是客户端提供了LOAD DATA INFILE语句的一个命令行接口。</li>
<li>mysqlshow(数据库对象查看工具)客户端对象查找工具，用来很快地查找哪些数据库、数据库中的表、表中的列或索引。其使用方法如下：mysqlshow [-u|-p] [dbname] [table] [col] &#8211;count(显示统计信息)/-k(-keys,显示指定表的所有索引)/-i(-status,显示表的一些状态信息)</li>
<li>perror(错误代码查看工具)是用来解释数据库中一些错误代码的详细含义的，&#8221;perror 30 60&#8243;是查看错误号30和60分别指什么错误。</li>
</ul>
<p><span id="more-84"></span></li>
<li>MySQL日志
<ul>
<li><strong>错误日志</strong>：这是MySQL中最重要的日志之一，它记录了当mysqld启动和停止时，以及服务器在运行过程中发生任何严重错误时的相关信息。当数据库出现任何故障导致无法正常使用时，可以首先查看此日志。</li>
<li>错误日志可以用&#8211;log-error[=file_name]选项来指定mysqld保存错误日志文件的位置。如果没有给定file_name值，mysqld使用错误日志名host_name.error(host_name为主机名)并默认在参数DATADIR(数据目录)指定的目录中写入日志文件。</li>
<li><strong>二进制日志</strong>：又称binlog，记录了所有的DDL(数据定义语言)语句和DML(数据操纵语言)语句，但是不包括数据查询语句。语句以“事件”的形式保存，它描述了数据的更改过程。</li>
<li>二进制日志可以使用&#8211;log-bin[=file_name]选项启动来指定mysqld将包含所有更新数据的SQL命令写入指定的日志文件。如果没有给出file_name值，默认名为主机后面跟&#8221;-bin&#8221;。如果给出了文件名，但没有包含路径，则文件默认为被写入参数DATADIR(数据目录)指定的目录。</li>
<li>二进制日志是以二进制方式存储，不能直接读取，需要用mysqlbinlog工具查看。</li>
<li>执行&#8221;RESET MASTER&#8221;可以删除所有BINLOG日志，新日志编号从&#8221;000001&#8243;开始。执行“PURGE MASTER LOGS TO log_file-bin.000006&#8243;命令将删除000006之前编号的所有日志。执行“PURGE MASTER TO LOGS BEFORE &#8216;yyyy-mm-dd hh:mm:ss&#8221;将删除指定时间前的日志。设置参数&#8211;expire_logs_days(expire_logs_day=d)可以设置删除d日前的过期日志。</li>
<li><strong>查询日志</strong>：记录了客户端的所有语句，而二进制日志不包含只查询数据的语句。查询日志记录的格式是纯文本，因此可以直接进行读取。</li>
<li>查询日志也可以用&#8211;log[=file_name]选项启动mysqld来指定查询日志要保存的位置。和其他日志一样，如果没有给定file_name的值，日志将写入参数DATADIR(数据目录)指定的路径下，默认文件名是host_name.log。</li>
<li>查询日志记录了所有的数据库操作，对于访问频繁的系统，此日志对系统性能的影响较大，建议一般情况下关闭。</li>
<li><strong>慢查询日志</strong>：记录了包含所有执行时间超过参数long_query_time(单位：秒)所设置值的SQL语句的日志。获得表锁定的时间不算作执行时间。和错误日志、查询日志一样，慢查询日志记录的格式也是纯文本，可以被直接读取。</li>
<li>慢查询日志可以用&#8211;log-slow-queries[=file_name]选项启动mysqld来指定慢查询日志要保存的具体位置。和前面几种日志一样，如果没有给定file_name的值，日志将写入参数DATADIR(数据目录)指定的路径下，默认文件名是host_name-slow.log。</li>
<li>如果慢查询日志中记录内容很多，可以使用mysqldumpslow工具来对慢查询日志进行分类汇总。慢查询日志对于我们发现应用中有性能问题的SQL很有帮助，建议正常情况下，打开此日志并经常查看分析。</li>
</ul>
</li>
<li>备份和恢复
<ul>
<li>在MySQL里面，逻辑备份的最大优点是对于各种存储引擎，都可以用同样的方法来备份，都是通过导出执行过的SQL命令来重新建立数据；而物理备份则不同，不同的存储引擎有着不同的备份方法。</li>
<li>备份后的完全恢复，可以将mysqldump导出的SQL命令重新导入执行，然后将备份后执行的日志进行重做，&#8221;mysqlbinlog binlog-file | mysql -u root -p&#8221;。</li>
<li>不完全恢复是指由于误操作导致数据丢失，此时需要恢复误操作之前的状态，并跳出误操作语句，再恢复后面的语句。这个可以利用mysqlbinlog中的&#8211;start-datetime/position、&#8211;stop-datetime/position表跳过误操作的语句来进行基于时间和位置的数据不完全恢复。</li>
<li>对于MyISAM存储引擎，热备份有多种方法，本质其实就是将备份的表加读锁，然后再cp数据文件到备份目录。常用的方法有两种：mysqlhotcopy；手工锁表(flush tables for read)，然后cp数据文件到备份目录。</li>
<li>对于InnoDB存储引擎，可以使用ibbackup工具，ibbackup是Innobase公司的一个热备份工具，专门对InnoDB存储引擎进行物理热备份的，此工具是收费滴。</li>
<li>表数据的导出可以用&#8221;SELECT &#8230; INTO OUTFILE&#8221;和mysqldump命令。导入可以用&#8221;LOAD DATA INFILE&#8221;和mysqlimport命令。</li>
</ul>
</li>
<li>MySQL权限和安全
<ul>
<li>对于身份认证，MySQL是通过IP地址和用户名联合进行确认的，即同样的用户名，如果来自不同的IP地址，则MySQL将其视为不同的用户。MySQL的权限表在数据库启动的时候就载入了内存，当用户通过身份认证后，就在内存中进行相应权限的存取。</li>
<li>在权限存取的两个过程中，系统会用到&#8221;mysql&#8221;数据库中的user、host和db这3个最重要的权限表，当然还有procs_priv、tables_priv和columns_priv等表。</li>
<li>在认证过程中，会先从user表中的host、user和password字段来判断连接的IP、用户名和密码是否存在于表中，如果存在，则通过身份认证，否则拒绝连接。通过了身份认证之后，则按照以下权限表的顺序得到数据库权限：user-&gt;db-&gt;tables_priv-&gt;columns_priv，权限范围依次递减，全局权限覆盖局部权限。</li>
<li>所谓的全局权限覆盖局部权限，是指所有数据库都具有相同权限的用户记录并不需要记入db表，而仅仅需要将user表中的select_priv改为&#8221;Y&#8221;即可。换句话说，user表中每个权限都代表了对<strong>所有数据库</strong>都有的权限，而db表只针对于某一个具体的数据库而言。</li>
<li>在使用grant创建账号的时候，如果要赋予Grant_priv权限，则需要在grant语句中加上&#8221;with grant option&#8221;。</li>
<li>修改密码：&#8221;mysqladmin -u user_name -h host_name password &#8216;newpwd&#8217;&#8221;；SET PASSWORD [FOR 'user_name'@'host'] = PASSWORD(&#8220;newpwd&#8221;)；grant usage on *.* to &#8216;user_name&#8217;@'host&#8217; identified by &#8216;newpwd&#8217;；直接更改数据库的user表，注意要用PASSWORD函数。</li>
</ul>
</li>
<li>MySQL复制：看书，29章。</li>
</ol>
]]></content:encoded>
			<wfw:commentRss>http://blog.endlesscode.com/2010/01/04/mysql-book-maintainance/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《深入浅出MySQL》读书拾遗-优化</title>
		<link>http://blog.endlesscode.com/2009/12/29/mysql-book-optimization/</link>
		<comments>http://blog.endlesscode.com/2009/12/29/mysql-book-optimization/#comments</comments>
		<pubDate>Tue, 29 Dec 2009 17:20:06 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.endlesscode.com/?p=78</guid>
		<description><![CDATA[在MySQL中，数据库对应操作系统下的数据目录。数据库中的每个表至少对应数据库目录中的一个文件（也可能是多个，这取决于存储引擎）。因此，所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。 列、索引、存储子程序和触发器名在任何平台上对大小写不敏感。默认情况下，表别名在UNIX中对大小写敏感，但在Windows或Mac OS X中对大小写不敏感。在MySQL中如何在硬盘上保存、使用表名和数据库名由lower_case_tables_name系统变量决定，可以在启动mysqld时设置这个系统变量。 MySQL客户端连接成功后，通过show [session&#124;global] status命令可以提供服务器状态信息，也可以在操作系统上使用mysqladmin extended-status命令获得这些消息。 &#8220;show status like &#8216;Com_%s&#8217;;&#8221;可以显示当前session中所有统计参数的值。其中Com_xxx表示每个xxx语句执行的次数，如Com_select(执行select操作的次数，一次查询只累加1)、Com_insert(执行insert操作的次数，对于批量插入的insert操作，只累加一次)，还有Com_update/Com_delete/Innodb_rows_read/Innodb_rows_inserted/Innodb_rows_updated/Innodb_rows_deleted等等，通过这些参数可以了解到当前数据库的应用是以插入更新为主还是以查询操作为主，以及各种类型的SQL大致的执行比例是多少。 对于事务型的应用，通过Com_commit和Com_rollback可以了解事务提交和回滚的情况，对于回滚操作非常频繁的数据库，可能意味着应用编写存在问题。 Connections(试图连接MySQL服务器的次数)，Uptime(服务器工作时间)，Slow_queries(慢查询的次数)这三个参数也可以帮助用户了解数据库的基本情况。 通过慢查询日志定位那些执行效率较低的SQL语句，用&#8211;log-slow-queries=[file_name]选项启动时，mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。 通过show processlist命令可以查看当前MySQL在进行的线程，包括线程的状态、是否锁表等，可以实时地查看SQL的执行情况，同时对一些锁表操作进行优化。 通过explain分析低效的SQL的执行计划 MySQL中索引的存储类型目前只有支持两种，具体和表的存储引擎相关：MyISAM和InnoDB存储引擎都只支持BTREE索引；MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。 查询要使用索引最主要的条件是查询条件需要使用索引关键字，如果是多列索引，那么只有查询条件使用了多列关键字最左边的前缀时，才可以使用索引，否则将不能使用索引。 使用索引 对于创建的多列索引，只要查询条件中用到了最左边的列，索引一般都会被使用。 对于使用like的查询，后面如果是常量并且只有%号不在第一个字符，索引才可能会被使用。 如果对大的文本进行搜索，使用全文索引而不用使用like&#8217;%&#8230;%&#8217;。 如果列名是索引，使用column_name is null将使用索引。 存在索引但不使用索引 如果MySQL估计使用索引比全表扫描更慢，则不使用索引。 如果使用MEMORY/HEAP表并且where条件中不使用&#8221;=&#8221;进行索引列，那么不会使用索引。heap表只有在&#8221;=&#8221;的条件下才会使用索引。 用or割开的条件，如果or前的条件中的列有索引，而后面的列没有索引，那么涉及的索引都不会被使用。 如果不是索引列的第一部分。 如果like是以%开始。 如果列类型是字符串，那么一定记得在where条件中把字符常量值用引号引起来，否则的话即使这个列上有索引，MySQL也不会用到。 如果索引現在工作，Handler_read_key的值将很高，这个值代表了一个行被索引值读的次数，很低的值表明增加索引得到的性能改善不高，因为索引并不经常使用。 Handler_read_rnd_next的值高则意味着查询运行低效，并且应该建立索引补救。这个值含义是在数据文件中读一下行的请求数。如果現在进行大量的表扫描，Handler_read_rnd_next的值较高，则通常说明表索引不正确或写入的查询没有利用索引。 当从一个文本文件装载一个表时，使用LOAD DATA INFILE。这通常从使用很多INSERT语句快20倍。 默认情况下，MySQL对所有GROUP &#8230; <a href="http://blog.endlesscode.com/2009/12/29/mysql-book-optimization/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<ul>
<li>在MySQL中，数据库对应操作系统下的数据目录。数据库中的每个表至少对应数据库目录中的一个文件（也可能是多个，这取决于存储引擎）。因此，所使用操作系统的大小写敏感性决定了数据库名和表名的大小写敏感性。</li>
<li>列、索引、存储子程序和触发器名在任何平台上对大小写不敏感。默认情况下，表别名在UNIX中对大小写敏感，但在Windows或Mac OS X中对大小写不敏感。在MySQL中如何在硬盘上保存、使用表名和数据库名由lower_case_tables_name系统变量决定，可以在启动mysqld时设置这个系统变量。</li>
<li>MySQL客户端连接成功后，通过show [session|global] status命令可以提供服务器状态信息，也可以在操作系统上使用mysqladmin extended-status命令获得这些消息。</li>
<li>&#8220;show status like &#8216;Com_%s&#8217;;&#8221;可以显示当前session中所有统计参数的值。其中Com_xxx表示每个xxx语句执行的次数，如Com_select(执行select操作的次数，一次查询只累加1)、Com_insert(执行insert操作的次数，对于批量插入的insert操作，只累加一次)，还有Com_update/Com_delete/Innodb_rows_read/Innodb_rows_inserted/Innodb_rows_updated/Innodb_rows_deleted等等，通过这些参数可以了解到当前数据库的应用是以插入更新为主还是以查询操作为主，以及各种类型的SQL大致的执行比例是多少。</li>
<li>对于事务型的应用，通过Com_commit和Com_rollback可以了解事务提交和回滚的情况，对于回滚操作非常频繁的数据库，可能意味着应用编写存在问题。</li>
<li>Connections(试图连接MySQL服务器的次数)，Uptime(服务器工作时间)，Slow_queries(慢查询的次数)这三个参数也可以帮助用户了解数据库的基本情况。</li>
<li>通过慢查询日志定位那些执行效率较低的SQL语句，用&#8211;log-slow-queries=[file_name]选项启动时，mysqld写一个包含所有执行时间超过long_query_time秒的SQL语句的日志文件。</li>
<li>通过show processlist命令可以查看当前MySQL在进行的线程，包括线程的状态、是否锁表等，可以实时地查看SQL的执行情况，同时对一些锁表操作进行优化。</li>
<li>通过explain分析低效的SQL的执行计划</li>
<li>MySQL中索引的存储类型目前只有支持两种，具体和表的存储引擎相关：MyISAM和InnoDB存储引擎都只支持BTREE索引；MEMORY/HEAP存储引擎可以支持HASH和BTREE索引。</li>
<li>查询要使用索引最主要的条件是查询条件需要使用索引关键字，如果是多列索引，那么只有查询条件使用了<strong>多列关键字最左边的前缀</strong>时，才可以使用索引，否则将不能使用索引。</li>
<p><span id="more-78"></span></p>
<li>使用索引
<ul>
<li>对于创建的多列索引，只要查询条件中用到了最左边的列，索引一般都会被使用。</li>
<li>对于使用like的查询，后面如果是常量并且只有%号不在第一个字符，索引才可能会被使用。</li>
<li>如果对大的文本进行搜索，使用全文索引而不用使用like&#8217;%&#8230;%&#8217;。</li>
<li>如果列名是索引，使用column_name is null将使用索引。</li>
</ul>
</li>
<li>存在索引但不使用索引
<ul>
<li>如果MySQL估计使用索引比全表扫描更慢，则不使用索引。</li>
<li>如果使用MEMORY/HEAP表并且where条件中不使用&#8221;=&#8221;进行索引列，那么不会使用索引。heap表只有在&#8221;=&#8221;的条件下才会使用索引。</li>
<li>用or割开的条件，如果or前的条件中的列有索引，而后面的列没有索引，那么涉及的索引都不会被使用。</li>
<li>如果不是索引列的第一部分。</li>
<li>如果like是以%开始。</li>
<li>如果列类型是字符串，那么一定记得在where条件中把字符常量值用引号引起来，否则的话即使这个列上有索引，MySQL也不会用到。</li>
</ul>
</li>
<li>如果索引現在工作，Handler_read_key的值将很高，这个值代表了一个行被索引值读的次数，很低的值表明增加索引得到的性能改善不高，因为索引并不经常使用。</li>
<li>Handler_read_rnd_next的值高则意味着查询运行低效，并且应该建立索引补救。这个值含义是在数据文件中读一下行的请求数。如果現在进行大量的表扫描，Handler_read_rnd_next的值较高，则通常说明表索引不正确或写入的查询没有利用索引。</li>
<li>当从一个文本文件装载一个表时，使用LOAD DATA INFILE。这通常从使用很多INSERT语句快20倍。</li>
<li>默认情况下，MySQL对所有GROUP BY col1, col2&#8230;的字段进行排序。这与在查询中指定ORDER BY col1, col2&#8230;类似。如果查询包括GROUP BY但想要避免排序結果的消耗，则可以指定ORDER BY NULL禁止排序。</li>
<li>对于含有OR的查询子句，如果要利用索引，则OR之间的每个条件列都必须用到索引：如果没有索引，则应该考虑增加索引。</li>
<li>可以通过查询Table_locks_waited和Table_locks_immediate状态变量来分析系统上的表锁定争夺，如果Table_locks_waited的值比较高，则说明存在着较严重的表级锁争用情况。</li>
<li>MyISAM存储引擎有一个系统变量concurrent_insert，专门用以控制其并发插入的行为，其值分别可以为0(不允许并发插入)、1(MyISAM表中没有空洞，可允许一个进程在读，另一个进程在尾插入)，2(无论有没有空洞，都可以在表尾插入)。</li>
<li>如果一个进程请求某个MyISAM表的读锁，同时另一个进程也请求同一表的写锁，MySQL会让写进程先获得锁，这是因为MySQL认为写请求一般比读请求重要，这也是MyISAM表不太适合于有大量更新操作和查询操作应用的原因，因为，大量的更新操作会造成查询操作很难获得读锁，从而可能永远阻塞。</li>
<li>MySQL服务启动后，我们可以用&#8221;show variables&#8221;和&#8221;show status&#8221;命令查看MySQL的服务器静态参数值和动态运行状态信息。其中前者是在数据库启动后不会动态更改的值，比如缓冲区大小、字符集、数据文件名称等；后者是数据库运行期間的动态变化的信息，比如锁等待、当前连接数等；也可以在操作系统下直接查看数据库参数或数据库状态信息，&#8221;mysqladmin -uroot variables&#8221;。</li>
<li>一些影响MySQL性能的重要参数：
<ul>
<li>key_buffer_size：设置索引块缓存的大小，它被所有线路共享，此参数只适用于MyISAM存储引擎。</li>
<li>table_cache：表示数据库用户打开表的缓存数量。每个连接进来，都会至少打开一个表缓存。因此，table_cache与max_connections有关，对于M个并行运行的连接，应该让表缓存至少有M*N，N为可以执行的查询的一个联接中表的最大数量。</li>
<li>innodb_buffer_pool_size：定义了InnoDB存储引擎的表数据和索引数据的最大内存缓冲区大小。和MyISAM存储引擎不同，MyISAM的key_buffer_size只缓存索引键，而innodb_buffer_pool_size却是同时为数据块和索引块做缓存。这个值设得越高，访问表中数据需要的磁盘I/O就越少。</li>
<li>innodb_flush_log_at_trx_commit：用来控制缓冲区中的数据写入到日志文件以及日志文件数据刷新到磁盘的操作时机。</li>
<li>innodb_additional_mem_pool_size：表示InnoDB存储引擎用来存储数据库结构和其他内部数据结构的内存池大小，其默认值是1MB。应用程序里的表越多，则需要在这里分配越多的内存。</li>
<li>innodb_support_xa：设置是否支持分布式事务，默认值是ON或者1，表示支持分布式事务。</li>
<li>innodb_log_buffer_size：表示日志缓存的大小。如果它的值设置太高了，可能会浪费内存，因为它每秒都会刷新一次，因此无须设置超过1秒所需的内存空间。默认值为1MB。</li>
<li>innodb_log_file_size：表示一个日志组(log group)中每个日志文件的大小。此参数在高写入负载尤其是大数据集的情况下很重要。这个值越大则性能相对越高，但是带来的副作用是，当系统灾难时恢复时间会加大。系统默认值为5MB。</li>
</ul>
</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://blog.endlesscode.com/2009/12/29/mysql-book-optimization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>《深入浅出MySQL》读书拾遗-基础开发</title>
		<link>http://blog.endlesscode.com/2009/12/23/mysql-book-basic-dev/</link>
		<comments>http://blog.endlesscode.com/2009/12/23/mysql-book-basic-dev/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 16:50:12 +0000</pubDate>
		<dc:creator>Stephen</dc:creator>
				<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://blog.endlesscode.com/?p=48</guid>
		<description><![CDATA[一、    MySQL入门 DDL(Data Definition Languages)语句：数据定义语言，这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象。常用的语句关键字主要包括create、drop、alter等。 DML(Data Manipulation Languages)语句：数据操纵语句，用于添加、删除、更新和查询数据库记录，并检查数据库完整性。常用的语句关键字主要包括insert、delete、update和select等。 DCL(Data Control Language)语句：数据控制语句，用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。 change和modify都可以修改表的定义，不同的是change后面需要写两次列名，不方便。但是change的优点是可以修改列名称，modify则不能。 二、    MySQL支持的数据类型 MySQL支持的数值类别有TINYINT, SMALLINT, MEDIUMINT, INT/INTEGER, BIGINT, FLOAT, DOUBLE, DEC(M,D)/DECIMAL(M,D), BIT(M) 在5个整数类型中，如果超出类型范围的操作，会发生“Out of range”的错误提示。 对于整型数据，MySQL还支持在类型名称后面的小括号内指定显示宽度，例如int(5)表示当数值小于5位的时候在数字前面填满宽度，如果不显示指定宽度则默认为int(11)。一般配合zerofill使用，zerofill就是用“0”填充的意思，也就是在数字位数不够的空间用字符“0”填满。 一个表中最多只能有一个AUTO_INCREMENT列。对于任何想要使用AUTO_INCREMENT的列，应该定义为NOT NULL，并定义为PRIMARY KEY或定义为UNIQUE键。 浮点数(Float/Double)和定点数(Decimal)都可以用类型名称后加“(M,D)”的方式来进行表示，“(M,D)”表示该值一花显示M位数字(整数位+小数位)，其中D位位于小数点后面，M和D又称为精度和标度。 浮点数如果不写精度和，则会按照实际精度值显示，如果有精度和标度，则会自动将四舍五入的结果插入，系统不会报错；定点数如果不写精度和标度，则按照默认值DECIMAL(10,0)来进行操作，并且如果数据超越了精度和标度值，系统则会报错。 BIT(M)可以用来存放多位二进制数，M范围从1~64，如果不写则默认为1位。对于位字段，直接使用SELECT命令将不会看到结果，可以用bin()(显示为二进制格式)或者hex()(显示为十六进制格式)函数进行读取。 数据插入BIT类别字段时，首先转换为二进制，如果位数允许，将成功插入；如果位数小于实际定义的数，则插入失败。如果长度过长则直接所有位填充1(自己测试的)。 MySQL中的日期和时间类型有DATE, DATETIME, TIMESTAMP, TIME, YEAR。每种日期时间类型都有一个有效值范围，如果超出这个范围，在默认的SQLMode下，系统会进行错误提示，并将以零值来进行存储。 MySQL只给表中的第一个TIMESTAMP字段设置默认值为系统日期，如果有第二个TIMESTAMP类型，则默认值设置为0值，因为MySQL规定TIMESTAMP类型字段只能有一列的默认值为CURRENT_TIMESTAMP。 &#8230; <a href="http://blog.endlesscode.com/2009/12/23/mysql-book-basic-dev/">Continue reading <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>一、    MySQL入门</p>
<ol>
<li>DDL(Data Definition Languages)语句：数据定义语言，这些语句定义了不同的数据段、数据库、表、列、索引等数据库对象。常用的语句关键字主要包括create、drop、alter等。</li>
<li>DML(Data Manipulation Languages)语句：数据操纵语句，用于添加、删除、更新和查询数据库记录，并检查数据库完整性。常用的语句关键字主要包括insert、delete、update和select等。</li>
<li>DCL(Data Control Language)语句：数据控制语句，用于控制不同数据段直接的许可和访问级别的语句。这些语句定义了数据库、表、字段、用户的访问权限和安全级别。主要的语句关键字包括grant、revoke等。</li>
<li>change和modify都可以修改表的定义，不同的是change后面需要写两次列名，不方便。但是change的优点是可以修改列名称，modify则不能。</li>
</ol>
<p><span id="more-48"></span><br />
二、    MySQL支持的数据类型</p>
<ol>
<li>MySQL支持的数值类别有TINYINT, SMALLINT, MEDIUMINT, INT/INTEGER, BIGINT, FLOAT, DOUBLE, DEC(M,D)/DECIMAL(M,D), BIT(M)</li>
<li> 在5个整数类型中，如果超出类型范围的操作，会发生“Out of range”的错误提示。</li>
<li> 对于整型数据，MySQL还支持在类型名称后面的小括号内指定显示宽度，例如int(5)表示当数值小于5位的时候在数字前面填满宽度，如果不显示指定宽度则默认为int(11)。一般配合zerofill使用，zerofill就是用“0”填充的意思，也就是在数字位数不够的空间用字符“0”填满。</li>
<li>一个表中最多只能有一个AUTO_INCREMENT列。对于任何想要使用AUTO_INCREMENT的列，应该定义为NOT NULL，并定义为PRIMARY KEY或定义为UNIQUE键。</li>
<li>浮点数(Float/Double)和定点数(Decimal)都可以用类型名称后加“(M,D)”的方式来进行表示，“(M,D)”表示该值一花显示M位数字(整数位+小数位)，其中D位位于小数点后面，M和D又称为精度和标度。</li>
<li>浮点数如果不写精度和，则会按照实际精度值显示，如果有精度和标度，则会自动将四舍五入的结果插入，系统不会报错；定点数如果不写精度和标度，则按照默认值DECIMAL(10,0)来进行操作，并且如果数据超越了精度和标度值，系统则会报错。</li>
<li> BIT(M)可以用来存放多位二进制数，M范围从1~64，如果不写则默认为1位。对于位字段，直接使用SELECT命令将不会看到结果，可以用bin()(显示为二进制格式)或者hex()(显示为十六进制格式)函数进行读取。</li>
<li>数据插入BIT类别字段时，首先转换为二进制，如果位数允许，将成功插入；如果位数小于实际定义的数，则插入失败。如果长度过长则直接所有位填充1(自己测试的)。</li>
<li>MySQL中的日期和时间类型有DATE, DATETIME, TIMESTAMP, TIME, YEAR。每种日期时间类型都有一个有效值范围，如果超出这个范围，在默认的SQLMode下，系统会进行错误提示，并将以零值来进行存储。</li>
<li>MySQL只给表中的第一个TIMESTAMP字段设置默认值为系统日期，如果有第二个TIMESTAMP类型，则默认值设置为0值，因为MySQL规定TIMESTAMP类型字段只能有一列的默认值为CURRENT_TIMESTAMP。</li>
<li>TIMESTAMP还有一个重要特点，会先转换为本地时区后存放；而从数据库里面取出时，也同样需要将日期转换为本地时区后显示。</li>
<li>TIMESTAMP的取值范围为19700101080001到2038年的某一天。插入的数值超出下限和上限都会出现警告，并插入0值。</li>
<li>DATETIME的格式允许不严格语法：任何标点符都可以用做日期部分或时间部分之间的间隔符。</li>
<li>MySQL中支持字符类型有，CHAR(M), VARCHAR(M), TINYBLOB, BLOB, MEDIUMBLOB, LONGBLOB, TINYTEXT, TEXT, MEDIUMTEXT, LONGTEXT, VARBINARY(M), BINARY(M)。</li>
<li>CHAR列的长度固定为创建表时声明的长度，长度可以从0~255的任何值；而VARCHAR列中的值为可变长字符串，长度可以指定为0    ~255(5.0.3以前)或65535(5.0.3之后)之间的值。在检索的时候，CHAR列删除尾部的空格，而VARCHAR则保留这些空格。</li>
<li>BINARY和VARBINARY类似于CHAR和VARCHAR，不同的是它们包含二进制字符串而不包含非二进制字符串。当保存BINARY值，在值的最后通过填充“0X00”(零字节)以达到指定的字段长度。</li>
</ol>
<p>三、   常用函数</p>
<ol>
<li>字符串函数：
<ul>
<li>CONCAT(S1,S2,&#8230;,Sn)：把传入的参数连接成为一个字符串</li>
<li>INSERT(str, x, y, instr)：把字符串str从第x位置开始，y个字符长的子串替换为字符串instr</li>
<li>LOWER(str)和UPPER(STR)：把字符串的大小写转换</li>
<li>LEFT(str, x)和RIGHT(str, x)：返回字符串最左边的x个字符和最右边的x个字符。如果第二个参数为NULL，那么将不返回任何字符串</li>
<li>LPAD(str, x, pad)和RPAD(str, n, pad)：用字符串pad对str最左边和最右边进行填充，直到长度为n个字符长度</li>
<li>LTRIM(str)和RTRIM(str)：去年字符串str左侧和右侧空格</li>
<li>REPEAT(str, x)：返回str重复x次的結果</li>
<li>REPLACE(str, a, b)：用字符串b替换字符串str中所有出现的字符串a</li>
<li>STRCMP(s1, s2)：比较字符串s1和s2的ASCII码值的大小</li>
<li>TRIM(str)：去掉目标字符吕的开头和结尾的空格</li>
<li>SUBSTRING(str, x, y)：返回从字符串str中的第x位置起y个字符长度的字串</li>
</ul>
</li>
<li>数值函数：
<ul>
<li>ABS(x)：返回x的绝对值</li>
<li>CEIL(x)：返回大于x的最小整数</li>
<li>FLOOR(x)：返回小于x的最大整数</li>
<li>MOD(x)：返回x/y的模</li>
<li>RAND()：返回0～1内的随机值</li>
<li>ROUND(x, y)：返回参数x的四舍五入的有y位小数的值</li>
<li>TRUNCATE(x, y)：返回数字x截断为y位小数的結果</li>
</ul>
</li>
<li>日期和时间函数：
<ul>
<li>CURDATE()：返回当前日期，只包含年月日</li>
<li>CURTIME()：返回当前时间，只包含时分秒</li>
<li>NOW()：返回当前的日期和时间，年月日时分秒都包含</li>
<li>UNIX_TIMESTAMP(date)：返回日期date的UNIX时间戳</li>
<li>FROM_UNIXTIME(unixtime)：返回UNIXTIME时间戳的日期值，和UNIX_TIMESTAMP(date)互为逆操作</li>
<li>WEEK(DATE)和YEAR(DATE)：前者返回所给的日期是一年中的第几周，后者返回所给的日期是哪一年</li>
<li>HOUR(time)和MINUTE(time)：前者返回所给时间的小时，后者返回所给时间的分钟</li>
<li>MONTHNAME(date)：返回date的英文月份名称</li>
<li>DATE_FORMAT(date, fmt)：按字符串fmt格式化日期date值</li>
<li>DATE_ADD(date, INTERVAL expr type)：返回与所给日期date相差INTERVAL时间段的日期</li>
<li>DATEDIFF(date1, date2)：用来计算两个日期之间相关的天数</li>
</ul>
</li>
<li>其他函数
<ul>
<li>DATABASE()：返回当前数据库名</li>
<li>VERSION()：返回当前数据库版本</li>
<li>USER()：返回当前登录用户名</li>
<li>INET_ATON(IP)：返回IP地址的网络字节序表示</li>
<li>INET_NTOA(num)：返回网络字节序代表的IP地址</li>
<li>PASSWORD(str)：返回字符串str的加密版本，一个41位长的字符串</li>
<li>MD5(str)：返回字符串str的MD5值，常用来对应中的数据进行加密</li>
</ul>
</li>
</ol>
<p>四、   存储引擎</p>
<ol>
<li>MySQL 5.0支持的存储引擎包括 MyISAM、InnoDB、BDB、MEMORY、MERGE、EXAMPLE、NDB Cluster、ARCHIVE、CSV、BLACKHOLE、FEDERATED等，其中InnoDB和BDB提供事务安全表。</li>
<li>如果需要修改默认的存储引擎，则可以在参数文件中设置default-table-type。查看当前的默认存储引擎，可用命令&#8221;show variables like &#8216;table_type&#8217;&#8221;。</li>
<li>查询当前数据库支持的存储引擎有两种方法。第一种为，&#8221;show engines&#8221;，第二种为，&#8221;show variables like &#8216;have%&#8217;&#8221;。</li>
<li>MyISAM
<ul>
<li>MySQL的默认存储引擎。MyISAM不支持事务、也不支持外键，其优势是访问的速度快，对事务完整性没有要求或者以SELECT、INSERT为主的应用基本上都可以使用这个引擎来创建表。</li>
<li>每个MyISAM在磁盘上存储成3个文件，其文件名都和表名相同，但扩展名分别是：.frm(存储表定义)、MYD(MYData，存储数据)、MYI(MYIndex，存储索引)。</li>
<li>MyISAM的表还支持3种不同的存储格式，分别是静态(固定长度)表、动态表和压缩表。</li>
</ul>
</li>
<li>InnoDB
<ul>
<li>InnoDB表的自动增长列可以手工插入，但是插入的值如果是空或者0，则实际插入的将是自动增长后的值。</li>
<li>可以通过&#8221;ALTER TABLE *** AUTO_INCREMENT=n;&#8221;語句强制设置自动增长列的初识值，默认从1开始，但是该强制的默认值是保留在内存中的，如果该值在使用之前数据库重新启动，那么这个强制的默认值就会丢失，就需要在数据库启动以后重新设置。</li>
<li>可以使用LAST_INSERT_ID()查询当前线程最后插入记录使用的值。如果一次插入了多条记录，那么返回的是第一条记录使用的自动增长值。</li>
<li>自动增长列必须是索引。如果是组合索引，也必须是组合索引的第一列，但是对于MyISAM表，自动增长列可以是组合索引的其他列，这样插入记录后，自动增长列是按照组合索引前几列排序后在同值的类里面递值的。</li>
<li>使用共享表存储，这种方式创建的表的表结构保存在.frm文件中，数据和索引保存在innodb_data_home_dir和innodb_data_file_path定义的表空间中，可以是多个文件。</li>
<li>使用多表空间存储，这种方式创建的表的表结构仍然保存在.frm文件中，但是每个表的数据和索引单独保存在.idb中。</li>
<li>多表空间的参数生效后，只对新建的表生效，其表的数据文件没有大小限制，不需要设置初始大小，也不需要设置文件的最大限制、扩展大小等参数。</li>
</ul>
</li>
<li>MEMORY
<ul>
<li>每个MEMORY表只实际对应一个磁盘文件，格式是.frm。MEMORY类型的表访问非常得快，因为它的数据是放在内存中的，并且默认使用HASH索引，但是一旦服务关闭，表中的数据就会丢失掉。</li>
<li>每个MEMORY表中可以放置的数据量的大小，受到max_heap_table_size系统变量的約束，这个系统变量的初始值是16MB，可以按照需要加大。</li>
</ul>
</li>
<li>MERGE
<ul>
<li>MERGE存储引擎是一组MyISAM表的组合，这些MyISAM表必须结构完全相同，MERGE表本身并没有数据，对MERGE类型的表可以进行查询、更新、删除的操作，这些操作实际上是对内部的实际的MyISAM表进行的。</li>
<li>MERGE表在磁盘上保留两个文件，文件名以表的名字开始，一个.frm文件存储表定义，另一个.MRG文件包含组合表的信息，包括MERGE表由哪些表组成、插入新的数据时的依据。可以通过修改.MRG文件来修改MERGE表，但是修改后要通过FLUSH TABLES刷新。</li>
</ul>
</li>
</ol>
<p>五、  字符集</p>
<ol>
<li>查看所有可用的字符集的命令是&#8221;show character set&#8221;或者&#8221;desc information_schema.character_sets&#8221;。</li>
<li>字符集是用来定义MySQL存储字符串的方式，校对规则是定义了比较字符串的方式。</li>
<li>每个字符集至少对应一个校对规则。可以用&#8221;show collation like &#8216;utf-8/gbk/***&#8217;&#8221;命令或者查看information_schema.COLLATIONS。</li>
<li>校对规则命名约定：它们以其相关的字符集名开始，通常包括一个语言名，并且以_ci(大小写不敏感)、_cs(大小写敏感)或_bin(二元，即比较是基于字符编码的值而与language无关)结束。</li>
<li>MySQL的字符集和校对规则有４个级别的默认设置：服务器级、数据库级、表级和字段级。</li>
<li>服务器字符集和校对，在MySQL服务启动的时候确定。可以在my.cnf中设置：default-character-set=gbk。或者在启动选项中指定：mysqld &#8211;default-character-set=gbk。或者在编译的时候指定：./configure &#8211;with-charaset=gbk。</li>
<li>如果没有特别的指定服务器字符集，默认使用latin1作为服务器字符集。可以通过&#8221;show variables like &#8216;character_set_server&#8217;&#8221;和&#8221;show variables like &#8216;collation_server&#8217;&#8221;查看当前服务器的字符集和校对规则。</li>
<li>数据库的字符集和校对规则在创建数据库的时候指定，如果没有指定，则应用服务器的字符集和校对规则的配置。要显示当前数据库的字符集和校对规则，可以使用&#8221;show variables like &#8216;character_set_database&#8217;&#8221;和&#8221;show variables like &#8216;collation_database&#8217;&#8221;命令查看。</li>
<li>设置了以上４个级别的字符集，对于实际的应用访问来说，还存在客户端和服务器之间交互的字符集和校对规则的设置。对于客户端和服务器的交互操作，MySQL提供了３个不同的参数：character_set_client、character_set_connection和character_set_results，分别代表客户端、连接和返回結果的字符集。通过情况下，这３个字符集应该是相同的，才可以确保用户写入的数据可以正确地读出。</li>
<li>可以通过&#8221;SET NAMES ***&#8221;来设置连接的字符集和校对规则，这个命令可以同时修改这３个参数的值。使用这个方法修改连接的字符集和校对规则，需要应用每次连接数据库后都执行这个命令。</li>
<li>可以在my.cnf中设置&#8221;default-character-set=gbk&#8221;，这样服务器启动后，所有连接默认就是使用GBK字符集进行连接的，而不需要在程序中再执行set names命令了。</li>
</ol>
<p><img id="myFxSearchImg" style="border: medium none ; position: absolute; z-index: 2147483647; opacity: 0.6; display: none;" src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAADsElEQVR4nK2VTW9VVRSGn33OPgWpYLARbKWhQlCHTogoSkjEkQwclEQcNJEwlfgD/AM6NBo1xjhx5LyJ0cYEDHGkJqhtBGKUpm3SFii3vb2956wPB/t+9raEgSs52fuus89613rftdcNH8/c9q9++oe/Vzb5P+3McyNcfm2CcPj9af9w6gwjTwzvethx3Bx3x8xwd1wNM8dMcTNUHTfFLPnX6nVmZpeIYwf3cWD/PhbrvlPkblAzVFurKS6GmmGqqComaS+qmBoTI0Ncu3mXuGvWnrJ+ZSxweDgnkHf8ndVTdbiT3M7cQp2Z31dRTecHAfqydp4ejhwazh6Zezfnu98E1WIQwB3crEuJ2Y45PBTAQUVR9X4At66AppoEVO1Q8sgAOKJJjw6Am6OquDmvHskZ3R87gW+vlHz98zpmiqphkkRVbQtsfPTOC30lJKFbFTgp83bWh7Zx/uX1B6w3hI3NkkZTqEpBRDBRzG2AQHcwcYwEkOGkTERREbLQ/8HxJwuW7zdYrzfZ2iopy4qqEspKaDYravVm33k1R91Q69FA1VBRzFIVvXbx5AgXT44A8MWP81yfu0utIR2aVK3vfCnGrcUNxp8a7gKYKiLCvY2SUvo/aNtnM3e49ucK9S3p0aDdaT0UAVsKi2tVi6IWwNL9JvdqTdihaz79/l+u/rHMxmaJVMLkS2OoKKLWacdeE3IsSxctc2D5Qcl6vUlVVgNt+fkPPcFFmTw1xruvT7SCd7nuVhDQvECzJH90h0azRKoKFRkAmP5lKTWAGRdefoZL554FQNUxB92WvYeA5UN4PtSqwB2phKqsqMpBgAunRhFR3j49zuU3jnX8k6fHEQKXzh1jbmGDuYU6s4t1rt6socUeLLZHhYO2AHSHmzt19ihTZ48O8Hzl/AmunD/BjTvrvPfNX3hWsNpwJCvwYm+ngug4UilSCSq6k8YPtxDwfA+WRawIWFbgscDiULcCEaWqBFOlrLazurupOSHLqGnEKJAY8TwBEHumqUirAjNm52vEPPRV4p01XXMPAQhUBjcWm9QZwijwokgAeYHlHYA06KR1cT6ZvoV56pDUJQEjw0KeaMgj1hPEY4vz2A4eW0/e1qA7KtQdsxTYAG0H3iG4xyK1Y+xm7XmEPOJZDiENzLi2WZHngeOjj2Pe+sMg4GRYyLAsx7ME4FnsyTD9pr0PEc8zPGRAwKXBkYOPEd96cZRvf11g9MDe7e3R4Z4Q+vyEnn3P4t0XzK/W+ODN5/kPfRLewAJVEQ0AAAAASUVORK5CYII%3D" alt="" width="24" height="24" /></p>
]]></content:encoded>
			<wfw:commentRss>http://blog.endlesscode.com/2009/12/23/mysql-book-basic-dev/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

