选择合适的数据类型

在使用MySQL创建数据表的时候会遇到一个问题,如何为字段选择合适的数据类型.比如创建一个员工信息表,每个字段都可以用很多种类型来定义,

int,char,float等等.

char和varchar

char和varchar都是用来存储字符串类型的数据,但是他们保存和检索的方式不一样.char属于固定长度的字符类型,二varchar属于可变成的字符类型

值  char(4) 存储需求 varchar(4) 存储需求
'' '   ' 4个字节 ''  1个字节
'ab' 'ab ' 4个字节 'ab' 3个字节
'abcd' 'abcd' 4个字节 'abcd' 5个字节
'abcdefg' 'abcd' 4个字节 'abcd' 5个字节

由于char是固定长度的,所以它的处理速度比varchar快得多,但是其缺点是浪费存储空间,程序需要对尾行空格进行处理,所以对那些变化不打并且查询速度有较高的要求的数据可以考虑使用char类型来存储

  在mysql中,不同的存储引擎对char和varchar的使用原则有所不同

  • MyISAM存储引擎

    • 建议使用固定长度的数列代替可变长度的数据列
  • InnoDB存储引擎
    • 建议使用varchar类型,对于InnnoDB数据表,内部的行存储格式没有区分固定长度和可变长度,因此使用char列不一定比可变长度的varchar性能好
    • 由于char平均占用空间多余varchar,因此varchar来UI消化需要处理的数据航的存储总量和磁盘I/O是比较好的.

TEXT和BLOB

介绍

在选择大文本的时候我们会优先选择text类型或者blob比如文章.

那么TEXT和BLOB最主要的区别是 BLOB能用来保存二进制数据比如照片.而text智能保存字符串数据,比如文章和日记.

根据存储的文本长度不同和存储的字节不同我们可以使用

MEDIUMTEXT,LONGTEXT和MUDIUMBLOB,LONGBLOB

常见问题

空洞问题

BLOB和text在执行了大量的删除操作时,会留下很大的'空洞',以后填入这些'空洞'的记录在插入的性能上回有影响.为了提高性能,建议使用OPTIMIZE TABLE功能对类表进行碎片整理,

避免空洞带来的性能问题

空洞例子:

CREATE TABLE t (
id VARCHAR(100),
context TEXT
);
INSERT INTO t VALUES(1,repeat('haha',100));
INSERT INTO t VALUES(2,repeat('haha',100));
INSERT INTO t VALUES(3,repeat('haha',100));
insert into t select * from t;
insert into t select * from t;
.....
insert into t select * from t;

这时候文件的大小为:

删除id=1的数据,那么就是删除了1/3的数据:

mysql> delete from t where id=1;
Query OK, 32768 rows affected (0.63 sec)

再看文件大小,我们可以看到文件大小还是96MB,这就形成了空洞.

我们用OPTIMIZE进行优化:

mysql> optimize table t;

此时我们再看文件,已经变成了60MB,文件大大的缩小了,说明'空洞被收回了'

文件索引

使用合成索引来提高大文本字段的查询性能:

合成索引就是根据大文本的字段的内容建立一个散列值,并且把这个值存储在单独的数据列中,接下来可以通过检索散列值来找到数据.

但是,要注意这种技术只能用于精确匹配(对于< >=等范围搜索是没有用的)

可以使用MD5()函数来生成散列值.

下面介绍一下合成索引的方法:

CREATE TABLE t (
id VARCHAR(100),
context BLOB,
hash_value char(32)
);
INSERT INTO t VALUES(1,repeat('beijing',2),MD5(context)); INSERT INTO t VALUES(1,repeat('beijing2008',2),MD5(context)); mysql> select * from t where hash_value=md5(repeat('beijing2008',2));
+------+------------------------+----------------------------------+
| id | context | hash_value |
+------+------------------------+----------------------------------+
| 1 | beijing2008beijing2008 | 0fe88accc8741a9d1bc323bd286866bb |
+------+------------------------+----------------------------------+

由于这种技术只能用于精确匹配,从一定程度上减少了I/O,提高了查询效率.如果需要对BLOB字段进行模糊查询,MYsql提供了前缀索引,也就是只为字段的前n列创建索引

create index idx_blob on t(context(100));
mysql> desc select * from t where context like "beijing%" \G;
*************************** 1. row ***************************
id: 1
select_type: SIMPLE
table: t
type: range
possible_keys: idx_blob
key: idx_blob
key_len: 103
ref: NULL
rows: 2
Extra: Using where
1 row in set (0.04 sec)

对context的前100个字符进行模糊查询,就可以用前缀索引.

注意这里的%不能放在前面,否则不能命中索引

避免使用select *

不要用select * 检索大型的BLOB或者TEXT值

除非能够确定约束条件where只会找到需要的数据,否则很可能毫无目的在网络上传输大量的值.

用户可以用搜索索引列,决定需要的那些数据行,然后从符合条件的数据中检索BLOB或者TEXT

分表

水平分表,在某些环境中,如果把这些大型的列数据移动到第二章表数据中,那么把原数据表中的数据列转换成固定长度的数据行格式,

那么它就是有意义的.这会减少表中的碎片,可以得到固定长度的性能优势.

浮点数和定点数

在MYSQL中用float,double来标识浮点数.当一个字段被定义浮点类型后,如果插入的数据精度超过该列定义的实际精度,那么会采取四舍五入的办法来得到实际的值.

定点数不同于浮点数,他是用字符串的形式存存放的,所以插入的实际值精度大于实际定义的精度,如果在传统模式下,会直接报错,不能插入数据.

CREATE TABLE test(c1 float(10,2),c2 decimal(10,2));

INSERT INTO text VALUES(131072.32,131072.32);

mysql> select * from test;
+-----------+-----------+
| c1 | c2 |
+-----------+-----------+
| 131072.31 | 131072.32 |
+-----------+-----------+

可以看到c1列的值从131072.32 变成了131072.31,这是上面的数值在使用单精度浮点数表示时,产生了误差.

注意:

  • 浮点数存在误差问题
  • 对货币等对精度要求比较高的数据,应该用定点数表示或存储
  • 在变成中,如果用到浮点数,要特别注意误差问题,尽量避免做浮点数比较

日期类型的选择

  • 根据实际需要选择能够满足的最小存储的日期类型,如果只需要记录年,那么用一个字节来存储的YEAR类型就而已满足.而不需要用4个字节的date,不仅节省空间,还提高查询效率
  • 如果要记录年月日时分秒,并记录比较久远,那么最好使用datetime,不要使用timestamp
  • 如果记录的日期需要不同的时区的用户使用,那么最好使用timestamp,因为日期类型中,只有他能够和实际时区相对应

mysql设计表结构数据类型的选择的更多相关文章

  1. navicat如何导出mysql数据表结构

    我们在创建数据库时会对字段进行设置,比如类型.长度等,如果字段多的话一个个设置非常麻烦,可以从其他地方已有的表导入数据表结构,怎么操作呢?我们拿navicat导出mysql数据表结构为例: 1.点击“ ...

  2. 用户中心mysql数据库表结构的脚本

    /* Navicat MySQL Data Transfer Source Server : rm-m5e3xn7k26i026e75o.mysql.rds.aliyuncs.com Source S ...

  3. mysql数据库表结构导出

    mysql数据库表结构导出 命令行下具体用法如下: mysqldump -u用戶名 -p密码 -d 数据库名 表名 > 脚本名; 导出整个数据库结构和数据 mysqldump -h localh ...

  4. mysql对比表结构对比同步,sqlyog架构同步工具

    mysql对比表结构对比同步,sqlyog架构同步工具 对比后的结果示例: 执行后的结果示例: 点击:"另存为(S)" 按钮可以把更新sql导出来.

  5. MySQL复制表结构表数据

    MySQL复制表结构 表数据 1.复制表结构及数据到新表CREATE TABLE 新表 SELECT * FROM 旧表这种方法会将oldtable中所有的内容都拷贝过来,当然我们可以用delete ...

  6. MySQL 查看表结构

    mysql查看表结构命令,如下: desc 表名; show columns from 表名; describe 表名; show create table 表名; use information_s ...

  7. mysql查看表结构命令

    mysql查看表结构命令 mysql查看表结构命令,如下: desc 表名;show columns from 表名;describe 表名;show create table 表名; use inf ...

  8. Mysql 复制表结构 及其表的内容

    顺便转一下Mysql复制表结构.表数据的方法: 1.复制表结构及数据到新表CREATE TABLE 新表 SELECT * FROM 旧表 这种方法会将oldtable中所有的内容都拷贝过来,当然我们 ...

  9. mysql查看表结构,字段等命令

    mysql查看表结构命令,如下: desc 表名; show columns from 表名; describe 表名; show create table 表名;

随机推荐

  1. ping的原理以及ICMP

    ping 的原理:     ping 程序是用来探测主机到主机之间是否可通信,如果不能ping到某台主机,表明不能和这台主机建立连接.     ping 使用的是ICMP协议,它发送icmp回送请求消 ...

  2. java 图片缩放

    使用java自带的图片处理api,也可以使用(GraphicsMagick + im4j) import java.awt.Image; import java.awt.image.BufferedI ...

  3. Atitit.eclipse comment  template注释模板

    Atitit.eclipse comment  template注释模板 1. Code templet1 1.1. Settpath1 1.2. 设置存储1 1.3. 导出设置1 2. Java d ...

  4. [ci]持续集成系列

    持续集成一直很蛋疼,感觉没底. 几个方面来写 1,搭建gitlab 配邮箱 域名等使之好用 2,搭建jenkins –yum,安装常见插件 3,搭建sonar,汉化 4,安装sonar-scanner ...

  5. std::vector

    Vector Vectors are sequence containers representing arrays that can change in size. Just like arrays ...

  6. JavaScript 代码块

    JavaScript 语句通过代码块的形式进行组合. 块由左花括号开始,由右花括号结束. 块的作用是使语句序列一起执行. JavaScript 函数是将语句组合在块中的典型例子. 下面的例子将运行可操 ...

  7. java web 开发入门实例

    学习是个技巧活,关键是要找到重点的地方,新手在这方面的坑尤其多.看别人的教程一步一步的跟着做,隔几步就遇到一个新知识点,忍不住就百度往深处了解,一晃半天就过去了. 有的知识点要深入学习的,有的是了解下 ...

  8. Mysql事务-隔离级别

    MYSQL事务-隔离级别 事务是什么? 事务简言之就是一组SQL执行要么全部成功,要么全部失败.MYSQL的事务在存储引擎层实现. 事务都有ACID特性: 原子性(Atomicity):一个事务必须被 ...

  9. CI的意思

    Continuous integration (CI) is the practice, in software engineering, of merging all developer worki ...

  10. python数据分析之numpy

    知乎:https://zhuanlan.zhihu.com/p/26514493 numoy安装:http://blog.csdn.net/wyc12306/article/details/53705 ...