<?xml version="1.0" encoding="UTF-8" ?>
<rss version="2.0">
<channel>
<title><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></title> 
<link>http://jackxiang.com/index.php</link> 
<description><![CDATA[赢在IT，Playin' with IT,Focus on Killer Application,Marketing Meets Technology.]]></description> 
<language>zh-cn</language> 
<copyright><![CDATA[向东博客 专注WEB应用 构架之美 --- 构架之美，在于尽态极妍 | 应用之美，在于药到病除]]></copyright>
<item>
<link>http://jackxiang.com/post//</link>
<title><![CDATA[[精华]MySQL主从服务器的一些技巧]]></title> 
<author>jack &lt;xdy108@126.com&gt;</author>
<category><![CDATA[WEB2.0]]></category>
<pubDate>Mon, 17 Nov 2008 03:43:08 +0000</pubDate> 
<guid>http://jackxiang.com/post//</guid> 
<description>
<![CDATA[ 
	作者：老王<br/><br/>问题：主从服务器表类型的选择<br/><br/>一般的共识是主服务器使用innodb，从服务器使用myisam，以便各尽其能。<br/><br/>问题：主从服务器字段类型的选择<br/><br/>字段类型对于分页等操作有很大影响。主服务器一般是innodb，因为不涉及查询，所以可以使用varchar等来存储字符串来节省空间，从服务器一般是 myisam，因为涉及查询，所以必须在char和varchar之间仔细权衡，没有varchar, text, blob字段的表是静态表，反之是动态表，静态表的检索效率要比动态表好若干倍，一般来说，所有涉及大结果集的查询都应该尽可能保证在静态表上完成，这里说一个例子：比如说常见的articles表有title(varchar), body(text)等字段，在做文章列表的时候，因为不是静态表，所以查询不会很快，下面开始重构解决方案：把原来的articles表拆分成 subjects表和contents表，title字段设置为一个足够的char类型放在subjects表里，body字段还保持是text类型放到 contents表里，subjects和contents表之间的关系是一对多，这样，顺带着也方便的实现了多页文章的功能，而且更重要的是在查询文章列表的时候，操作都是在subjects静态表里完成，效率肯定会比前一种方案提升很多。<br/><br/>问题：主从服务器NOW()函数造成数据不一致<br/><br/>假设在主服务器上执行一条INSERT …. VALUES ( …, NOW())，那么在从服务器上也会同样执行一条的SQL语句，但是主从服务器各自的时间设置可能不一致（比如说时区不同），NOW()在两台服务器上的结果就可能不一致。解决方法是显而易见的，就是不要使用NOW()，时间的计算在应用程序里完成。这里介绍一个额外的小技巧：获得时间戳，和time() 相比，$_SERVER[‘REQUEST_TIME’] 少做了一次系统调用，不过是否合适要视客观情况而定。<br/><br/>问题：主从服务器读写分离时读操作失败<br/><br/>先重现一下问题：比如说添加一条新数据，添加成功后根据last_insert_id跳转到新添加数据的浏览页面。在此过程中添加新数据的操作是在主服务器上完成的，浏览新数据的操作实在从服务器上完成的，不过由于主从服务器间SQL同步存在延迟，所以当使用last_insert_id在从服务器上查询的时候，从服务器很可能还没有还没来得及同步到此记录，所以读操作失败。解决思路也不复杂，在代码里加入一个缓存层（可以使用memcached），新添加的数据都顺手放到缓存层里一份，新数据的读操作也先查询缓存层，这样就不会再有读操作失败的问题了，当然删除或者更新数据的时候也要顺带着处理好缓存数据，可以使用观察者模式来搞定。不过这样缓存方案只限于读取单一的记录，对于读取列表的记录的情况，则是无效的。<br/><br/>问题：主从服务器索引是否有必要保持一致<br/><br/>一般都是利用主从服务器完成读写分离，从服务器上进行读操作，主服务器进行写操作，这样的话，主服务器上仅保留主键，外键，唯一索引等必要的索引即可，以便保持数据合法性，而对于那些原本用于优化SELECT操作的索引，可以全部删除，如此的话主服务器的写操作效率会提升很多。<br/><br/>网友评论：<br/>1 &nbsp;&nbsp;<br/>网友:三马<br/>&nbsp;&nbsp;2008年11月11日 星期二 下午 08:31<br/>受教：）<br/> <br/>2 &nbsp;&nbsp;<br/>匿名网友<br/>&nbsp;&nbsp;2008年11月12日 星期三 下午 10:39<br/>牛！<br/> <br/>3 &nbsp;&nbsp;<br/>网友:phzzy<br/>&nbsp;&nbsp;2008年11月14日 星期五 上午 11:13<br/>组号不要用 $_SERVER[‘REQUEST_TIME’]，特别是接口里<br/>如果后台进程调用这个接口，则没有这个值<br/>用 time() 不会比 $_SERVER[‘REQUEST_TIME’] 多耗多少资源<br/> <br/>4 &nbsp;&nbsp;<br/>网友:yejr<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 01:43<br/>问题：主从服务器NOW()函数造成数据不一致<br/><br/>早就没问题了。<br/>另外，适合自己的业务模式才是最合理的，太古董的东西最好标明发帖时间。<br/> <br/>9 &nbsp;&nbsp;<br/>网友:老王<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 04:00<br/>@yejr：我查阅了一下官方文档，上面是这么说的：应在主服务器和从服务器上设置相同的系统时区。否则一些语句，例如使用NOW()或FROM_UNIXTIME()函数的语句，将不会正确复制。<br/><br/>http://dev.mysql.com/doc/refman/5.1/zh/replication.html<br/> <br/>10 &nbsp;&nbsp;<br/>网友:老王<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 04:24<br/>@phzzy：我在命令行下调用，也是有$_SERVER[‘REQUEST_TIME’]的，不知道你说的是何种调用。<br/> <br/>11 &nbsp;&nbsp;<br/>网友:phzzy<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 05:16<br/>说错了<br/>是在 php 长期执行的进程里，比如server或daemon<br/>任何时候取 $_SERVER[‘REQUEST_TIME’] 都是进程开始的时间，而不是当前时间<br/> <br/>12 &nbsp;&nbsp;<br/>网友:zeal<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 05:53<br/>NOW()函数不会因为主从服务器之间同步的时间差而造成数据不一致，因为mysql会通过 seconds_behind_master 参数来自动进行校正。<br/>当然前提是主从服务器的系统时间必须保持一致。<br/> <br/>15 &nbsp;&nbsp;<br/>网友:老王<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 08:34<br/>@phzzy：确实，使用$_SERVER[&#039;REQUEST_TIME&#039;]要分清场合。<br/> <br/>16 &nbsp;&nbsp;<br/>网友:老王<br/>&nbsp;&nbsp;2008年11月14日 星期五 下午 08:34<br/>@yejr, @zeal：我看到binlog里记录的是NOW()而不是实际的时间，就惯性的以为SQL同步延迟会使NOW()在主从服务器上出现差异，多谢提醒。<br/> 
]]>
</description>
</item><item>
<link>http://jackxiang.com/post//#blogcomment</link>
<title><![CDATA[[评论] [精华]MySQL主从服务器的一些技巧]]></title> 
<author> &lt;user@domain.com&gt;</author>
<category><![CDATA[评论]]></category>
<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate> 
<guid>http://jackxiang.com/post//#blogcomment</guid> 
<description>
<![CDATA[ 
	
]]>
</description>
</item>
</channel>
</rss>