精华内容
下载资源
问答
  • 类型
    万次阅读
    2021-01-19 06:25:45

    MySQL 的数值数据类型可以大致划分为两个类别,一个是整数,另一个是浮点数或小数。许多不同的子类型对这些类别中的每一个都是可用的,每个子类型支持不同大小的数据,并且 MySQL 允许我们指定数值字段中的值是否有正负之分或者用零填补。

    表列出了各种数值类型以及它们的允许范围和占用的内存空间。

    类型                  大小    范围(有符号)                                                                   范围(无符号)                                用途

    TINYINT           1 字节 (-128,127)                                                                      (0,255)                                     小整数值

    SMALLINT        2 字节 (-32 768,32 767)                                                             (0,65 535)                                 大整数值

    MEDIUMINT      3 字节 (-8 388 608,8 388 607)                                                    (0,16 777 215)                          大整数值

    INT或INTEGER  4 字节 (-2 147 483 648,2 147 483 647)                                       (0,4 294 967 295)                      大整数值

    BIGINT            8 字节 (-9 233 372 036 854 775 808,9 223 372 036 854 775 807) (0,18 446 744 073 709 551 615) 极大整数值

    FLOAT             4 字节 (-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38) 0,(1.175494351 E-38,3.402 823 466 E+38) 单精度浮点数值

    DOUBLE           8 字节 (1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308) 双精度浮点数值

    DECIMAL 对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2 依赖于M和D的值 依赖于M和D的值 小数值

    INT 类型

    在 MySQL 中支持的 5 个主要整数类型是 TINYINT,SMALLINT,MEDIUMINT,INT 和 BIGINT。这些类型在很大程度上是相同的,只有它们存储的值的大小是不相同的。

    MySQL 以一个可选的显示宽度指示器的形式对 SQL 标准进行扩展,这样当从数据库检索一个值时,可以把这个值加长到指定的长度。例如,指定一个字段的类型为 INT(6),就可以保证所包含数字少于 6 个的值从数据库中检索出来时能够自动地用空格填充。需要注意的是,使用一个宽度指示器不会影响字段的大小和它可以存储的值的范围。

    万一我们需要对一个字段存储一个超出许可范围的数字,MySQL 会根据允许范围最接近它的一端截短后再进行存储。还有一个比较特别的地方是,MySQL 会在不合规定的值插入表前自动修改为 0。

    UNSIGNED 修饰符规定字段只保存正值。因为不需要保存数字的正、负符号,可以在储时节约一个“位”的空间。从而增大这个字段可以存储的值的范围。

    ZEROFILL 修饰符规定 0(不是空格)可以用来真补输出的值。使用这个修饰符可以阻止 MySQL 数据库存储负值。

    FLOAT、DOUBLE 和 DECIMAL 类型

    MySQL 支持的三个浮点类型是 FLOAT、DOUBLE 和 DECIMAL 类型。FLOAT 数值类型用于表示单精度浮点数值,而 DOUBLE 数值类型用于表示双精度浮点数值。

    与整数一样,这些类型也带有附加参数:一个显示宽度指示器和一个小数点指示器。比如语句 FLOAT(7,3) 规定显示的值不会超过 7 位数字,小数点后面带有 3 位数字。

    对于小数点后面的位数超过允许范围的值,MySQL 会自动将它四舍五入为最接近它的值,再插入它。

    DECIMAL 数据类型用于精度要求非常高的计算中,这种类型允许指定数值的精度和计数方法作为选择参数。精度在这里指为这个值保存的有效数字的总个数,而计数方法表示小数点后数字的位数。比如语句 DECIMAL(7,3) 规定了存储的值不会超过 7 位数字,并且小数点后不超过 3 位。

    忽略 DECIMAL 数据类型的精度和计数方法修饰符将会使 MySQL 数据库把所有标识为这个数据类型的字段精度设置为 10,计算方法设置为 0。

    UNSIGNED 和 ZEROFILL 修饰符也可以被 FLOAT、DOUBLE 和 DECIMAL 数据类型使用。并且效果与 INT 数据类型相同。

    字符串类型

    MySQL 提供了 8 个基本的字符串类型,可以存储的范围从简单的一个字符到巨大的文本块或二进制字符串数据。

    类型 大小 用途

    CHAR 0-255字节 定长字符串

    VARCHAR 0-255字节 变长字符串

    TINYBLOB 0-255字节 不超过 255 个字符的二进制字符串

    TINYTEXT 0-255字节 短文本字符串

    BLOB 0-65 535字节 二进制形式的长文本数据

    TEXT 0-65 535字节 长文本数据

    MEDIUMBLOB 0-16 777 215字节 二进制形式的中等长度文本数据

    MEDIUMTEXT 0-16 777 215字节 中等长度文本数据

    LOGNGBLOB 0-4 294 967 295字节 二进制形式的极大文本数据

    LONGTEXT 0-4 294 967 295字节 极大文本数据

    CHAR 和 VARCHAR 类型

    CHAR 类型用于定长字符串,并且必须在圆括号内用一个大小修饰符来定义。这个大小修饰符的范围从 0-255。比指定长度大的值将被截短,而比指定长度小的值将会用空格作填补。

    CHAR 类型可以使用 BINARY 修饰符。当用于比较运算时,这个修饰符使 CHAR 以二进制方式参于运算,而不是以传统的区分大小写的方式。

    CHAR 类型的一个变体是 VARCHAR 类型。它是一种可变长度的字符串类型,并且也必须带有一个范围在 0-255 之间的指示器。CHAR 和 VARCHGAR 不同之处在于 MuSQL 数据库处理这个指示器的方式:CHAR 把这个大小视为值的大小,不长度不足的情况下就用空格补足。而 VARCHAR 类型把它视为最大值并且只使用存储字符串实际需要的长度(增加一个额外字节来存储字符串本身的长度)来存储值。所以短于指示器长度的 VARCHAR 类型不会被空格填补,但长于指示器的值仍然会被截短。

    因为 VARCHAR 类型可以根据实际内容动态改变存储值的长度,所以在不能确定字段需要多少字符时使用 VARCHAR 类型可以大大地节约磁盘空间、提高存储效率。

    VARCHAR 类型在使用 BINARY 修饰符时与 CHAR 类型完全相同。

    TEXT 和 BLOB 类型

    对于字段长度要求超过 255 个的情况下,MySQL 提供了 TEXT 和 BLOB 两种类型。根据存储数据的大小,它们都有不同的子类型。这些大型的数据用于存储文本块或图像、声音文件等二进制数据类型。

    TEXT 和 BLOB 类型在分类和比较上存在区别。BLOB 类型区分大小写,而 TEXT 不区分大小写。大小修饰符不用于各种 BLOB 和 TEXT 子类型。比指定类型支持的最大范围大的值将被自动截短。

    日期和时间类型

    在处理日期和时间类型的值时,MySQL 带有 5 个不同的数据类型可供选择。它们可以被分成简单的日期、时间类型,和混合日期、时间类型。根据要求的精度,子类型在每个分类型中都可以使用,并且 MySQL 带有内置功能可以把多样化的输入格式变为一个标准格式。

    类型 大小

    (字节) 范围 格式 用途

    DATE 3 1000-01-01/9999-12-31 YYYY-MM-DD 日期值

    TIME 3 '-838:59:59'/'838:59:59' HH:MM:SS 时间值或持续时间

    YEAR 1 1901/2155 YYYY 年份值

    DATETIME 8 1000-01-01 00:00:00/9999-12-31 23:59:59 YYYY-MM-DD HH:MM:SS 混合日期和时间值

    TIMESTAMP 8 1970-01-01 00:00:00/2037 年某时 YYYYMMDD HHMMSS 混合日期和时间值,时间戳

    DATE、TIME 和 TEAR 类型

    MySQL 用 DATE 和 TEAR 类型存储简单的日期值,使用 TIME 类型存储时间值。这些类型可以描述为字符串或不带分隔符的整数序列。如果描述为字符串,DATE 类型的值应该使用连字号作为分隔符分开,而 TIME 类型的值应该使用冒号作为分隔符分开。

    需要注意的是,没有冒号分隔符的 TIME 类型值,将会被 MySQL 理解为持续的时间,而不是时间戳。

    MySQL 还对日期的年份中的两个数字的值,或是 SQL 语句中为 TEAR 类型输入的两个数字进行最大限度的通译。因为所有 TEAR 类型的值必须用 4 个数字存储。MySQL 试图将 2 个数字的年份转换为 4 个数字的值。把在 00-69 范围内的值转换到 2000-2069 范围内。把 70-99 范围内的值转换到 1970-1979 之内。如果 MySQL 自动转换后的值并不符合我们的需要,请输入 4 个数字表示的年份。

    DATEYIME 和 TIMESTAMP 类型

    除了日期和时间数据类型,MySQL 还支持 DATEYIME 和 TIMESTAMP 这两种混合类型。它们可以把日期和时间作为单个的值进行存储。这两种类型通常用于自动存储包含当前日期和时间的时间戳,并可在需要执行大量数据库事务和需要建立一个调试和审查用途的审计跟踪的应用程序中发挥良好作用。

    如果我们对 TIMESTAMP 类型的字段没有明确赋值,或是被赋与了 null 值。MySQL 会自动使用系统当前的日期和时间来填充它。

    复合类型

    MySQL 还支持两种复合数据类型 ENUM 和 SET,它们扩展了 SQL 规范。虽然这些类型在技术上是字符串类型,但是可以被视为不同的数据类型。一个 ENUM 类型只允许从一个集合中取得一个值;而 SET 类型允许从一个集合中取得任意多个值。

    ENUM 类型

    ENUM 类型因为只允许在集合中取得一个值,有点类似于单选项。在处理相互排拆的数据时容易让人理解,比如人类的性别。ENUM 类型字段可以从集合中取得一个值或使用 null 值,除此之外的输入将会使 MySQL 在这个字段中插入一个空字符串。另外如果插入值的大小写与集合中值的大小写不匹配,MySQL 会自动使用插入值的大小写转换成与集合中大小写一致的值。

    ENUM 类型在系统内部可以存储为数字,并且从 1 开始用数字做索引。一个 ENUM 类型最多可以包含 65536 个元素,其中一个元素被 MySQL 保留,用来存储错误信息,这个错误值用索引 0 或者一个空字符串表示。

    MySQL 认为 ENUM 类型集合中出现的值是合法输入,除此之外其它任何输入都将失败。这说明通过搜索包含空字符串或对应数字索引为 0 的行就可以很容易地找到错误记录的位置。

    SET 类型

    SET 类型与 ENUM 类型相似但不相同。SET 类型可以从预定义的集合中取得任意数量的值。并且与 ENUM 类型相同的是任何试图在 SET 类型字段中插入非预定义的值都会使 MySQL 插入一个空字符串。如果插入一个即有合法的元素又有非法的元素的记录,MySQL 将会保留合法的元素,除去非法的元素。

    一个 SET 类型最多可以包含 64 项元素。在 SET 元素中值被存储为一个分离的“位”序列,这些“位”表示与它相对应的元素。“位”是创建有序元素集合的一种简单而有效的方式。并且它还去除了重复的元素,所以 SET 类型中不可能包含两个相同的元素。

    希望从 SET 类型字段中找出非法的记录只需查找包含空字符串或二进制值为 0 的行。

    更多相关内容
  • 面试官:兄弟,说说基本类型和包装类型的区别吧

    万次阅读 多人点赞 2019-09-29 08:36:07
    Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点。

    六年前,我从苏州回到洛阳,抱着一幅“海归”的心态,投了不少简历,也“约谈”了不少面试官,但仅有两三个令我感到满意。其中有一位叫老马,至今还活在我的手机通讯录里。他当时扔了一个面试题把我砸懵了:说说基本类型和包装类型的区别吧。

    我当时二十三岁,正值青春年华,从事 Java 编程已有 N 年经验(N < 4),自认为所有的面试题都能对答如流,结果没想到啊,被“刁难”了——原来洛阳这块互联网的荒漠也有技术专家啊。现在回想起来,脸上不自觉地泛起了羞愧的红晕:主要是自己当时太菜了。不管怎么说,是时候写篇文章剖析一下基本类型和包装类型的区别了。

    Java 的每个基本类型都对应了一个包装类型,比如说 int 的包装类型为 Integer,double 的包装类型为 Double。基本类型和包装类型的区别主要有以下 4 点。

    01、包装类型可以为 null,而基本类型不可以

    别小看这一点区别,它使得包装类型可以应用于 POJO 中,而基本类型则不行。

    POJO 是什么呢?这里稍微说明一下。

    POJO 的英文全称是 Plain Ordinary Java Object,翻译一下就是,简单无规则的 Java 对象,只有属性字段以及 setter 和 getter 方法,示例如下。

    class Writer {
    	private Integer age;
    	private String name;
    
    	public Integer getAge() {
    		return age;
    	}
    
    	public void setAge(Integer age) {
    		this.age = age;
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    }
    

    和 POJO 类似的,还有数据传输对象 DTO(Data Transfer Object,泛指用于展示层与服务层之间的数据传输对象)、视图对象 VO(View Object,把某个页面的数据封装起来)、持久化对象 PO(Persistant Object,可以看成是与数据库中的表映射的 Java 对象)。

    那为什么 POJO 的属性必须要用包装类型呢?

    《阿里巴巴 Java 开发手册》上有详细的说明,我们来大声朗读一下(预备,起)。

    数据库的查询结果可能是 null,如果使用基本类型的话,因为要自动拆箱(将包装类型转为基本类型,比如说把 Integer 对象转换成 int 值),就会抛出 NullPointerException 的异常。

    02、包装类型可用于泛型,而基本类型不可以

    泛型不能使用基本类型,因为使用基本类型时会编译出错。

    List<int> list = new ArrayList<>(); // 提示 Syntax error, insert "Dimensions" to complete ReferenceType
    List<Integer> list = new ArrayList<>();
    

    为什么呢?因为泛型在编译时会进行类型擦除,最后只保留原始类型,而原始类型只能是 Object 类及其子类——基本类型是个特例。

    03、基本类型比包装类型更高效

    基本类型在栈中直接存储的具体数值,而包装类型则存储的是堆中的引用。

    很显然,相比较于基本类型而言,包装类型需要占用更多的内存空间。假如没有基本类型的话,对于数值这类经常使用到的数据来说,每次都要通过 new 一个包装类型就显得非常笨重。

    03、两个包装类型的值可以相同,但却不相等

    两个包装类型的值可以相同,但却不相等——这句话怎么理解呢?来看一段代码就明明白白了。

    Integer chenmo = new Integer(10);
    Integer wanger = new Integer(10);
    
    System.out.println(chenmo == wanger); // false
    System.out.println(chenmo.equals(wanger )); // true
    

    两个包装类型在使用“”进行判断的时候,判断的是其指向的地址是否相等。chenmo 和 wanger 两个变量使用了 new 关键字,导致它们在“”的时候输出了 false。

    chenmo.equals(wanger) 的输出结果为 true,是因为 equals 方法内部比较的是两个 int 值是否相等。源码如下。

    private final int value;
    
    public int intValue() {
        return value;
    }
    public boolean equals(Object obj) {
        if (obj instanceof Integer) {
            return value == ((Integer)obj).intValue();
        }
        return false;
    }
    

    瞧,虽然 chenmo 和 wanger 的值都是 10,但他们并不相等。换句话说就是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符

    04、自动装箱和自动拆箱

    既然有了基本类型和包装类型,肯定有些时候要在它们之间进行转换。把基本类型转换成包装类型的过程叫做装箱(boxing)。反之,把包装类型转换成基本类型的过程叫做拆箱(unboxing)。

    在 Java SE5 之前,开发人员要手动进行装拆箱,比如说:

    Integer chenmo = new Integer(10);  // 手动装箱
    int wanger = chenmo.intValue();  // 手动拆箱
    

    Java SE5 为了减少开发人员的工作,提供了自动装箱与自动拆箱的功能。

    Integer chenmo  = 10;  // 自动装箱
    int wanger = chenmo;     // 自动拆箱
    

    上面这段代码使用 JAD 反编译后的结果如下所示:

    Integer chenmo = Integer.valueOf(10);
    int wanger = chenmo.intValue();
    

    也就是说,自动装箱是通过 Integer.valueOf() 完成的;自动拆箱是通过 Integer.intValue() 完成的。理解了原理之后,我们再来看一道老马当年给我出的面试题。

    // 1)基本类型和包装类型
    int a = 100;
    Integer b = 100;
    System.out.println(a == b);
    
    // 2)两个包装类型
    Integer c = 100;
    Integer d = 100;
    System.out.println(c == d);
    
    // 3)
    c = 200;
    d = 200;
    System.out.println(c == d);
    

    答案是什么呢?有举手要回答的吗?答对的奖励一朵小红花哦。

    第一段代码,基本类型和包装类型进行 == 比较,这时候 b 会自动拆箱,直接和 a 比较值,所以结果为 true。

    第二段代码,两个包装类型都被赋值为了 100,这时候会进行自动装箱,那 == 的结果会是什么呢?

    我们之前的结论是:将“==”操作符应用于包装类型比较的时候,其结果很可能会和预期的不符。那结果是 false?但这次的结果却是 true,是不是感觉很意外?

    第三段代码,两个包装类型重新被赋值为了 200,这时候仍然会进行自动装箱,那 == 的结果会是什么呢?

    吃了第二段代码的亏后,是不是有点怀疑人生了,这次结果是 true 还是 false 呢?扔个硬币吧,哈哈。我先告诉你结果吧,false。

    为什么?为什么?为什么呢?

    事情到了这一步,必须使出杀手锏了——分析源码吧。

    之前我们已经知道了,自动装箱是通过 Integer.valueOf() 完成的,那我们就来看看这个方法的源码吧。

    public static Integer valueOf(int i) {
        if (i >= IntegerCache.low && i <= IntegerCache.high)
            return IntegerCache.cache[i + (-IntegerCache.low)];
        return new Integer(i);
    }
    

    难不成是 IntegerCache 在作怪?你猜对了!

    private static class IntegerCache {
        static final int low = -128;
        static final int high;
        static final Integer cache[];
    
        static {
            // high value may be configured by property
            int h = 127;
            int i = parseInt(integerCacheHighPropValue);
            i = Math.max(i, 127);
            h = Math.min(i, Integer.MAX_VALUE - (-low) -1);
            high = h;
    
            cache = new Integer[(high - low) + 1];
            int j = low;
            for(int k = 0; k < cache.length; k++)
                cache[k] = new Integer(j++);
    
            // range [-128, 127] must be interned (JLS7 5.1.7)
            assert IntegerCache.high >= 127;
        }
    }
    

    大致瞟一下这段代码你就全明白了。-128 到 127 之间的数会从 IntegerCache 中取,然后比较,所以第二段代码(100 在这个范围之内)的结果是 true,而第三段代码(200 不在这个范围之内,所以 new 出来了两个 Integer 对象)的结果是 false。

    看完上面的分析之后,我希望大家记住一点:当需要进行自动装箱时,如果数字在 -128 至 127 之间时,会直接使用缓存中的对象,而不是重新创建一个对象

    自动装拆箱是一个很好的功能,大大节省了我们开发人员的精力,但也会引发一些麻烦,比如下面这段代码,性能就很差。

    long t1 = System.currentTimeMillis();
    Long sum = 0L;
    for (int i = 0; i < Integer.MAX_VALUE;i++) {
        sum += i;
    }
    long t2 = System.currentTimeMillis();        
    System.out.println(t2-t1);
    

    sum 由于被声明成了包装类型 Long 而不是基本类型 long,所以 sum += i 进行了大量的拆装箱操作(sum 先拆箱和 i 相加,然后再装箱赋值给 sum),导致这段代码运行完花费的时间足足有 2986 毫秒;如果把 sum 换成基本类型 long,时间就仅有 554 毫秒,完全不一个等量级啊。

    05、最后

    谢谢大家的阅读,原创不易,喜欢就点个赞,这将是我最强的写作动力。如果你觉得文章对你有所帮助,也蛮有趣的,就关注一下我的公众号,谢谢。

    展开全文
  • 详细介绍MySQL中的数据类型

    万次阅读 多人点赞 2022-04-12 21:46:07
    主要介绍了mysql中的数据类型,主要介绍整数类型,浮点类型,日期类型。开发中每个表都会存在主键和更新时间,这时候选择那个数据类型作为主键也是很重要的,如果选择的数据类型太大会浪费空间,如果选择小了会影响...

    MySQL数据类型精讲

    1.MySQL中的数据类型

    image-20220405111750005

    常见数据类型的属性,如下:

    image-20220405111820593

    2.整数类型

    2.1 类型介绍

    整数类型一共有 5 种,包括 TINYINT、SMALLINT、MEDIUMINT、INT(INTEGER)和 BIGINT

    image-20220405112024144

    2.2可选属性

    整数类型的可选属性有三个:

    2.2.1 M

    M : 表示显示宽度,M的取值范围是(0, 255)。例如,int(5):当数据宽度小于5位的时候在数字前面需要用字符填满宽度。该项功能需要配合“ ZEROFILL ”使用,表示用“0”填满宽度,否则指定显示宽度无效。

    如果设置了显示宽度,那么插入的数据宽度超过显示宽度限制,会不会截断或插入失败?

    答案:不会对插入的数据有任何影响,还是按照类型的实际宽度进行保存,即 显示宽度与类型可以存储的 值范围无关 。从MySQL 8.0.17开始,整数数据类型不推荐使用显示宽度属性。整型数据类型可以在定义表结构时指定所需要的显示宽度,如果不指定,则系统为每一种类型指定默认的宽度值。

    举例:

    CREATE TABLE test_int1 ( x TINYINT, y SMALLINT, z MEDIUMINT, m INT, n BIGINT );

    查看表结构 (MySQL5.7中显式如下,MySQL8中不再显式范围)

    image-20220405112808037

    TINYINT有符号数和无符号数的取值范围分别为-128127和0255,由于负号占了一个数字位,因此TINYINT默认的显示宽度为4。同理,其他整数类型的默认显示宽度与其有符号数的最小值的宽度相同。

    举例:

    CREATE TABLE test_int2(
    	f1 INT,
    	f2 INT(5),
    	f3 INT(5) ZEROFILL )
    DESC test_int2; 
    INSERT INTO test_int2(f1,f2,f3) 
    VALUES(1,123,123); 
    INSERT INTO test_int2(f1,f2) 
    VALUES(123456,123456); 
    INSERT INTO test_int2(f1,f2,f3) 
    VALUES(123456,123456,123456)
    

    image-20220405113043303

    2.2.2 UNSIGNED

    UNSIGNED : 无符号类型(非负),所有的整数类型都有一个可选的属性UNSIGNED(无符号属性),无符号整数类型的最小取值为0。所以,如果需要在MySQL数据库中保存非负整数值时,可以将整数类型设置为无符号类型。

    int类型默认显示宽度为int(11),无符号int类型默认显示宽度为int(10)。

    image-20220405113211366

    2.2.3 ZEROFILL

    ZEROFILL : 0填充,(如果某列是ZEROFILL,那么MySQL会自动为当前列添加UNSIGNED属性),如果指定了ZEROFILL只是表示不够M位时,用0在左边填充,如果超过M位,只要不超过数据存储范围即可。原来,在 int(M) 中,M 的值跟 int(M) 所占多少存储空间并无任何关系。 int(3)、int(4)、int(8) 在磁盘上都是占用 4 bytes 的存储空间。也就是说,int(M) ,必须和 UNSIGNED ZEROFILL **一起使用才有意义。**如果整数值超过M位,就按照实际位数存储。只是无须再用字符 0 进行填充。

    2.3使用场景

    • TINYINT :一般用于枚举数据,比如系统设定取值范围很小且固定的场景。
    • SMALLINT :可以用于较小范围的统计数据,比如统计工厂的固定资产库存数量等。
    • MEDIUMINT :用于较大整数的计算,比如车站每日的客流量等
    • INT、INTEGER :取值范围足够大,一般情况下不用考虑超限问题,用得最多。比如商品编号。
    • BIGINT :只有当你处理特别巨大的整数时才会用到。比如双十一的交易量、大型门户网站点击量、证券公司衍生产品持仓等

    2.4如何选择

    在评估用哪种整数类型的时候,你需要考虑 存储空间 和 可靠性 的平衡问题:一方 面,用占用字节数少的整数类型可以节省存储空间;另一方面,要是为了节省存储空间, 使用的整数类型取值范围太小,一旦遇到超出取值范围的情况,就可能引起 系统错误 ,影响可靠性。举个例子,商品编号采用的数据类型是 INT。原因就在于,客户门店中流通的商品种类较多,而且,每天都有旧商品下架,新商品上架,这样不断迭代,日积月累。如果使用 SMALLINT 类型,虽然占用字节数比 INT 类型的整数少,但是却不能保证数据不会超出范围65535。相反,使用 INT,就能确保有足够大的取值范围,不用担心数据超出范围影响可靠性的问题。你要注意的是,在实际工作中,系统故障产生的成本远远超过增加几个字段存储空间所产生的成本。因此,我建议你首先确保数据不会超过取值范围,在这个前提之下,再去考虑如何节省存储空间。

    3.浮点类型

    3.1类型介绍

    浮点数和定点数类型的特点是可以 处理小数 ,你可以把整数看成小数的一个特例。因此,浮点数和定点数的使用场景,比整数大多了。 MySQL支持的浮点数类型,分别是 FLOAT、DOUBLE、REAL。

    • FLOAT 表示单精度浮点数;

    • DOUBLE 表示双精度浮点数;

      image-20220405114116059

    • REAL默认就是 DOUBLE。如果你把 SQL 模式设定为启用“ REAL_AS_FLOAT ”,那 么,MySQL 就认为REAL 是 FLOAT。如果要启用“REAL_AS_FLOAT”,可以通过以下 SQL 语句实现:

      SET sql_mode = “REAL_AS_FLOAT”;

    问题1: FLOAT 和 DOUBLE 这两种数据类型的区别是啥呢?

    FLOAT 占用字节数少,取值范围小;DOUBLE 占用字节数多,取值范围也大。

    **问题2:**为什么浮点数类型的无符号数取值范围,只相当于有符号数取值范围的一半,也就是只相当于有符号数取值范围大于等于零的部分呢?

    MySQL 存储浮点数的格式为: 符号(S) 、 尾数(M) 和 阶码(E) 。因此,无论有没有符号,MySQL 的浮点数都会存储表示符号的部分。因此, 所谓的无符号数取值范围,其实就是有符号数取值范围大于等于零的部分。

    3.2 数据精度说明

    对于浮点类型,在MySQL中单精度值使用 4 个字节,双精度值使用 8 个字节。

    • MySQL允许使用 非标准语法 (其他数据库未必支持,因此如果涉及到数据迁移,则最好不要这么

      用): FLOAT(M,D) 或 DOUBLE(M,D) 。这里,M称为 精度 ,D称为 标度 。(M,D)中 M=整数位+小数位,D=小数位。 D<=M<=255,0<=D<=30。

      例如,定义为FLOAT(5,2)的一个列可以显示为-999.99-999.99。如果超过这个范围会报错。

    • FLOAT和DOUBLE类型在不指定(M,D)时,默认会按照实际的精度(由实际的硬件和操作系统决定)来显示。

    • 说明:浮点类型,也可以加 UNSIGNED ,但是不会改变数据范围,例如:FLOAT(3,2) UNSIGNED仍然只能表示0-9.99的范围。

    • 不管是否显式设置了精度(M,D),这里MySQL的处理方案如下:

      • 如果存储时,整数部分超出了范围,MySQL就会报错,不允许存这样的值
      • 如果存储时,小数点部分若超出范围,就分以下情况:
        • 若四舍五入后,整数部分没有超出范围,则只警告,但能成功操作并四舍五入删除多余的小数位后保存。例如在FLOAT(5,2)列内插入999.009,近似结果是999.01。
        • 若四舍五入后,整数部分超出范围,则MySQL报错,并拒绝处理。如FLOAT(5,2)列内插入999.995和-999.995都会报错。
    • 从MySQL 8.0.17开始,FLOAT(M,D) 和DOUBLE(M,D)用法在官方文档中已经明确不推荐使用,将来可能被移除。另外,关于浮点型FLOAT和DOUBLE的UNSIGNED也不推荐使用了,将来也可能被移除

    • 举例

      CREATE TABLE test_double1(
          f1 FLOAT,
          f2 FLOAT(5,2),
          f3 DOUBLE,
          f4 DOUBLE(5,2) 
      );
      DESC test_double1; 
      INSERT INTO test_double1 VALUES(123.456,123.456,123.4567,123.45); 
      #Out of range value for column 'f2' at row 1 
      INSERT INTO test_double1 VALUES(123.456,1234.456,123.4567,123.45); 
      SELECT * FROM test_double1;
      

      3.3精度误差说明

      浮点数类型有个缺陷,就是不精准。下面我来重点解释一下为什么 MySQL 的浮点数不够精准。比如,我们设计一个表,有f1这个字段,插入值分别为0.47,0.44,0.19,我们期待的运行结果是:0.47 + 0.44 + 0.19 = 1.1。而使用sum之后查询:

      CREATE TABLE test_double2(
      f1 DOUBLE 
      );
      INSERT INTO test_double2 VALUES(0.47),(0.44),(0.19);
      

      image-20220405124617102

      查询结果是 1.0999999999999999。看到了吗?虽然误差很小,但确实有误差。 你也可以尝试把数据类型改成 FLOAT,然后运行求和查询,得到的是, 1.0999999940395355。显然,误差更大了。

      那么,为什么会存在这样的误差呢?问题还是出在 MySQL 对浮点类型数据的存储方式上。

      MySQL 用 4 个字节存储 FLOAT 类型数据,用 8 个字节来存储 DOUBLE 类型数据。无论哪个,都是采用二进制的方式来进行存储的。比如 9.625,用二进制来表达,就是 1001.101,或者表达成 1.001101×2^3。如果尾数不是 0 或 5(比如 9.624),你就无法用一个二进制数来精确表达。进而,就只好在取值允许的范围内进行四舍五入。

      在编程中,如果用到浮点数,要特别注意误差问题,因为浮点数是不准确的,所以我们要避免使用“=”来**判断两个数是否相等。**同时,在一些对精确度要求较高的项目中,千万不要使用浮点数,不然会导致结果错误,甚至是造成不可挽回的损失。那么,MySQL 有没有精准的数据类型呢?当然有,这就是定点数类型: DECIMAL 。

      4.定点数类型

      4.1 类型介绍

      • MySQL中的定点数类型只有 DECIMAL 一种类型。

        image-20220405124934162

        使用 DECIMAL(M,D) 的方式表示高精度小数。其中,M被称为精度,D被称为标度。0<=M<=65, 0<=D<=30,D<M。例如,定义DECIMAL(5,2)的类型,表示该列取值范围是-999.99~999.99。

      • DECIMAL(M,D) 的最大取值范围与 DOUBLE 类型一样,但是有效的数据范围是由M和D决定的。DECIMAL 的存储空间并不是固定的,由精度值M决定,总共占用的存储空间为M+2个字节。也就是说,在一些对精度要求不高的场景下,比起占用同样字节长度的定点数,浮点数表达的数值范围可以更大一些。

      • 定点数在MySQL内部是以 字符串 的形式进行存储,这就决定了它一定是精准的。

      • 当DECIMAL类型不指定精度和标度时,其默认为DECIMAL(10,0)。当数据的精度超出了定点数类型的精度范围时,则MySQL同样会进行四舍五入处理。

      • 浮点数 vs 定点数

        • 浮点数相对于定点数的优点是在长度一定的情况下,浮点类型取值范围大,但是不精准,适用于需要取值范围大,又可以容忍微小误差的科学计算场景(比如计算化学、分子建模、流体动力学等)
        • 定点数类型取值范围相对小,但是精准,没有误差,适合于对精度要求极高的场景 (比如涉及金额计算的场景)
      • 举例

        CREATE TABLE test_decimal1(
            f1 DECIMAL,
            f2 DECIMAL(5,2) 
        );
        DESC test_decimal1; 
        INSERT INTO test_decimal1(f1,f2) VALUES(123.123,123.456); 
        #Out of range value for column 'f2' at row 1 
        INSERT INTO test_decimal1(f2) VALUES(1234.34)
        

        image-20220405125348314

      • 举例

        我们运行下面的语句,把test_double2表中字段“f1”的数据类型修改为 DECIMAL(5,2):

        ALTER TABLE test_double2 
        MODIFY f1 DECIMAL(5,2);
        

        然后,我们再一次运行求和语句:

        image-20220405125452313

    4.2开发中经验

    “由于 DECIMAL 数据类型的精准性,在我们的项目中,除了极少数(比如商品编号)用到整数类型外,其他的数值都用的是 DECIMAL,原因就是这个项目所处的零售行业,要求精准,一分钱也不能差。 ” ——来自某项目经理

    5.位类型:BIT

    BIT类型中存储的是二进制值,类似010110。

    image-20220405125658905

    BIT类型,如果没有指定(M),默认是1位。这个1位,表示只能存1位的二进制值。这里(M)是表示二进制的位数,位数最小值为1,最大值为64。

    CREATE TABLE test_bit1(
        f1 BIT,
        f2 BIT(5),
        f3 BIT(64) 
    );
    INSERT INTO test_bit1(f1) VALUES(1); 
    #Data too long for column 'f1' at row 1 
    INSERT INTO test_bit1(f1) VALUES(2); 
    INSERT INTO test_bit1(f2) VALUES(23);
    

    注意:在向BIT类型的字段中插入数据时,一定要确保插入的数据在BIT类型支持的范围内。

    使用SELECT命令查询位字段时,可以用 BIN() 或 HEX() 函数进行读取。

    image-20220405125850826

    可以看到,使用b+0查询数据时,可以直接查询出存储的十进制数据的值。

    6.日期与时间类型

    日期与时间是重要的信息,在我们的系统中,几乎所有的数据表都用得到。原因是客户需要知道数据的时间标签,从而进行数据查询、统计和处理。MySQL有多种表示日期和时间的数据类型,不同的版本可能有所差异,MySQL8.0版本支持的日期和时间类型主要有:YEAR类型、TIME类型、DATE类型、DATETIME类型和TIMESTAMP类型。

    • YEAR 类型通常用来表示年
    • DATE 类型通常用来表示年、月、日
    • TIME 类型通常用来表示时、分、秒
    • DATETIME 类型通常用来表示年、月、日、时、分、秒
    • TIMESTAMP 类型通常用来表示带时区的年、月、日、时、分、秒

    image-20220405130128696

    可以看到,不同数据类型表示的时间内容不同、取值范围不同,而且占用的字节数也不一样,你要根据实际需要灵活选取。为什么时间类型 TIME 的取值范围不是 -23:59:59~23:59:59 呢?原因是 MySQL 设计的 TIME 类型,不光表示一天之内的时间,而且可以用来表示一个时间间隔,这个时间间隔可以超过 24 小时。

    6.1 YEAR类型

    YEAR类型用来表示年份,在所有的日期时间类型中所占用的存储空间最小,只需要 1个字节 的存储空间。在MySQL中,YEAR有以下几种存储格式:

    • 以4位字符串或数字格式表示YEAR类型,其格式为YYYY,最小值为1901,最大值为2155。
    • 以2位字符串格式表示YEAR类型,最小值为00,最大值为99。
      • 当取值为01到69时,表示2001到2069;
      • 当取值为70到99时,表示1970到1999;
      • 当取值整数的0或00添加的话,那么是0000年;
      • 当取值是日期/字符串的’0’添加的话,是2000年

    从MySQL5.5.27开始,2位格式的YEAR已经不推荐使用。YEAR默认格式就是“YYYY”,没必要写成YEAR(4),

    从MySQL 8.0.19开始,不推荐使用指定显示宽度的YEAR(4)数据类型。

    CREATE TABLE test_year(
    	f1 YEAR,
    	f2 YEAR(4) 
    );
    

    image-20220405130755089

    image-20220405130836896

    6.2 DATE类型

    DATE类型表示日期,没有时间部分,格式为 YYYY-MM-DD ,其中,YYYY表示年份,MM表示月份,DD表示日期。需要 3个字节 的存储空间。在向DATE类型的字段插入数据时,同样需要满足一定的格式条件。

    • 以 YYYY-MM-DD 格式或者 YYYYMMDD 格式表示的字符串日期,其最小取值为1000-01-01,最大取值为9999-12-03。YYYYMMDD格式会被转化为YYYY-MM-DD格式。
    • 以 YY-MM-DD 格式或者 YYMMDD 格式表示的字符串日期,此格式中,年份为两位数值或字符串满足YEAR类型的格式条件为:当年份取值为00到69时,会被转化为2000到2069;当年份取值为70到99时,会被转化为1970到1999。
    • 使用 CURRENT_DATE() 或者 NOW() 函数,会插入当前系统的日期。

    举例:

    创建数据表,表中只包含一个DATE类型的字段f1。

    CREATE TABLE test_date1(
    	f1 DATE 
    );
    Query OK, 0 rows affected (0.13 sec)
    #插入数据:
    INSERT INTO test_date1 
    VALUES ('2020-10-01'), ('20201001'),(20201001); 
    
    INSERT INTO test_date1 
    VALUES ('00-01-01'), ('000101'), ('69-10-01'), ('691001'), ('70-01-01'), ('700101'), ('99-01-01'), ('990101');
    
    INSERT INTO test_date1 
    VALUES (000301), (690301), (700301), (990301);
    
    INSERT INTO test_date1 
    VALUES (CURRENT_DATE()), (NOW()); 
    
    SELECT * FROM test_date1;
    

    6.3 TIME类型

    TIME类型用来表示时间,不包含日期部分。在MySQL中,需要 3个字节 的存储空间来存储TIME类型的数据,可以使用“HH:MM:SS”格式来表示TIME类型,其中,HH表示小时,MM表示分钟,SS表示秒。

    在MySQL中,向TIME类型的字段插入数据时,也可以使用几种不同的格式。 (1)可以使用带有冒号的字符串,比如’ D HH:MM:SS’ 、’ HH:MM:SS ‘、’ HH:MM ‘、’ D HH:MM ‘、’ D HH ‘或’ SS ‘格式,都能被正确地插入TIME类型的字段中。其中D表示天,其最小值为0,最大值为34。如果使用带有D格式的字符串插入TIME类型的字段时,D会被转化为小时,计算格式为D*24+HH。当使用带有冒号并且不带D的字符串表示时间时,表示当天的时间,比如12:10表示12:10:00,而不是00:12:10。 (2)可以使用不带有冒号的字符串或者数字,格式为’ HHMMSS '或者 HHMMSS 。如果插入一个不合法的字符串或者数字,MySQL在存储数据时,会将其自动转化为00:00:00进行存储。比如1210,MySQL会将最右边的两位解析成秒,表示00:12:10,而不是12:10:00。 (3)使用 CURRENT_TIME() 或者 NOW() ,会插入当前系统的时间。

    举例:

    创建数据表,表中包含一个TIME类型的字段f1。

    CREATE TABLE test_time1(
    	f1 TIME 
    );
    Query OK, 0 rows affected (0.02 sec) 
    INSERT INTO test_time1 
    VALUES('2 12:30:29'), ('12:35:29'), ('12:40'), ('2 12:40'),('1 05'), ('45'); 
    INSERT INTO test_time1 
    VALUES ('123520'), (124011),(1210); 
    INSERT INTO test_time1 VALUES (NOW()), (CURRENT_TIME()); 
    SELECT * FROM test_time1;
    

    6.4 DATETIME

    DATETIME类型在所有的日期时间类型中占用的存储空间最大,总共需要 8 个字节的存储空间。在格式上为DATE类型和TIME类型的组合,可以表示为 YYYY-MM-DD HH:MM:SS ,其中YYYY表示年份,MM表示月份,DD表示日期,HH表示小时,MM表示分钟,SS表示秒。在向DATETIME类型的字段插入数据时,同样需要满足一定的格式条件。

    • 以 YYYY-MM-DD HH:MM:SS 格式或者 YYYYMMDDHHMMSS 格式的字符串插入DATETIME类型的字段时,最小值为1000-01-01 00:00:00,最大值为9999-12-03 23:59:59
      • 以YYYYMMDDHHMMSS格式的数字插入DATETIME类型的字段时,会被转化为YYYY-MM-DD HH:MM:SS格式。
    • 以 YY-MM-DD HH:MM:SS 格式或者 YYMMDDHHMMSS 格式的字符串插入DATETIME类型的字段时,两位数的年份规则符合YEAR类型的规则,00到69表示2000到2069;70到99表示1970到1999。
    • 使用函数 CURRENT_TIMESTAMP() 和 NOW() ,可以向DATETIME类型的字段插入系统的当前日期和时间。

    举例:

    #创建数据表,表中包含一个DATETIME类型的字段dt。
    CREATE TABLE test_datetime1( 
        dt DATETIME 
    );
    Query OK, 0 rows affected (0.02 sec)
    #插入数据:
    INSERT INTO test_datetime1 
    VALUES ('2021-01-01 06:50:30'), ('20210101065030'); 
    INSERT INTO test_datetime1 
    VALUES ('99-01-01 00:00:00'), ('990101000000'), ('20-01-01 00:00:00'), ('200101000000'); 
    INSERT INTO test_datetime1 
    VALUES (20200101000000), (200101000000), (19990101000000), (990101000000); 
    INSERT INTO test_datetime1 VALUES (CURRENT_TIMESTAMP()), (NOW());
    

    6.5 TIMESTAMP类型

    TIMESTAMP类型也可以表示日期时间,其显示格式与DATETIME类型相同,都是 YYYY-MM-DD HH:MM:SS ,需要4个字节的存储空间。但是TIMESTAMP存储的时间范围比DATETIME要小很多,只能存储“1970-01-01 00:00:01 UTC”到“2038-01-19 03:14:07 UTC”之间的时间。其中,UTC表示世界统一时间,也叫作世界标准时间。

    • 存储数据的时候需要对当前时间所在的时区进行转换,查询数据的时候再将时间转换回当前的时区。因此,使用TIMESTAMP存储的同一个时间值,在不同的时区查询时会显示不同的时间。

    向TIMESTAMP类型的字段插入数据时,当插入的数据格式满足YY-MM-DD HH:MM:SS和YYMMDDHHMMSS时,两位数值的年份同样符合YEAR类型的规则条件,只不过表示的时间范围要小很多。如果向TIMESTAMP类型的字段插入的时间超出了TIMESTAMP类型的范围,则MySQL会抛出错误信息。

    举例:

    #创建数据表,表中包含一个TIMESTAMP类型的字段ts。
    CREATE TABLE test_timestamp1( 
        ts TIMESTAMP 
    );
    #插入数据:
    INSERT INTO test_timestamp1 
    VALUES ('1999-01-01 03:04:50'), ('19990101030405'), ('99-01-01 03:04:05'), ('990101030405'); 
    INSERT INTO test_timestamp1 
    VALUES ('2020@01@01@00@00@00'), ('20@01@01@00@00@00'); 
    INSERT INTO test_timestamp1 
    VALUES (CURRENT_TIMESTAMP()), (NOW()); 
    #Incorrect datetime value 
    INSERT INTO test_timestamp1 VALUES ('2038-01-20 03:14:07');
    

    TIMESTAMP和DATETIME的区别:

    • TIMESTAMP存储空间比较小,表示的日期时间范围也比较小
    • 底层存储方式不同,TIMESTAMP底层存储的是毫秒值,距离1970-1-1 0:0:0 0毫秒的毫秒值。
    • 两个日期比较大小或日期计算时,TIMESTAMP更方便、更快。
    • TIMESTAMP和时区有关。TIMESTAMP会根据用户的时区不同,显示不同的结果。而DATETIME则只能反映出插入时当地的时区,其他时区的人查看数据必然会有误差的。

    image-20220405132448901

    6.6 开发中经验

    用得最多的日期时间类型,就是 DATETIME 。虽然 MySQL 也支持 YEAR(年)、 TIME(时间)、DATE(日期),以及 TIMESTAMP 类型,但是在实际项目中,尽量用 DATETIME 类型。因为这个数据类型包括了完整的日期和时间信息,取值范围也最大,使用起来比较方便。毕竟,如果日期时间信息分散在好几个字段,很不容易记,而且查询的时候,SQL 语句也会更加复杂。此外,一般存注册时间、商品发布时间等,不建议使用DATETIME存储,而是使用 时间戳 ,因为DATETIME虽然直观,但不便于计算。

    image-20220405132711542

    7.文本字符串类型

    在实际的项目中,我们还经常遇到一种数据,就是字符串数据。

    MySQL中,文本字符串总体上分为 CHAR 、 VARCHAR 、 TINYTEXT 、 TEXT 、MEDIUMTEXT 、 LONGTEXT 、 ENUM 、 SET 等类型

    image-20220405132958219

    7.1CHAR与VARCHAR类型

    CHAR和VARCHAR类型都可以存储比较短的字符串。

    image-20220405133135363

    CHAR类型:

    • CHAR(M) 类型一般需要预先定义字符串长度。如果不指定(M),则表示长度默认是1个字符。
    • 如果保存时,数据的实际长度比CHAR类型声明的长度小,则会在 右侧填充 空格以达到指定的长度。当MySQL检索CHAR类型的数据时,CHAR类型的字段会去除尾部的空格。
    • 定义CHAR类型字段时,声明的字段长度即为CHAR类型字段所占的存储空间的字节数。
    CREATE TABLE test_char1( 
        c1 CHAR, 
        c2 CHAR(5) 
    );
    DESC test_char1;
    
    INSERT INTO test_char1 
    VALUES('a','Tom');
    
    SELECT c1,CONCAT(c2,'***') 
    FROM test_char1; 
    
    INSERT INTO test_char1(c2) 
    VALUES('a '); 
    
    SELECT CHAR_LENGTH(c2) 
    FROM test_char1;
    

    VARCHAR类型:

    • VARCHAR(M) 定义时, 必须指定 长度M,否则报错。
    • MySQL4.0版本以下,varchar(20):指的是20字节,如果存放UTF8汉字时,只能存6个(每个汉字3字节) ;MySQL5.0版本以上,varchar(20):指的是20字符。
    • 检索VARCHAR类型的字段数据时,会保留数据尾部的空格。VARCHAR类型的字段所占用的存储空间为字符串实际长度加1个字节。
    CREATE TABLE test_varchar1( 
        NAME VARCHAR #错误 
    );
    #Column length too big for column 'NAME' (max = 21845); 
    CREATE TABLE test_varchar2( 
        NAME VARCHAR(65535) #错误 
    )
    CREATE TABLE test_varchar3( 
        NAME VARCHAR(5) 
    );
    INSERT INTO test_varchar3 
    VALUES('尚硅谷'),('尚硅谷教育'); 
    #Data too long for column 'NAME' at row 1 
    INSERT INTO test_varchar3 VALUES('尚硅谷IT教育')
    

    哪些情况使用 CHAR VARCHAR 更好

    image-20220405133628995

    情况1:存储很短的信息。比如门牌号码101,201……这样很短的信息应该用char,因为varchar还要占个byte用于存储信息长度,本来打算节约存储的,结果得不偿失。

    情况2:固定长度的。比如使用uuid作为主键,那用char应该更合适。因为他固定长度,varchar动态根据长度的特性就消失了,而且还要占个长度信息。

    情况3:十分频繁改变的column。因为varchar每次存储都要有额外的计算,得到长度等工作,如果一个非常频繁改变的,那就要有很多的精力用于计算,而这些对于char来说是不需要的。

    情况4:具体存储引擎中的情况:

    • MyISAM 数据存储引擎和数据列:MyISAM数据表,最好使用固定长度(CHAR)的数据列代替可变长度(VARCHAR)的数据列。这样使得整个表静态化,从而使 数据检索更快 ,用空间换时间。
    • MEMORY 存储引擎和数据列:MEMORY数据表目前都使用固定长度的数据行存储,因此无论使用CHAR或VARCHAR列都没有关系,两者都是作为CHAR类型处理的。
    • InnoDB 存储引擎,建议使用VARCHAR类型。因为对于InnoDB数据表,内部的行存储格式并没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),而且主要影响性能的因素 是数据行使用的存储总量,由于char平均占用的空间多于varchar,所以除了简短并且固定长度的,其他考虑varchar。这样节省空间,对磁盘I/O和数据存储总量比较好。

    7.2 TEXT类型

    在MySQL中,TEXT用来保存文本类型的字符串,总共包含4种类型,分别为TINYTEXT、TEXT、 MEDIUMTEXT 和 LONGTEXT 类型。

    在向TEXT类型的字段保存和查询数据时,系统自动按照实际长度存储,不需要预先定义长度。这一点和VARCHAR类型相同。

    每种TEXT类型保存的数据长度和所占用的存储空间不同,如下:

    image-20220405134255946

    由于实际存储的长度不确定, MySQL 不允许 TEXT 类型的字段做主键。遇到这种情况,你只能采用CHAR(M),或者 VARCHAR(M)。

    举例:

    #创建数据表:
    CREATE TABLE test_text( tx TEXT );
    INSERT INTO test_text VALUES('atguigu '); 
    SELECT CHAR_LENGTH(tx) FROM test_text; #10
    

    说明在保存和查询数据时,并没有删除TEXT类型的数据尾部的空格。

    开发中经验:

    TEXT文本类型,可以存比较大的文本段,搜索速度稍慢,因此如果不是特别大的内容,建议使用CHAR, VARCHAR来代替。还有TEXT类型不用加默认值,加了也没用。而且text和blob类型的数据删除后容易导致“空洞”,使得文件碎片比较多,所以频繁使用的表不建议包含TEXT类型字段,建议单独分出去,单独用一个表。

    8.ENUM类型

    ENUM类型也叫作枚举类型,ENUM类型的取值范围需要在定义字段时进行指定。设置字段值时,ENUM类型只允许从成员中选取单个值,不能一次选取多个值。其所需要的存储空间由定义ENUM类型时指定的成员个数决定

    image-20220405134553481

    • 当ENUM类型包含1~255个成员时,需要1个字节的存储空间;
    • 当ENUM类型包含256~65535个成员时,需要2个字节的存储空间。
    • ENUM类型的成员个数的上限为65535个。

    举例:

    #创建表如下:
    CREATE TABLE test_enum( 
        season ENUM('春','夏','秋','冬','unknow') 
    )
    #添加数据:
    INSERT INTO test_enum VALUES('春'),('秋'); 
    # 忽略大小写 
    INSERT INTO test_enum VALUES('UNKNOW'); 
    # 允许按照角标的方式获取指定索引位置的枚举值 
    INSERT INTO test_enum VALUES('1'),(3); 
    # Data truncated for column 'season' at row 1 
    INSERT INTO test_enum VALUES('ab'); 
    # 当ENUM类型的字段没有声明为NOT NULL时,插入NULL也是有效的 
    INSERT INTO test_enum VALUES(NULL);
    

    9.SET类型

    SET表示一个字符串对象,可以包含0个或多个成员,但成员个数的上限为 64 。设置字段值时,可以取取值范围内的 0 个或多个值。当SET类型包含的成员个数不同时,其所占用的存储空间也是不同的,具体如下:

    image-20220405134927506

    SET类型在存储数据时成员个数越多,其占用的存储空间越大。注意:SET类型在选取成员时,可以一次选择多个成员,这一点与ENUM类型不同。

    #举例
    CREATE TABLE test_set( s SET ('A', 'B', 'C') );
    #向表中插入数据:
    INSERT INTO test_set (s) VALUES ('A'), ('A,B'); 
    #插入重复的SET类型成员时,MySQL会自动删除重复的成员 
    INSERT INTO test_set (s) VALUES ('A,B,C,A'); 
    #向SET类型的字段插入SET成员中不存在的值时,MySQL会抛出错误。 
    INSERT INTO test_set (s) VALUES ('A,B,C,D'); 
    SELECT * FROM test_set;
    #举例2
    CREATE TABLE temp_mul( 
        gender ENUM('男','女'), 
        hobby SET('吃饭','睡觉','打豆豆','写代码') 
    );
    INSERT INTO temp_mul VALUES('男','睡觉,打豆豆'); #成功 
    # Data truncated for column 'gender' at row 1 
    INSERT INTO temp_mul VALUES('男,女','睡觉,写代码'); #失败 
    # Data truncated for column 'gender' at row 1 
    INSERT INTO temp_mul VALUES('妖','睡觉,写代码');#失败 
    INSERT INTO temp_mul VALUES('男','睡觉,写代码,吃饭'); #成功
    

    10.二进制字符串类型

    MySQL中的二进制字符串类型主要存储一些二进制数据,比如可以存储图片、音频和视频等二进制数据。MySQL中支持的二进制字符串类型主要包括BINARY、VARBINARY、TINYBLOB、BLOB、MEDIUMBLOB 和 LONGBLOB类型。

    BINARY与VARBINARY类型

    BINARY和VARBINARY类似于CHAR和VARCHAR,只是它们存储的是二进制字符串。

    BINARY (M)为固定长度的二进制字符串,M表示最多能存储的字节数,取值范围是0~255个字符。如果未指定(M),表示只能存储 1个字节 。例如BINARY (8),表示最多能存储8个字节,如果字段值不足(M)个字节,将在右边填充’\0’以补齐指定长度。

    VARBINARY (M)为可变长度的二进制字符串,M表示最多能存储的字节数,总字节数不能超过行的字节长度限制65535,另外还要考虑额外字节开销,VARBINARY类型的数据除了存储数据本身外,还需要1或2个字节来存储数据的字节数。VARBINARY类型 必须指定(M) ,否则报错。

    image-20220405141514055

    举例:

    #创建表
    CREATE TABLE test_binary1(
        f1 BINARY,
        f2 BINARY(3), # f3 VARBINARY,
        f4 VARBINARY(10) 
    )
    INSERT INTO test_binary1(f1,f2) 
    VALUES('a','a'); 
    INSERT INTO test_binary1(f1,f2) 
    VALUES('尚','尚');#失败 
    INSERT INTO test_binary1(f2,f4) 
    VALUES('ab','ab')
    

    image-20220405141723017

    BLOB类型

    BLOB是一个 二进制大对象 ,可以容纳可变数量的数据。

    MySQL中的BLOB类型包括TINYBLOB、BLOB、MEDIUMBLOB和LONGBLOB 4种类型,它们可容纳值的最大长度不同。可以存储一个二进制的大对象,比如 图片 、 音频 和 视频 等。需要注意的是,在实际工作中,往往不会在MySQL数据库中使用BLOB类型存储大对象数据,通常会将图片、音频和视频文件存储到 服务器的磁盘上 ,并将图片、音频和视频的访问路径存储到MySQL中。

    image-20220405141825657

    举例:

    CREATE TABLE test_blob1( 
        id INT, 
        img MEDIUMBLOB 
    )
    

    TEXT和BLOB的使用注意事项

    在使用text和blob字段类型时要注意以下几点,以便更好的发挥数据库的性能。

    ① BLOB和TEXT值也会引起自己的一些问题,特别是执行了大量的删除或更新操作的时候。删除这种值会在数据表中留下很大的" 空洞 ",以后填入这些"空洞"的记录可能长度不同。为了提高性能,建议定期使用 OPTIMIZE TABLE 功能对这类表进行 碎片整理 。

    ② 如果需要对大文本字段进行模糊查询,MySQL 提供了 前缀索引 。但是仍然要在不必要的时候避免检索大型的BLOB或TEXT值。例如,SELECT * 查询就不是很好的想法,除非你能够确定作为约束条件的WHERE子句只会找到所需要的数据行。否则,你可能毫无目的地在网络上传输大量的值。

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

    11.JSON类型

    JSON(JavaScript Object Notation)是一种轻量级的 数据交换格式 。简洁和清晰的层次结构使得 JSON 成为理想的数据交换语言。它易于人阅读和编写,同时也易于机器解析和生成,并有效地提升网络传输效率。JSON 可以将 JavaScript 对象中表示的一组数据转换为字符串,然后就可以在网络或者程序之间轻 松地传递这个字符串,并在需要的时候将它还原为各编程语言所支持的数据格式。

    在MySQL 5.7中,就已经支持JSON数据类型。在MySQL 8.x版本中,JSON类型提供了可以进行自动验证的JSON文档和优化的存储结构,使得在MySQL中存储和读取JSON类型的数据更加方便和高效。 创建数据表,表中包含一个JSON类型的字段 js 。

    CREATE TABLE test_json( 
        js json 
    );
    #向表中插入JSON数据。
    INSERT INTO test_json (js) 
    VALUES ('{"name":"songhk", "age":18, "address":{"province":"beijing", "city":"beijing"}}');
    

    查询t19表中的数据。

    image-20220405142430165

    当需要检索JSON类型的字段中数据的某个具体值时,可以使用“->”和“->>”符号

    image-20220405142505664

    通过“->”和“->>”符号,从JSON字段中正确查询出了指定的JSON数据的值。

    12.空间类型

    MySQL 空间类型扩展支持地理特征的生成、存储和分析。这里的地理特征表示世界上具有位置的任何东西,可以是一个实体,例如一座山;可以是空间,例如一座办公楼;也可以是一个可定义的位置,例如一个十字路口等等。MySQL中使用 Geometry(几何) 来表示所有地理特征。Geometry指一个点或点的集合,代表世界上任何具有位置的事物。

    MySQL的空间数据类型(Spatial Data Type)对应于OpenGIS类,包括单值类型:GEOMETRY、POINT、 LINESTRING、POLYGON以及集合类型:MULTIPOINT、MULTILINESTRING、MULTIPOLYGON、 GEOMETRYCOLLECTION 。

    • Geometry是所有空间集合类型的基类,其他类型如POINT、LINESTRING、POLYGON都是Geometry的子类。
      • Point,顾名思义就是点,有一个坐标值。例如POINT(121.213342 31.234532)POINT(30 10),坐标值支持DECIMAL类型,经度(longitude)在前,维度(latitude)在后,用空格分隔。
      • LineString,线,由一系列点连接而成。如果线从头至尾没有交叉,那就是简单的(simple);如果起点和终点重叠,那就是封闭的(closed)。例如LINESTRING(30 10,10 30,40 40),点与点之间用逗号分隔,一个点中的经纬度用空格分隔,与POINT格式一致。
      • Polygon,多边形。可以是一个实心平面形,即没有内部边界,也可以有空洞,类似纽扣。最简单的就是只有一个外边界的情况,例如POLYGON((0 0,10 0,10 10, 0 10))。

    下面展示几种常见的几何图形元素:

    image-20220405142720438

    • MultiPoint、MultiLineString、MultiPolygon、GeometryCollection 这4种类型都是集合类,是多个Point、LineString或Polygon组合而成。

    下面展示的是多个同类或异类几何图形元素的组合:

    image-20220405142745379

    13.小结及选择建议

    在定义数据类型时,如果确定是 整数 ,就用 INT ; 如果是 小数 ,一定用定点数类型DECIMAL(M,D) ; 如果是日期与时间,就用 DATETIME 。

    这样做的好处是,首先确保你的系统不会因为数据类型定义出错。不过,凡事都是有两面的,可靠性好,并不意味着高效。比如,TEXT 虽然使用方便,但是效率不如 CHAR(M) 和VARCHAR(M)。

    关于字符串的选择,建议参考如下阿里巴巴的《Java开发手册》规范:

    阿里巴巴《Java开发手册》之MySQL数据库:

    • 任何字段如果为非负数,必须是 UNSIGNED

    • 【 强制 】小数类型为 DECIMAL,禁止使用 FLOAT 和 DOUBLE。

      • 说明:在存储的时候,FLOAT 和 DOUBLE 都存在精度损失的问题,很可能在比较值的候,得到不正确的结果。如果存储的数据范围超过 DECIMAL 的范围,建议将数据拆成整数和小数并分开存储。
    • 【 强制 】如果存储的字符串长度几乎相等,使用 CHAR 定长字符串类型。

    • 【 强制 】VARCHAR 是可变长字符串,不预先分配存储空间,长度不要超过 5000。如果存储长度大于此值,定义字段类型为 TEXT,独立出来一张表,用主键来对应,避免影响其它字段索引效率。

    展开全文
  • Java的基本类型

    万次阅读 2021-12-17 21:25:42
    文章目录前言Java 虚拟机的 boolean 类型Java 的基本类型 前言 如果你了解面向对象语言的发展史,那你可能听说过 Smalltalk 这门语言。它的影响力之大,以至于之后诞生的面向对象语言,或多或少都借鉴了它的设计和...


    前言

    面向对象语言的发展史中 Smalltalk 这门语言的影响力之大,以至于之后诞生的面向对象语言,或多或少都借鉴了它的设计和实现。

    在 Smalltalk 中,所有的值都是对象。因此许多人认为它是一门纯粹的面向对象语言。

    Java 则不同,它引进了八个基本类型,来支持数值计算。Java 这么做的原因主要是工程上的考虑,因为使用基本类型能够在执行效率以及内存使用两方面提升软件性能。

    
    public class Foo {
      public static void main(String[] args) {
        boolean 吃过饭没 = 2; // 直接编译的话javac会报错
        if (吃过饭没) System.out.println("吃了");
        if (true == 吃过饭没) System.out.println("真吃了");
      }
    }
    

    构造了一段代码,它将一个 boolean 类型的局部变量赋值为 2。变量名叫“吃过饭没”。第一个 if 语句,也就是直接判断“吃过饭没”,在它成立的情况下,代码会打印“吃了”。第二个 if 语句,也就是判断“吃过饭没”和 true 是否相等,在它成立的情况下,代码会打印“真吃了”。直接编译这段代码,编译器是会报错的。

    所以迂回了一下,采用一个 Java 字节码的汇编工具,直接对字节码进行更改。跑这段代码会发现,问虚拟机“吃过饭没”,它会回答“吃了”,而问虚拟机“真(==)吃过饭没”,虚拟机则不会回答“真吃了”。那么虚拟机到底吃过没,下面分析一下这背后的细节。

    Java 虚拟机的 boolean 类型

    首先看看 Java 语言规范以及 Java 虚拟机规范是怎么定义 boolean 类型的。

    在 Java 语言规范中,boolean 类型的值只有两种可能,分别用符号“true”和“false”来表示。显然,这两个符号是不能被虚拟机直接使用的。

    在 Java 虚拟机规范中,boolean 类型则被映射成 int 类型。“true”被映射为整数 1,而“false”被映射为整数 0。这个编码规则约束了 Java 字节码的具体实现。

    举个例子,对于存储 boolean 数组的字节码,Java 虚拟机需保证实际存入的值是整数 1 或者 0。Java 虚拟机规范同时也要求 Java 编译器遵守这个编码规则,并且用整数相关的字节码来实现逻辑运算,以及基于 boolean 类型的条件跳转。这样在编译而成的 class 文件中,除了字段和传入参数外,基本看不出 boolean 类型的痕迹了。

    
    # Foo.main编译后的字节码
     0: iconst_2       // 我们用AsmTools更改了这一指令
     1: istore_1
     2: iload_1
     3: ifeq 14        // 第一个if语句,即操作数栈上数值为0时跳转
     6: getstatic java.lang.System.out
     9: ldc "吃了"
    11: invokevirtual java.io.PrintStream.println
    14: iload_1
    15: iconst_1
    16: if_icmpne 27   // 第二个if语句,即操作数栈上两个数值不相同时跳转
    19: getstatic java.lang.System.out
    22: ldc "真吃了"
    24: invokevirtual java.io.PrintStream.println
    27: return
    

    第一个 if 语句会被编译成条件跳转字节码 ifeq,也就是说,如果局部变量“吃过饭没”的值为 0,那么跳过打印“吃了”的语句。

    第二个 if 语句则会被编译成条件跳转字节码 if_icmpne,也就是说,如果局部变量的值和整数 1 不相等,那么跳过打印“真吃了”的语句。

    Java 编译器的确遵守了相同的编码规则。当然这个约束很容易绕开。除了用到的汇编工具 AsmTools 外,还有许多可以修改字节码的 Java 库,比如说 ASM 等。

    对于 Java 虚拟机来说,它看到的 boolean 类型,早已被映射为整数类型。因此,将原本声明为 boolean 类型的局部变量,赋值为除了 0、1 之外的整数值,在 Java 虚拟机看来是“合法”的。

    在例子中,经过编译器编译之后,Java 虚拟机看到的不是在问“吃过饭没”,而是在问“吃过几碗饭”。也就是说,第一个 if 语句变成:你不会一碗饭都没吃吧。第二个 if 语句则变成:你吃过一碗饭了吗。

    如果约定俗成,每人每顿只吃一碗,那么第二个 if 语句还是有意义的。但如果打破常规,吃了两碗,那么较真的 Java 虚拟机就会将第二个 if 语句判定为假了。

    Java 的基本类型

    Java 的基本类型还包括整数类型 boolean 、byte、short、char、int、 long,以及浮点类型 float 和 double。
    在这里插入图片描述
    Java 的基本类型都有对应的值域和默认值。byte、short、int、long、float 、double 的值域依次扩大,而且前面的值域被后面的值域所包含。因此,从前面的基本类型转换至后面的基本类型,无需强制转换。另外一点值得注意的是,尽管他们的默认值看起来不一样,但在内存中都是 0。

    boolean 和 char 是唯二的无符号类型。在不考虑违反规范的情况下,boolean 类型的取值范围是 0 或者 1。char 类型的取值范围则是[0, 65535]。通常我们可以认定 char 类型的值为非负数。这种特性十分有用,比如说作为数组索引等。

    在前面的例子中,能够将整数 2 存储到一个声明为 boolean 类型的局部变量中。其实声明为 byte、char 以及 short 的局部变量,也能够存储超出它们取值范围的数值。

    这些超出取值范围的数值同样会带来一些麻烦。比如说,声明为 char 类型的局部变量实际上有可能为负数。当然,在正常使用 Java 编译器的情况下,生成的字节码会遵守 Java 虚拟机规范对编译器的约束,因此无须过分担心局部变量会超出它们的取值范围。

    Java 的浮点类型采用 IEEE 754 浮点数格式。以 float 为例,浮点类型通常有两个 0,+0.0F 以及 -0.0F。

    前者在 Java 里是 0,后者是符号位为 1、其他位均为 0 的浮点数,在内存中等同于十六进制整数 0x8000000(即 -0.0F 可通过 Float.intBitsToFloat(0x8000000) 求得)。尽管它们的内存数值不同,但是在 Java 中 +0.0F == -0.0F 会返回真。

    在有了 +0.0F 和 -0.0F 这两个定义后,便可以定义浮点数中的正无穷及负无穷。

    1. 正无穷是任意正浮点数(不包括 +0.0F)除以 +0.0F 得到的值;
    2. 负无穷是任意正浮点数除以 -0.0F 得到的值。

    在 Java 中,正无穷和负无穷是有确切的值,在内存中分别等同于十六进制整数 0x7F800000 和 0xFF800000。

    整数 0x7F800000 等同于正无穷,0x7F800001 对应浮点数是 NaN(Not-a-Number)。

    不仅如此,[0x7F800001, 0x7FFFFFFF]和[0xFF800001, 0xFFFFFFFF]对应的都是 NaN。一般计算得出的 NaN,比如说通过 +0.0F/+0.0F,在内存中应为 0x7FC00000。这个数值称之为标准的 NaN,而其他的称之为不标准的 NaN。

    NaN 有一个有趣的特性:除了“!=”始终返回 true 之外,所有其他比较结果都会返回 false。

    举例来说,“NaN<1.0F”返回 false,而“NaN>=1.0F”同样返回 false。对于任意浮点数 f,不管它是 0 还是 NaN,“f!=NaN”始终会返回 true,而“f==NaN”始终会返回 false。

    Java 基本类型的大小

    Java 虚拟机每调用一个 Java 方法,便会创建一个栈帧。为了方便理解,这里只讨论供解释器使用的解释栈帧(interpreted frame)。

    这种栈帧有两个主要的组成部分:

    1. 局部变量区;
    2. 字节码的操作数栈。

    局部变量是广义的,除了普遍意义下的局部变量之外,它还包含实例方法的“this 指针”以及方法所接收的参数。在 Java 虚拟机规范中,局部变量区等价于一个数组,并且可以用正整数来索引。除了 long、double 值需要用两个数组单元来存储之外,其他基本类型以及引用类型的值均占用一个数组单元。也就是说,boolean、byte、char、short 这四种类型,在栈上占用的空间和 int 是一样的,和引用类型也是一样的。因此,在 32 位的 HotSpot 中,这些类型在栈上将占用 4 个字节;而在 64 位的 HotSpot 中,他们将占 8 个字节。

    这种情况仅存在于局部变量,不会出现在存储于堆中的字段或者数组元素上。对于 byte、char 以及 short 这三种类型的字段或者数组单元,它们在堆上占用的空间分别为一字节、两字节,以及两字节,也就是说,跟这些类型的值域相吻合。

    将一个 int 类型的值,存储到这些类型的字段或数组时,相当于做了一次隐式的掩码操作。举例来说,把 0xFFFFFFFF(-1)存储到一个声明为 char 类型的字段里时,由于该字段仅占两字节,所以高两位的字节便会被截取掉,最终存入“\uFFFF”。

    boolean 字段和 boolean 数组则比较特殊。在 HotSpot 中,boolean 字段占用一字节,而 boolean 数组则直接用 byte 数组来实现。为了保证堆中的 boolean 值是合法的,HotSpot 在存储时显式地进行掩码操作,也就是说,只取最后一位的值存入 boolean 字段或数组中。

    Java 虚拟机的算数运算几乎全部依赖于操作数栈。也就是说,我们需要将堆中的 boolean、byte、char 以及 short 加载到操作数栈上,而后将栈上的值当成 int 类型来运算。

    对于 boolean、char 这两个无符号类型来说,加载伴随着零扩展。举个例子,char 的大小为两个字节。在加载时 char 的值会被复制到 int 类型的低二字节,而高二字节则会用 0 来填充。

    对于 byte、short 这两个类型来说,加载伴随着符号扩展。举个例子,short 的大小为两个字节。在加载时 short 的值同样会被复制到 int 类型的低二字节。如果该 short 值为非负数,即最高位为 0,那么该 int 类型的值的高二字节会用 0 来填充,否则用 1 来填充。

    总结

    Java 里的基本类型中,boolean 类型在 Java 虚拟机中被映射为整数类型:“true”被映射为 1,而“false”被映射为 0。Java 代码中的逻辑运算以及条件跳转,都是用整数相关的字节码来实现的。

    Java 还有另外 7 个基本类型。它们拥有不同的值域,但默认值在内存中均为 0。这些基本类型之中,浮点类型比较特殊。基于它的运算或比较,需要考虑 +0.0F、-0.0F 以及 NaN 的情况。

    除 long 和 double 外,其他基本类型与引用类型在解释执行的方法栈帧中占用的大小是一致的,但它们在堆中占用的大小确不同。在将 boolean、byte、char 以及 short 的值存入字段或者数组单元时,Java 虚拟机会进行掩码操作。在读取时,Java 虚拟机则会将其扩展为 int 类型。

    展开全文
  • C51 常见数据类型详解

    万次阅读 2022-07-16 21:38:52
    KEILC51编译器所支持的数据类型如下表所示。1、位变量——bit bit 位变量是C51 编译器的一种扩充数据类型,它的值是一个二进制位,不是0 就是1。2、特殊功能寄存器——sfr sfr 也是一种扩充数据类型,值域为0~255。...
  • Python数据类型转换

    千次阅读 2021-09-29 19:51:10
    Python数据类型转换1. Python的数据类型2. Python数据类型转换2.1 自动类型转换2.2 强制类型转换2.2.1 其他转字符串 1. Python的数据类型 上一遍博文已经详细地介绍了Python的数据类型,详见链接Python的变量命名及...
  • 一文带你了解TypeScript中的常用类型
  • Java 泛型,你了解类型擦除吗?

    万次阅读 多人点赞 2017-08-05 22:32:18
    代表着类型未知,但是我们的确需要对于类型的描述再精确一点,我们希望在一个范围内确定类别,比如类型 A 及 类型 A 的子类都可以。 <? extends T> 代表类型 T 及 T 的子类。 ```java public void testSub...
  • 一、int 类型转换 成String类型 定义一个int类型 int i =100; //方法一:使用 i+""; String s1 = i+""; //方法二:String.valueOF(i); String s2 = String.valueOF(i); //方法三:转化成包装类Integer,再...
  • 究极推荐:36个漂亮的各类型网站源代码打包分享

    万次下载 热门讨论 2013-01-07 09:02:39
    所有网站都采用CSS控制样式展现,木有table,都是DIV控制布局!更有一些网站有华丽丽的JS特效。 是的,在您看过之后,如果您真觉得不错,或者需要下载后续百来个网站的话,欢迎您评论,给予@贝斯特_岳 和优设哥一些...
  • Flutter(Dart)基础——数据类型

    万次阅读 2020-09-14 17:34:22
    本文将介绍Dart的数据类型,以及它们的基本用法。
  • Oracle:时间类型

    万次阅读 2020-07-30 20:58:12
    Oracle中的时间类型 1、Oracle中的时间类型只有date和TIMESTAMP,TIMESTAMP是比date更精确的类型 ⑴DATE类型:ORACLE最常用的日期类型,它可以保存日期和时间,常用日期处理都可以采用这种类型 ⑵TIMESTAMP类型:...
  • String类型转换为Long类型

    万次阅读 2022-02-08 17:42:55
    String类型转换为Long类型 //返回Long包装类型 Long.ValueOf("String") //返回long基本数据类型 Long.parseLong("String")
  • golang中的值类型和引用类型

    千次阅读 2019-08-20 20:48:29
    类型与引用类型类型类型:这些类型的变量直接指向存在内存中的值,值类型的变量的值存储在栈中。当使用等号=将一个变量的值赋给另一个变量时,如 j = i ,实际上是在内存中将 i 的值进行了拷贝。可以通过 &...
  • 类型和弱类型的语言有什么区别

    万次阅读 多人点赞 2019-09-11 17:20:50
    类型语言  强类型语言也称为强类型定义语言。是一种总是强制类型定义的语言,要求变量的使用要严格符合定义,所有变量都必须先定义后使用。  java、.NET、C++等都是强制类型定义的。也就是说,一旦一个变量被...
  • 数据类型的拆装箱 1. 拆箱、装箱 2. 自动拆箱 3. 自动装箱 4. 自动拆装箱使用场景 5. 自动拆装箱的触发时机 6. 自动拆装箱带来的问题 基本数据类型的转换 1. 容量大小排序 2. 转换规则 3. 自动类型转换 4. 强制类型...
  • 变量以及数据类型

    万次阅读 多人点赞 2021-12-14 10:51:15
    变量以及数据类型变量的相关概念为什么需要变量变量的介绍概念变量使用的基本步骤变量使用注意事项变量的数据类型注意:数据类型相关整型:基本介绍整数的类型整型的使用细节浮点类型基本介绍浮点类型说明一下:浮点...
  • 作为一个热爱前端,喜欢分享并且还是处女座的小菜鸡,每次写作都会查尽各种资料,语言表达改了又改,只希望能创作出大家喜欢的,通俗易懂的,又不俗套的精品文章,但有时自己的努力和收获完全不成正比,看着自己忙碌...
  • String 或Clobchar varchar text数据库诸如此类的类型 , 在java中都对应String还是 String 类型,不知你们是否使用Hibernate框架,使用的话可以给String 类型设置最大长度;@Column(length = 1024) private String.....
  • } } 2.6 引用类型 除了基本类型以外的所有类型都是引用类型 目前我们只遇到了String字符串类型,需要用双引号包裹 引用类型是一个对象类型,值是什么呢? 它的值是指向内存空间的引用,就是地址,所指向的内存...
  • JS数据类型之基本数据类型

    万次阅读 多人点赞 2019-06-28 16:46:43
    1.JavaScript(以下简称js)的数据类型分为两种:原始类型(即基本数据类型)和对象类型(即引用数据类型); 2.js常用的基本数据类型包括undefined、null、number、boolean、string; 3.js的引用数据类型也就是...
  • Python (类型提示)指定参数类型以及参数注解

    万次阅读 多人点赞 2020-08-14 16:38:09
    众所周知,Python 是动态类型语言,运行时不需要指定变量类型。这一点是不会改变的,但是2015年9月创始人 Guido van Rossum 在 Python 3.5 引入了一个类型系统,允许开发者指定变量类型类型提示(Type Hints)。它...
  • Java中八大基本数据类型详解

    万次阅读 多人点赞 2020-12-04 11:06:42
    自从Java发布以来,基本数据类型就是Java语言的一部分,分别是 byte, short, int, long, char, float, double, boolean .当然围绕着这些基本数据类型衍生出来了很多面试题,但是说实话,工作中基本用不到
  • MySQL数据类型

    万次阅读 2021-02-02 12:25:31
    1、整型MySQL数据类型含义(有符号)tinyint(m)1个字节 范围(-128~127)smallint(m)2个字节 范围(-32768~32767)mediumint(m)3个字节 范围(-8388608~8388607)int(m)4个字节 范围(-2147483648~2147483647)bigint(m)8个...
  • 数据结构、数据类型、抽象数据类型之间的区别

    千次阅读 多人点赞 2019-11-03 20:15:37
    抽象数据类型是由若干基本数据类型归并之后形成的一种新的数据类型,这种类型由用户定义,功能操作比基本数据类型更多,一般包括结构体和类。其实说白了,抽象数据类型就是把一些有一定关联的基本数据类型打包,然后...
  • C语言不完全类型是什么?有什么用途?

    万次阅读 多人点赞 2021-05-22 12:28:28
    ISO(国际标准化组织(International Standard Organization))将C语言分为三个不同类型集合: 函数类型、对象类型和不完全类型
  • 什么是抽象数据类型

    千次阅读 2021-04-29 23:15:13
    什么是抽象数据类型?前言1.数据类型和数据构造2.抽象数据类型的概念3.抽象数据类型的描述 前言 抽象数据类型(Abstract Data Type,ADT)是计算机领域中被广泛接受的一种思想和方法,也是一种用于设计和实现程序...
  • Oracle数据库的数据类型

    千次阅读 2021-12-18 15:59:23
    常用的数据类型有: 一.数值类型 number: 在Oracle中取消了在mysql中的int类型,使用number代替,如果你在创建 数据库表的时候使用了int类型会自动转换成number类型,并且Oracle没有 这个”auto_increment”属性,...
  • MySQL数据库列的类型—TEXT类型

    千次阅读 2021-08-01 13:50:04
    1.定义:TEXT类型是一种特殊的字符串类型,包括TINYTEXT、TEXT、MEDIUMTEXT和LONGTEXT,其长度和储存空间的对比如下表所示 各种TEXT类型的区别在于允许的长度和储存空间不同。因此,在这几种TEXT类型中,根据需求...
  • 一、 自动类型转换(隐式类型转换) 整型、实型(常量)、字符型数据可以混合运算。运算中,不同类型的数据先转化为同一类型,然后进行运算。 自动转换从低级到高级。 自动转换有以下规律: 1、小的类型自动转化为...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 11,316,382
精华内容 4,526,553
关键字:

类型

友情链接: readText.rar