选择合适的数据类型

在使用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. hystrix-turbine实现多服务监控

    原文地址:http://www.cnblogs.com/skyblog/p/5633757.html 1.   概述 Demo地址:http://git.oschina.net/zhou666/spr ...

  2. 知也atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerException  v2 q31无涯 - I

    atitit.解决struts2 SpringObjectFactory.getClassInstance NullPointerExceptionv2 q31 1. #--现象 java.lang. ...

  3. [转载]linux下svn命令使用大全

    原文地址:http://blog.chinaunix.net/uid-22150747-id-189264.html 最近经常使用svn进行代码管理,这些命令老是记不住,得经常上网查,终于找了一个li ...

  4. 141. Linked List Cycle【easy】

    141. Linked List Cycle[easy] Given a linked list, determine if it has a cycle in it. Follow up:Can y ...

  5. input子系统分析(转)

    转自:http://www.linuxidc.com/Linux/2011-09/43187.htm 作者:作者:YAOZHENGUO2006 Input子系统处理输入事务,任何输入设备的驱动程序都可 ...

  6. LeetCode459. Repeated Substring Pattern

    Description Given a non-empty string check if it can be constructed by taking a substring of it and ...

  7. c++标准库之容器

    C++最原始的容器之一是数组.数组的特点有: 1.大小固定 2.单独存在的数组建立在栈上,作为对象成员存在的数组建立在堆上还是栈上则要看作为宿主对象是被建立在堆上还是栈上.栈空间是有限的,所以如果数组 ...

  8. tcp/iP协议族——IP工作原理及实例具体解释(下)

     IP协议具体解释 上一篇文章文章主要介绍了IP服务的特点,IPv4头部结构IP分片.并用tcpdump抓取数据包,来观察IP数据报传送过程中IP的格式,以及分片的过程.本文主要介绍IP路由,IP ...

  9. SlidingMenu官方实例分析6——ResponsiveUIActivity

    ResponsiveUIActivity 这个类实现的是一个响应适UI设计重点是布局的设计: layout布局如下: layout-large-land布局如下: layout-xlarge布局如下: ...

  10. poj 2117(割点的应用)

    题目链接:http://poj.org/problem?id=2117 思路:题目的意思是要求对于给定的无向图,删除某个顶点后,求最大的连通分量数.显然我们只有删掉割点后,连通分支数才会增加,因此我们 ...