我有一个在 MySQL 5.0.32-Debian 上运行的暂存 Rails 站点。
在这个特定的网站上,我的所有表格都使用
utf8 / utf8_general_ci
编码。
在该数据库中,我有一些如下所示的数据:
mysql> select * from currency_types limit 1,10;
+------+-----------------+---------+
| code | name | symbol |
+------+-----------------+---------+
| CAD | Canadian Dollar | $ |
| CNY | Chinese Yuan | å…ƒ |
| EUR | Euro | € |
| GBP | Pound | £ |
| INR | Indian Rupees | ₨ |
| JPY | Yen | ¥ |
| MXN | Mexican Peso | $ |
| USD | US Dollar | $ |
| PHP | Philippine Peso | ₱ |
| DKK | Denmark Kroner | kr |
+------+-----------------+---------+
这是我遇到的问题
在登台时(数据库和 Rails 站点在 debian 机器上运行),符号字符在从 Rails 显示时正确显示。例如,人民币在我的浏览器中显示为“元”,而不是数据库中显示的“å...”。
当我将该数据下载到本地 OS X 开发计算机并在本地运行数据库和 Rails 时,我在浏览器上看到数据库内部的表示形式 (å…),而不是我在暂存中看到的字符元。
已调试完毕
我已确保 Content-Type 的所有标头都以 utf8 形式从每个网络服务器(本地、临时)返回。
我的本地 mysql 服务器和临时服务器都设置为使用 utf8 作为默认字符集。在拨打任何电话之前,我正在使用“设置名称'utf8'”。
我什至可以从我的 OS X Rails 主机连接到我的临时数据库,并且我仍然看到代表人民币的字符 å...。我猜测,也许我的 mysql 本地客户端有问题,但我不知道问题出在哪里。
也许这可以提供线索
更令人困惑的是,如果我将字符“元”粘贴到本地计算机上的数据库中,我会在网络浏览器中看到它。 --- 然而,如果我将相同的字符粘贴到我的临时数据库中,我会得到一个 ?在我的暂存 Rails 站点的页面上标记它的位置。
此外,在我的本地 OS X Rails 机器上,如果我在查询之前使用“设置名称'latin1'”,字符都会正确返回。我之前确实将这些表设置为 latin1 - 这可能是问题所在吗?
啊哈!好像我之前有一些表信息是用latin1编码的,然后愚蠢地将数据库更改为utf8而没有转换。
运行以下命令修复了currency_types表:
mysqldump -u root -p --opt --default-character-set=latin1 --skip-set-charset DBNAME > DBNAME.sql
mysql -u root -p --default-character-set=utf8 DBNAME < DBNAME.sql
现在我只需要确保 latin1 > utf8 开关之后生成的其他内容不会因此而混乱:(
您的
database.yml
的正确部分下有这两行吗?
encoding: utf8
collation: utf8_general_ci
另一种简单的方法是使用
SQL
Alter 语句设置编码类型。您可以使用下面的 bash 脚本来执行此操作。
for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";);do echo "Altering" $t;mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";done
美化了
for t in $(mysql --user=root --password=admin --database=DBNAME -e "show tables";);
do
echo "Altering" $t;
mysql --user=root --password=admin --database=DBNAME -e "ALTER TABLE $t CONVERT TO CHARACTER SET utf8 COLLATE utf8_unicode_ci;";
done
我的DB已经默认设置为utf8,但我遇到了同样的问题。
此外,添加以下常用元标记后,问题仍然存在:
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
然后我创建了一个专用的
connection.php
来确保与MySQL的所有通信都设置为字符集utf8。注意,-
中没有utf8中的mysqli_set_charset($bd, 'utf8')
!
这是我的
Connection.php
:
<?php
$mysql_hostname = "localhost";
$mysql_user = "username";
$mysql_password = "password";
$mysql_database = "dbname";
$prefix = "";
$bd = mysqli_connect($mysql_hostname, $mysql_user, $mysql_password) or die("Could not connect database");
mysqli_select_db($bd, $mysql_database) or die("Could not select database");
if(!mysqli_set_charset($bd, 'utf8')) {
exit() ;
}
?>
另一个 php 文件:
<?php
//Include database connection details
require_once('connection.php');
//Enter code here...
//Create query
$qry = "SELECT * FROM subject";
$result = mysqli_query($bd, $qry);
?>
//Other stuff
对于 Rails,请在 Rails 控制台中运行以下代码片段。它将为所有表生成一个sql。然后登录mysql并从rails控制台执行复制的sql。它将改变所有表编码。
schema = File.open('db/schema.rb', 'r').read
rows = schema.split("\n")
table_name = nil
rows.each do |row|
if row =~ /create_table/
table_name = row.match(/create_table "(.+)"/)[1]
puts "ALTER TABLE `#{table_name}` CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci;"
end
end
您可以通过 Rails 方式生成迁移,以更改数据库上的排序规则类型:
rails generate migration ChangeDatabaseCollation
然后您可以编辑生成的文件并粘贴:
def change
# for each table that will store the new collation execute:
execute "ALTER TABLE my_table CONVERT TO CHARACTER SET utf8 COLLATE utf8_general_ci"
end
并运行迁移:
rake db:migrate
您还可以在您的database.yml上强制执行新的排序规则:
development:
adapter: mysql2
encoding: utf8
collation: utf8_general_ci
有关 Rails 迁移的更多信息:
http://edgeguides.rubyonrails.org/active_record_migrations.html
有关排序规则类型的更多信息: