美文网首页
MySQL之路-1-SQL分类与数据类型

MySQL之路-1-SQL分类与数据类型

作者: 灭BUG | 来源:发表于2018-07-08 20:16 被阅读17次

    1. SQL分类

    SQL语句可以划分为以下4个类别:

    1.1 DDL(Data Definition Language)

    数据定义语句,用于定义数据库对象(包括:数据库、表、列、索引等),常用关键字有:createdropalter等。

    -- 创建数据库
    create database dbname;
    -- 删除数据库
    drop database dbname;
    -- 创建表
    create table tablename(...)
    -- 添加列
    alter table tablename column1 type;
    ...
    

    1.2 DQL(Data Query Language)

    数据查询语句,用于查询数据库记录,常用关键字有:select

    -- 查询某个表的所有记录
    select * from tablename;
    ...
    

    1.3 DML(Data Manipulation Language)

    数据操纵语句,用于添加、删除和更新数据库记录,并检查数据完整新,常用关键字有:insertdeleteupdate等。

    -- 插入数据
    insert into tablenamt value(...);
    -- 更新数据
    update tablename set column1 = value1;
    -- 删除数据
    delete tablename;
    ...
    

    1.4 DCL(Data Control Language)

    数据控制语句,用于授予或回收访问数据库的某种特权,并控制数据库操纵事务发生的时间及效果,对数据库实行监视等,常用关键字有:grantinvokedeny等。

    -- 在本地环境中授予某个用户对某个数据库中所有表的select/insert权限
    grant select,insert on dbname.* to 'username'@'localhost' indentified by 'password';
    

    2. MySQL数据类型

    MySQl数据类型基本分为三类:

    • 数值
    • 日期和时间
    • 字符串

    2.1 数值类型

    类型 字节数
    tinyint 1
    smallint 2
    mediumint 3
    int 4
    bigint 8
    float 4
    double 8
    decimal (m,d) 最大值范围与double相同,取值范围可由m,d值控制

    2.1.1 decimal和float、double的区别?

    float、double是非标准数据类型,在数据库中保存的是近似值,decimal是标准数据类型,在数据库中是以字符串的形式保存数值

    2.1.2 decimal中的m、d取值分别是什么含义?

    d是指小数部分的位数,m则是指整数+小数的总长度

    2.2 日期和时间类型

    类型 字节数 格式
    date 3 YYYY-MM-DD
    time 3 HH:MM:SS
    year 1 YYYY
    datetime 8 YYYY-MM-DD HH:MM:SS
    timestamp 4 YYYY-MM-DD HH:MM:SS

    2.2.1 datetime类型和timestamp类型的区别?

    • datetime类型是按照实际格式存储,与时区无关;timestamp类型是以UTC格式保存,存储时对当前的失去进行转换,检索时再转换回来当前的时区。
    • 范围不一样,datatime类型支持的范围更宽,timestamp类型可表示的范围为:1970-01-01 00:00:00~2038-01-09 03:14:07
    • timestamp可以通过CURRENT_TIMESTAMP() 获取。
    • 索引速度不同,timestamp更轻量,索引相对datetime更快。

    注:实际使用中,我们再建表的时候通常需要再表中添加createTime和updateTime这两个字段,可以参考下面的例子来写

    `create_time` datetime NOT NULL DEFAULT '0000-00-00 00:00:00' COMMENT '创建时间',
    `update_time` timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP COMMENT '更新时间',
    

    2.3 字符串类型

    类型 范围 备注
    char 0~255字节
    varchar 0~65535字节
    tinyblob 0~255字节 不超过255个字符的二进制字符串
    tinytext 0~255字节
    blob 0~65535字节
    text 0~65535字节
    mediumblob 0~16777215字节
    mediumtext 0~16777215字节
    longblob 0~4294967295字节 二进制形式的极大文本数据
    longtext 0~4294967295字节 极大文本数据

    2.3.1 char类型和varchar类型的区别?

    char和varchar类型类似,但它们保存和检索的方式不同。它们的最大长度和是否尾部空格被保留等方面也不同。在存储或检索过程中不进行大小写转换。char(8)填了4个字符,会补上4个空格,varchar(8)则不会。

    3. 选择合适的数据类型

    3.1 char与varchar的选择

    char和varchar都可以用来存储字符串,但是它们的保存和检索方式不一样。char是定长类型,而varchar是可变长类型。由于char是定长的,所以char处理速度比varchar快得多,但是浪费存储空间,适合长度变化不大并对查询速度有较高要求的数据。

    注:随着MySQL版本的提升,varchar类型的性能也在不断提高,所以在实际应用中,反而是varchar被更多地使用。

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

    • MyISAM 存储引擎:建议使用固定长度的数据列代替可变长度的数据列
    • MEMORY 存储引擎:目前都使用固定长度的数据行存储,因此无论使用 CHAR 或
      VARCHAR 列都没有关系。两者都是作为 CHAR 类型处理
    • InnoDB 存储引擎:建议使用 VARCHAR 类型。

    注:对于使用InnoDB的表,内部的行存储格式没有区分定长和可变长,因此在本质上,使用定长度的CHAR 列不一定比使用可变长度 VARCHAR 列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于 CHAR 平均占用的空间多于 VARCHAR,因此使用 VARCHAR 来最小化需要处理的数据行的存储总量和磁盘 I/O 是比较好的。

    3.2 text和blob的选择

    存储大文本的时候,通常会选取text或者blob类型,两种类型的主要差别是blob是用来保存二进制数据的,text是用来保存字符串数据的。在实际使用中,应该根据实际情况,选取能够满足需求的最小存储类型。

    3.2.1 text和blob类型大批量删除数据的时候可能会存在的问题

    大批量删除数据后,会在数据库表存在大量的“空洞”,具体表现形式就是,删除数据后,对应表的占用的存储空间并没有变小。这时候可以通过optimize table命令对表进行碎片整理,避免因为“空洞”导致的性能问题。

    optimize table tablename;
    

    你可以通过show table status命名去判断数据库中的表是否需要使用optimize table命令

    show table status;
    
    image

    其中有两个参数是比较重要的,Data_length是代表整个表的数据量,Data_free是代表标识为已分配,但未使用的空间,并且包含了已被删除行的空间。

    • MySQL官方建议每周或者每个月整理一次即可
    • optimize table命令只对MyISAM,InnoDB起作用,其中对MyISAM作用最为明显
    • optimize table命令运行过程中会进行锁表操作
    • InnoDB执行optimize table命令的时候可能会提示Table does not support optimize, doing recreate + analyze instead,可以通过mysqld --skip-new或者mysqld –-safe-mode命令重启MySQL解决问题

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

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

    3.2.3 在不必要的时候避免检索大文本字段

    select * 查询就不是很好的想法,除非能够确定作为约束条件的 WHERE 子句只会找到所需要的数据行。否则,很可能毫无目的地在网络上传输大量的值。这也是 BLOB 或 TEXT标识符信息存储在合成的索引列中对用户有所帮助的例子。用户可以搜索索引列,决定需要的哪些数据行,然后从符合条件的数据行中检索 BLOB 或 TEXT 值。

    3.2.4 将大文本字段分离在单独的表中

    在某些环境中,如果把这些数据列移动到第二张数据表中,可以把原数据表中的数据列转换为固定长度的数据行格式,那么它就是有意义的。这会减少主表中的碎片,可以得到固定长度数据行的性能优势。它还可以使主数据表在运行 SELECT * 查询的时候不会通过网络传输大量的 BLOB 或 TEXT 值

    3.3 浮点数和定点数的选择

    在MySQL中可以使用floatdouble类型表示浮点数,当数据精度超出字段的实际精度,插入值则会被四舍五入。定点数decimal不同于浮点数,定点数是以字符串形式存放的,更加精准,当数据精度大于字段的实际精度,MySQL会告警。

    注:对于货币之类对精度敏感的数据,应该使用定点数存储

    3.4 日期类型选择

    MySQL提供常用的日期类型有:datetimedatetimetimestamp,选择日期类型一般需要遵循下面原则:

    • 根据实际需要,选择能够满足应用的最小存储的日期类型
    • 如果需要记录时分秒,并且记录的年份比较久远,尽量使用datetime
    • 如果记录的日期需要让不同时区的用户使用,最好选择timestamp

    相关文章

      网友评论

          本文标题:MySQL之路-1-SQL分类与数据类型

          本文链接:https://www.haomeiwen.com/subject/etxauftx.html