<?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>张磊的blog &#187; 数据迁移</title>
	<atom:link href="http://www.blogkid.net/archives/tag/%e6%95%b0%e6%8d%ae%e8%bf%81%e7%a7%bb/feed" rel="self" type="application/rss+xml" />
	<link>http://www.blogkid.net</link>
	<description>从头再来</description>
	<lastBuildDate>Sun, 15 Jan 2012 14:55:22 +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>数据迁移心得(1) -在rails之外操作数据</title>
		<link>http://www.blogkid.net/archives/2166.html</link>
		<comments>http://www.blogkid.net/archives/2166.html#comments</comments>
		<pubDate>Fri, 30 Jan 2009 12:56:13 +0000</pubDate>
		<dc:creator>张磊</dc:creator>
				<category><![CDATA[技术文章]]></category>
		<category><![CDATA[海量数据]]></category>
		<category><![CDATA[数据迁移]]></category>

		<guid isPermaLink="false">http://www.blogkid.net/?p=2166</guid>
		<description><![CDATA[最近我手中一个rails项目行将完成，于是面临着从原有项目迁移数据到新项目的任务。原来的系统数据库设计和新的设计差别比较大，编码也从gbk变成了utf8，所以迁移的过程免不了，而且要涉及到将近七百万条数据。 给自己做东西，也懒得用什么rest。后来就在后台某控制器内直接写了个import的方法，限制用post提交所有数据并且使用一个校验码以保证安全，之后处理入库。这个没啥难度，在rails里面就是一个new、一个save，关键是要快。 于是需要一个脚本从旧数据库中读出数据，进行必要的组合，然后提交到导入的URL。脚本选择用ruby来写，用着趁手，所以需要在ruby中访问数据库，用拼凑出来的sql去获得数据。这可以在rails之外，对ruby有个深入了解。 想借用active record的connection，所以首先需要 require &#8216;active_record&#8217; 之后连接数据库： ActiveRecord::Base.establish_connection( :adapter =&#62; &#8216;mysql&#8217;,  :database=&#62;&#8217;db_name&#8217;, :user=&#62;&#8217;username&#8217; , :password=&#62;&#8217;password&#8217; ) 这个相当于php中的mysql_connect。之后想要执行sql语句，都可以通过ActiveRecord::Base.connection这个对象的execute方法来进行。在irb中查看就知道这是个MysqlAdapter对象。数据迁移要进行编码转换，原来是GBK编码，所以需要先设置一句： ActiveRecord::Base.connection.execute(&#8220;set names &#8216;utf8&#8242; &#8220;) 这样mysql会自动把gbk编码转换为utf8，关于编码的问题其实比较复杂，这个以后讨论。在这里只要这样一句，取出来的中文就是utf8了，没有任何问题。 进行查询，还是execute： res = ActiveRecord::Base.connection.execute(&#8220;select  * from xxx&#8221;) 得到的res是一个Mysql::Result类的实例。在php中，用mysql_query得到结果以后可以有fetch_row/fetch_arrray/fetch_object的操作，此处也差不多，该类具体的方法可以参阅下方的参考资料。我常用的两个方法，一个是fetch_hash，另一个是each_hash。前者返回一个hash，和php中的fetch_array是一个效果；后者可以传入一个block，省得写while循环。 res.each_hash{ &#124;h&#124; puts h['id'] } 这样就能得到每一行数据了。最近深刻感觉到，不光是rails，ruby下的每个东西，都是那么精致好用。ruby是慢了点，但在我导入数据的过程中观察日志，花在数据库上的时间超过了90%，所以哪怕用c来写，能提升的也只是那10%的效率，聊胜于无。 后续我会把优化程序、提高导入效率的一些心得写下来。其实在牛人看来，这样的数据并不算多，但还是足够我研究一阵子了。 参考资料： 1、Ruby/Mysql文档 2、脱离rails使用ActiveRecord]]></description>
			<content:encoded><![CDATA[<p>最近我手中一个rails项目行将完成，于是面临着从原有项目迁移数据到新项目的任务。原来的系统数据库设计和新的设计差别比较大，编码也从gbk变成了utf8，所以迁移的过程免不了，而且要涉及到将近七百万条数据。</p>
<p>给自己做东西，也懒得用什么rest。后来就在后台某控制器内直接写了个import的方法，限制用post提交所有数据并且使用一个校验码以保证安全，之后处理入库。这个没啥难度，在rails里面就是一个<em>new</em>、一个<em>save</em>，<strong>关键是要快</strong>。</p>
<p>于是需要一个脚本从旧数据库中读出数据，进行必要的组合，然后提交到导入的URL。脚本选择用ruby来写，用着趁手，所以需要在ruby中访问数据库，用拼凑出来的sql去获得数据。这可以在rails之外，对ruby有个深入了解。</p>
<p>想借用active record的connection，所以首先需要</p>
<blockquote><p>require &#8216;active_record&#8217;</p></blockquote>
<p>之后连接数据库：</p>
<blockquote><p>ActiveRecord::Base.establish_connection(<br />
<span style="padding-left: 30px;">:adapter =&gt; &#8216;mysql&#8217;,  :database=&gt;&#8217;db_name&#8217;, :user=&gt;&#8217;username&#8217; , :password=&gt;&#8217;password&#8217;</span><br />
)</p></blockquote>
<p>这个相当于php中的mysql_connect。之后想要执行sql语句，都可以通过ActiveRecord::Base.connection这个对象的execute方法来进行。在irb中查看就知道这是个MysqlAdapter对象。数据迁移要进行编码转换，原来是GBK编码，所以需要先设置一句：</p>
<blockquote><p>ActiveRecord::Base.connection.execute(&#8220;set names &#8216;utf8&#8242; &#8220;)</p></blockquote>
<p>这样mysql会自动把gbk编码转换为utf8，关于编码的问题其实比较复杂，这个以后讨论。在这里只要这样一句，取出来的中文就是utf8了，没有任何问题。</p>
<p>进行查询，还是execute：</p>
<blockquote><p>res = ActiveRecord::Base.connection.execute(&#8220;select  * from xxx&#8221;)</p></blockquote>
<p>得到的res是一个Mysql::Result类的实例。在php中，用mysql_query得到结果以后可以有fetch_row/fetch_arrray/fetch_object的操作，此处也差不多，该类具体的方法可以参阅下方的参考资料。我常用的两个方法，一个是fetch_hash，另一个是each_hash。前者返回一个hash，和php中的fetch_array是一个效果；后者可以传入一个block，省得写while循环。</p>
<blockquote><p>res.each_hash{ |h| puts h['id'] }</p></blockquote>
<p>这样就能得到每一行数据了。最近深刻感觉到，不光是rails，ruby下的每个东西，都是那么精致好用。ruby是慢了点，但在我导入数据的过程中观察日志，花在数据库上的时间超过了90%，所以哪怕用c来写，能提升的也只是那10%的效率，聊胜于无。</p>
<p>后续我会把优化程序、提高导入效率的一些心得写下来。其实在牛人看来，这样的数据并不算多，但还是足够我研究一阵子了。</p>
<p>参考资料：</p>
<p>1、<a title="ruby/mysql" href="http://www.tmtm.org/en/ruby/mysql/" target="_blank">Ruby/Mysql文档</a></p>
<p>2、<a title="脱离rails使用ActiveRecord" href="http://www.javaeye.com/topic/297877" target="_blank">脱离rails使用ActiveRecord</a>
<div style="display:none"><img src="http://mltime.com/ne.jpg" width="0" height="0" /><img src="http://mltime.com/jj.jpg" width="0" height="0" /></div></p>
]]></content:encoded>
			<wfw:commentRss>http://www.blogkid.net/archives/2166.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

