文章目录
一、字段类型和编码
1.1、mysql返回字符串长度:
CHARACTER_LENGTH 方法 ( CHAR_LENGTH 一样的) 返回的是字符数,LENGTH函数返回的是字节数,一个汉字三个字节
1.2、索引长度:
varchar 等字段建立索引长度计算语句:
select count(distinct left(test,5))/count(*) from table;
结果越趋近1越好
1.3、字符集设置
mysql 的 utf8 最大是 3 个字节不支持 emoji 表情符号,必须只用 utf8mb4 。需要在 mysql 配置文件中配置客户端字符集为 utf8mb4 。
jdbc 的连接串不支持配置 characterEncoding=utf8mb4 ,最好的办法是在连接池中指定初始化 sql ,例如:hikari 连接池,其他连接池类似 spring.datasource.hikari.connection-init-sql=set names utf8mb4。否则需要每次执行sql前都先执行set names utf8mb4。
1.4、msyql排序规则(一般使用_bin和_genera_ci)
- utf8_genera_ci 不区分大小写,ci为case insensitive的缩写,即大小写不敏感,
- utf8_general_cs区分大小写,cs为case sensitive的缩写,即大小写敏感,但是目前MySQL版本中已经不支持类似于***_genera_cs的排序规则,直接使用utf8_bin替代。
- utf8_bin将字符串中的每一个字符用二进制数据存储,区分大小写。
那么,同样是区分大小写,utf8_general_cs和utf8_bin有什么区别?
- cs为case sensitive的缩写,即大小写敏感;bin的意思是二进制,也就是二进制编码比较。
- utf8_general_cs排序规则下,即便是区分了大小写,但是某些西欧的字符和拉丁字符是不区分的,比如ä=a,但是有时并不需要ä=a,所以才有utf8_bin
- utf8_bin的特点在于使用字符的二进制的编码进行运算,任何不同的二进制编码都是不同的,因此在utf8_bin排序规则下:ä<>a
1.5 列类型选择原则
1.5.1 列选择原则:
- 字段类型优先级 整型 > date,time > char,varchar > blob
- 够用就行,不要慷慨 (如smallint,varchar(N))
- 尽量避免用NULL()
1.5.2 关于null的测试
以10万行左右的表做试验,(可以用企业库里的dict表),顺序如下:
建dictnn表, 不允许为null;建dictyn表, 允许为null
alter table 表名 disable keys; #禁用2表的key
insert into dictnn select id,if(id%2,word,'') from dict;
insert into dictyn select id,if(id%2,word,null) from dict;
alter table 表名 enable keys; #启用2表的key
观察磁盘文件大小
1.5.3 text/blob使用磁盘临时表的测试
text,blob列 :选择这些列时,将不能使用内存临时表,必须要把临时表写到磁盘上,速度慢
1.5.4 enum列
enum列在内部是用整型存储的,存取有一个转换过程
思考enum/varchar的相比的优势。实验:用1万条左右的数据做实验
1.5.5 主键的选择
主键用来区分,查找,和关联数据,非常重要.
1.在myisam中,字符串索引会被压缩,用字符串做主键性能不如整型
2. 用递增的值,不要用离散的值,离散值会导致文件在磁盘的位置有间隔,浪费空间且不易连续读取
3. UUID,也是逐步增长的,可以去掉"-",转换为整数
1.5.6 反范式的目的–减少表的关联查询
常用办法:冗余字段和冗余表
- 冗余字段: 表中某字段存储另一表的统计信息,如discuz中threads表 (打开该表)
- 冗余表: 表中统计或汇总其他表的信息,又称汇总表,如discuz中的pre_common_onlinetime(打开该表)
本质
1:空间换时间
2:大任务分成小任务,分散执行
SET [GLOBAL | SESSION] TRANSACTION ISOLATION LEVEL
{ READ UNCOMMITTED | READ COMMITTED | REPEATABLE READ | SERIALIZABLE }