最近又用mysql了,重温了下基本操作,开始针对以前没用到的一些方面做些记录,以便日后查阅吧。
首先是中文乱码。这个是字符集的问题,这里有必要先说明支持中文几个常用的字符集:GBK、GB2312、UTF8。
- UTF- 8:Unicode Transformation Format-8bit,允许含BOM,但通常不含BOM。是用以解决国际上字符的一种多字节编码,它对英文使用8位(即一个字节),中文使用24为(三个字节)来编码。UTF-8包含全世界所有国家需要用到的字符,是国际编码,通用性强。UTF-8编码的文字可以在各国支持UTF8字符集的浏览器上显示。如果是UTF8编码,则在外国人的英文IE上也能显示中文,他们无需下载IE的中文语言支持包。
- GBK是国家标准GB2312基础上扩容后兼容GB2312的标准。GBK的文字编码是用双字节来表示的,即不论中、英文字符均使用双字节来表示,为了区分中文,将其最高位都设定成1。GBK包含全部中文字符,是国家编码,通用性比UTF8差,不过UTF8占用的数据库比GBD大。
- 显然GB2312是GBK的子集。
GBK、GB2312等与UTF8之间都必须通过Unicode编码才能相互转换:
GBK、GB2312--Unicode--UTF8
UTF8--Unicode--GBK、GB2312
总而言之,还是要根据具体需求使用相应的字符集,比较懒的做法是直接使用utf-8。
背景说完了,回到mysql来,mysql本身包含了一下几个方面涉及到字符集:
- character-set-server/default-character-set:服务器字符集,默认情况下所采用的。
- character-set-database:数据库字符集。
- character-set-table:数据库表字符集。
- character-set-client:客户端的字符集。客户端默认字符集。当客户端向服务器发送请求时,请求以该字符集进行编码。
- character-set-results:结果字符集。服务器向客户端返回结果或者信息时,结果以该字符集进行编码。
一般来说,出现乱码有几种情况:server本身设定问题;table的语系设定问题;客户端例如php)的连接语系设定问题。分别讨论,前两个的问题比较简单,查看其设定,不支持的话直接使用“set”命令修改即可,比如server的设定修改:set character-set-serve=utf-8。最后一下时客户端,这个需要参照具体客户端的配置。
要想避免出现乱码,最好先把服务器相关的设定都改为utf-8,或者直接在mysql的配置文件my.cnf下[mysql]段加入default_character_set=utf8;然后在创建新的数据库和表时明确指定编码格式为utf-8:
针对数据库:CREATE DATABASE `test` CHARACTER SET 'utf8' COLLATE 'utf8_general_ci';
针对数据表:CREATE TABLE `database_user` (...) DEFAULT CHARSET=utf8;
对于已经存在的数据库和表,查看创建库表的信息即可获取具体编码格式:
show create database db_name;
show create table table_name;
然后可以使用“alter”命令来修改:
ALTER DATABASE `db_name` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
ALTER TABLE `tb_name` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci;
其次是TIMESTAMP。TIMESTAMP是mysql中的一种数据类型,在使用时有如下几种方式:
- TIMESTAMP DEFAULT CURRENT_TIMESTAMP:在创建新记录的时候把这个字段设置为当前时间,但以后修改记录时,不主动刷新它。
- TIMESTAMP DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP:在上一种的基础上,每次更新数据主动刷新该字段。
- TIMESTAMP ON UPDATE CURRENT_TIMESTAMP:在创建新记录的时候把这个字段设置为0,以后修改记录时主动刷新该字段。
- TIMESTAMP DEFAULT 'yyyy-mm-dd hh:mm:ss' ON UPDATE CURRENT_TIMESTAMP:创建时使用固定值'yyyy-mm-dd hh:mm:ss',每次更新数据主动刷新该字段。
从上述几种使用方式知道,可以用TIMESTAMP字段自动标注出insert或update操作的日期和时间。需要注意到是,当表中有多个TIMEPSTAMP字段时,只有第一个会自动更新,更新规则为:
- 列值没有明确地在一个INSERT或LOAD DATA INFILE语句中指定。
- 列值没有明确地在一个UPDATE语句中指定且另外一些的列改变值。
- 明确地设定TIMESTAMP列为NULL。
- 除第一个以外的其他TIMESTAMP列也可以设置到当前的日期和时间,只要将列设为NULL,或NOW()。
参考文档:
- http://down.chinaz.com/server/201111/1423_1.htm
- http://www.2cto.com/database/201108/101151.html
- http://www.2cto.com/database/201205/131759.html