公司开发的应用,一般要兼容大多数主流数据库,postgres,mysql,sql server,sqlserver,由于postgres的免费,用的比较多,客户现场用mysql跟sql server较多,oracle太贵了,除非很大型的项目.个人非常喜欢postgres,功能非常强大,插件繁多,系统非常稳定,并发性能强.相比mysql,没有那么多的编码设置,乱码问题.实在清爽,我一般以postgres作初步测试,然后再转向其它数据库平台.
之前开发过一个自动建表库(包括权限表/采样表/统计表),能够根据不同的数据库配置,自动生成相应的数据表.各个平台都比较正常,可是一到mysql上总是会报错:
一. Specified key was too long; max key length is 767
建表SQL:
CREATE TABLE (
TAG VARCHAR(320) NOT NULL,
DATE1 DATE,
ZIP SMALLINT,
DATA BLOB,
PRIMARY KEY(TAG,DATE1)
);
从错误描述来看,键长度过大>767,导致建表失败.查看下数据库编码都是UTF-8.难道与编码有关系吗?
谷歌发现上述的键指的是主键,也就是主键长度过长,LATIN1单个字符长度为1个字节,GBK为2个字节,UTF8为3个字节.此时长度为:3*(320+3)>767
方法一:减小TAG长度,设置为:246 (765/3-9)
方法二:强制指定表编码为LATIN1
LATIN1单字节编码,键长度320+3<767
CREATE TABLE (
TAG VARCHAR(320) NOT NULL,
DATE1 DATE,
ZIP SMALLINT,
DATA BLOB,
PRIMARY KEY(TAG,DATE1)
) ENGINE=InnoDB DEFAULT CHARSET=LATIN1;
既然是单字节编码,那距中文乱码的噩梦就不远了,幸好没有中文数据
方法三: 指定MyISAM
MyISAM可以容纳更大的主键长度为1000
CREATE TABLE (
TAG VARCHAR(320) NOT NULL,
DATE1 DATE,
ZIP SMALLINT,
DATA BLOB,
PRIMARY KEY(TAG,DATE1)
) ENGINE=MyISAM;
如果用了MyISAM引擎,就无法使用事务了,这对于大批量数据的INSERT,也是不可忍受的问题
二. mysql中文乱码
如果你经常用到mysql,数据库有中文数据,那么一定遇到过中文乱码的问题. mysql的编码太过复杂,可以设置数据库,表,表字段,客户端,服务器的编码.明明很简单的问题,搞的太复杂,像postgres就没这问题出现
1.客户端与服务器编码不一致
大多数是这种情况,这种情况还是好的,因为此时从服务器端过来数据是正常的,只是在客户端显示出现了问题
我们经常会看到有人查询时喜欢先执行: set names gbk; 然后查询中文数据,数据真的不乱码了.该语句是设置客户端编码为GBK,可是只对当前控制台有效,控制台重新打开后,又乱码了
可以通过编辑/etc/my.cnf使之永远有效:
[client]
default-character-set=utf8
重启mysql,乱码不见了
2.客户端编码与服务器数据库编码不一致
测试过程中,发现进程INSERT到数据库的中文都是乱码,直接打开mysql客户端手动执行INSERT竟然也是乱码,明显不认UTF8编码.查看编码方式发现mysql的sqlscada数据库为LATIN1编码,果断改成UTF8
alter database sqlscada character set utf8;
手动INSERT发现中文正常
3.总结
因为工作环境,经常要用到java和C++,java的字符串为UTF-8编码,为了使得各个语言上更好的工作,将数据库所有的编码设置为UTF-8
编辑/etc/my.cnf
[client]
default-character-set=utf8
[mysqld]
character-set-server=utf8
default-character-set=utf8
重启mysql,查看编码:
>show variables like 'character%';
+--------------------------+----------------------------+
| Variable_name | Value |
+--------------------------+----------------------------+
| character_set_client | utf8 |
| character_set_connection | utf8 |
| character_set_database | utf8 |
| character_set_filesystem | binary |
| character_set_results | utf8 |
| character_set_server | utf8 |
| character_set_system | utf8 |
| character_sets_dir | /usr/share/mysql/charsets/ |
+--------------------------+----------------------------+
自此再也没见mysql中文乱码
三. mysql blob大小
采样服务在postgres上工作一直很正常,突然将数据库迁移到mysql,发现blob数据总是被损坏,无法正常解压. 查看发现该blob大小很有特点为65535(0xFF)接近65K,blob数据大小为235k,难道被截断,查看mysql官方文档
原来mysql下有四种blob类型:
类型 大小(单位:字节)
TinyBlob 最大 255
Blob 最大 65K
MediumBlob 最大 16M
LongBlob 最大 4G
这mysql到处都是坑啊,postgres就一个bytea(变长字节序列)搞定一切二进制数据.更换成MediumBlob,问题解决
相关推荐
今天在为数据库中的某两个字段设置unique索引的时候,出现了Specified key was too long; max key length is 1000 bytes错误
本文将详细提供mysql建库时提示Specified key was too long max key length is 1000 bytes的问题的解决方法,有需求的朋友可以参考
nacos-server-1.1.4 windows下的运行程序 springcloud alibaba
ALTER TABLE table1 ALTER COLUMN ... 您可能感兴趣的文章:sql server建库、建表、建约束技巧mysql建库时提示Specified key was too long max key length is 1000 bytes的问题的解决方法Mysql 建库建表技巧分享SQL S
Illuminate\Database\QueryException : SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was too long; max key length is 767 bytes (SQL: alter table `users` add unique `users_email_...
导致报 Specified key was too long; max key length is 767 bytes 解决方案1: 直接缩短到255长度 解决方案2: 修改数据库配置, set innodb_large_prefix=on 吐槽一下, 1.2.0版本比1.1.4版本多创建一...
String Keys are UTF8 encoded and limited to 60 bytes if not specified otherwise (maximum is 255 chars). Support for long string Keys with the RaptorDBString class. Duplicate keys are stored as a WAH ...
max_input_time ; Default Value: -1 (Unlimited) ; Development Value: 60 (60 seconds) ; Production Value: 60 (60 seconds) ; output_buffering ; Default Value: Off ; Development Value: 4096 ; Production...
- When x86-64 support is compiled in, you could enable/disable long mode 1G pages support without recompile using new CPUID option in .bochsrc. Configure options: --enable-mmx, --enable-sse, --...