• Mysql之库、表、记录相关操作1


    Mysql之库、表、记录相关操作4

    创建表完整语法

    #语法:
    create table 表名(
    字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
    )engine=innodb charset=utf8;
    
    #注意:
    1. 在同一张表中,字段名是不能相同
    2. 宽度和约束条件可选
    3. 字段名和类型是必须的
    4. []可选参数
    
    # create table db1.t1(name char(3) not null);
    # 数据插入时,name不能为空(null), 且最长只能存放三个字符
    # 总结: 宽度和约束条件为可选参数, 用来限制存放数据的规则
    

    数据库的模式

    # sql_mode :反应数据库的全局变量
    # 数据库模式限制的是客户端对服务器操作数据的方式(是否严格)
    
    # 两种模式
    no_engine_substitution:非安全性,默认
    strict_trans_tables:安全模式
    
    # 查看当前数据库模式
    show variables like "%sql_models%";# 匹配0~n个人以字符=>模糊查询
    
    
    # 设置安全模式
    set global sql_mode="strict_trans_tables";
    
    # 重启客户端
    quit
    
    
    

    数据类型

    mysql 数据库支持存放的数据类型:
    
    整型|浮点型|字符型|时间类型|枚举类型|集合类型
    

    一、整型

    整型类型:tinyint|smallint|mediumint|int|bigint

    作用:存储年龄、等级、id、号码等

    _____________________________________________________________________________
    tinyint(1字节)
        tinyint[(m)] [unsigned] [zerofill]
        小整数,用于保存一些范围的整数数值范围:
        	有符号:-128~127
            无符号:0~128
        PS:Mysql中无布尔值,使用tinyint(1)构造~~~?
    —————————————————————————————————————————————————————————————————————————————
    int(4字节)
    	int[(m)][unsigned][zerofill]
        整数,用于保存一些范围的整数数值范围:
        	有符号:-2147483648~2147483647
            无符号:0~4294967295
    —————————————————————————————————————————————————————————————————————————————
    bigint(8字节)
    	bigint[(m)][unsigned][zerofill]
        大整数,数据类型用于保存一些范围的整数数值范围:
        	有符号:-9223372036854775808~9223372036854775807
        	无符号:0~18446744073709551615
    
    '''
    约束条件:
    	undigned:无符号
    	zerofill:0填充
    '''
    不同类型所占字节数不一样,决定所占空间及存放数据的大小限制
    create table t8(x tinyint);
    insert into t8 values(200);  # 非安全模式存入,值只能到最大值127
    select (x) from t8;
    '''
    宽度:
    	1、不能决定整型存档数据的宽度,超过宽度可以存放,最终由数据类型所占字节决定
    	2、如果没有超过宽度,且有zerofill限制,会用0填充前置的不足位
    	3、没有必要规定整型的宽度,默认宽度即为整型能存放数据最大宽度
    
    '''
    # eg:1
    create table t9(x int(5));
    insert into t9 values(123456); 
    select (x) from t9; # 结果: 123456
    insert into t9 values(2147483648); 
    select (x) from t9; # 结果: 2147483647
    insert into t9 values(10); 
    select (x) from t9; # 结果: 10
    # eg:2
    create table t10(x int(5) unsigned zerofill); # 区域0~4294967295
    insert into t10 values(10); 
    select x from t10; # 结果: 00010
    insert into t10 values(12345678900); 
    select x from t10; # 结果: 4294967295
    
    # 练习
    =========有符号和无符号tinyint==========
    #tinyint默认为有符号
    MariaDB [db1]> create table t1(x tinyint); #默认为有符号,即数字前有正负号
    MariaDB [db1]> desc t1;
    MariaDB [db1]> insert into t1 values
        -> (-129),
        -> (-128),
        -> (127),
        -> (128);
    MariaDB [db1]> select * from t1;
    +------+
    | x    |
    +------+
    | -128 | #-129存成了-128
    | -128 | #有符号,最小值为-128
    |  127 | #有符号,最大值127
    |  127 | #128存成了127
    +------+
    
    
    #设置无符号tinyint
    MariaDB [db1]> create table t2(x tinyint unsigned);
    MariaDB [db1]> insert into t2 values
        -> (-1),
        -> (0),
        -> (255),
        -> (256);
    MariaDB [db1]> select * from t2;
    +------+
    | x    |
    +------+
    |    0 | -1存成了0
    |    0 | #无符号,最小值为0
    |  255 | #无符号,最大值为255
    |  255 | #256存成了255
    +------+
    
    ============有符号和无符号int=============
    #int默认为有符号
    MariaDB [db1]> create table t3(x int); #默认为有符号整数
    MariaDB [db1]> insert into t3 values
        -> (-2147483649),
        -> (-2147483648),
        -> (2147483647),
        -> (2147483648);
    MariaDB [db1]> select * from t3;
    +-------------+
    | x           |
    +-------------+
    | -2147483648 | #-2147483649存成了-2147483648
    | -2147483648 | #有符号,最小值为-2147483648
    |  2147483647 | #有符号,最大值为2147483647
    |  2147483647 | #2147483648存成了2147483647
    +-------------+
    
    
    #设置无符号int
    MariaDB [db1]> create table t4(x int unsigned);
    MariaDB [db1]> insert into t4 values
        -> (-1),
        -> (0),
        -> (4294967295),
        -> (4294967296);
    MariaDB [db1]> select * from t4;
    +------------+
    | x          |
    +------------+
    |          0 | #-1存成了0
    |          0 | #无符号,最小值为0
    | 4294967295 | #无符号,最大值为4294967295
    | 4294967295 | #4294967296存成了4294967295
    +------------+
    
    ==============有符号和无符号bigint=============
    MariaDB [db1]> create table t6(x bigint);
    MariaDB [db1]> insert into t5 values  
        -> (-9223372036854775809),
        -> (-9223372036854775808),
        -> (9223372036854775807),
        -> (9223372036854775808);
    
    MariaDB [db1]> select * from t5;
    +----------------------+
    | x                    |
    +----------------------+
    | -9223372036854775808 |
    | -9223372036854775808 |
    |  9223372036854775807 |
    |  9223372036854775807 |
    +----------------------+
    
    MariaDB [db1]> create table t6(x bigint unsigned);
    MariaDB [db1]> insert into t6 values  
        -> (-1),
        -> (0),
        -> (18446744073709551615),
        -> (18446744073709551616);
    
    MariaDB [db1]> select * from t6;
    +----------------------+
    | x                    |
    +----------------------+
    |                    0 |
    |                    0 |
    | 18446744073709551615 |
    | 18446744073709551615 |
    +----------------------+
    
    ======用zerofill测试整数类型的显示宽度=============
    MariaDB [db1]> create table t7(x int(3) zerofill);
    MariaDB [db1]> insert into t7 values
        -> (1),
        -> (11),
        -> (111),
        -> (1111);
    MariaDB [db1]> select * from t7;
    +------+
    | x    |
    +------+
    |  001 |
    |  011 |
    |  111 |
    | 1111 | #超过宽度限制仍然可以存
    +------+
    
    # 注意:为该类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关,存储范围如下
    

    img

    '''
    int的存储宽度是4个Bytes,即32个bit,即2**32
    无符号最大值为:4294967296-1
    有符号最大值:2147483648-1
    有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完全,所以int类型默认的显示宽度为11是非常合理的
    最后:整形类型,其实没有必要指定显示宽度,使用默认的就ok
    '''
    

    二、浮点型

    浮点类型:float|double

    作用:存储薪资、身高、体重、参数等

    ======================================
    #FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
    
    定义:
            单精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30
    
    有符号:
               -3.402823466E+38 to -1.175494351E-38,
               1.175494351E-38 to 3.402823466E+38
    无符号:
               1.175494351E-38 to 3.402823466E+38
    
    
    精确度: 
               **** 随着小数的增多,精度变得不准确 ****
    
    
    ======================================
    #DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
    
    定义:
               双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30
    
    有符号:
               -1.7976931348623157E+308 to -2.2250738585072014E-308
               2.2250738585072014E-308 to 1.7976931348623157E+308
    
    无符号:
               2.2250738585072014E-308 to 1.7976931348623157E+308
                
    精确度:
               ****随着小数的增多,精度比float要高,但也会变得不准确 ****
    
    ======================================
    decimal[(m[,d])] [unsigned] [zerofill]
    
    定义:
              准确的小数值,m是数字总个数(负号不算),d是小数点后个数。 m最大值为65,d最大值为30。
    
    
    精确度:
               **** 随着小数的增多,精度始终准确 ****
               对于精确数值计算时需要用此类型
               decaimal能够存储精确值的原因在于其内部按照字符串存储。
    
    '''
    宽度:
    限制存储宽度
    (M,D)=>M为位数,D为小数位
    float(255, 30):精度最低,最常用
    double(255, 30):精度高,占位多
    decimal(65, 30):字符串存,全精度
    '''
    # eg:1
    create table t11 (age float(256, 30)); # Display width out of range for column 'age' (max = 255)
    create table t11 (age float(255, 31)); # Too big scale 31 specified for column 'age'. Maximum is 30.
    # eg:2
    create table t12 (x float(255, 30));
    create table t13 (x double(255, 30));
    create table t14 (x decimal(65, 30));
    
    insert into t12 values(1.11111111111111111111);
    insert into t13 values(1.11111111111111111111);
    insert into t14 values(1.11111111111111111111);
    
    select * from t12; # 1.111111164093017600000000000000 => 小数据,精度要求不高, 均采用float来存储 *
    select * from t13; # 1.111111111111111200000000000000
    select * from t14; # 1.111111111111111111110000000000
    
    alter table t14 modify x decimal(10, 5); # 1.11111 => 限制了数据的存储宽度
    
    # 练习
    mysql> create table t1(x float(256,31));
    ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
    mysql> create table t1(x float(256,30));
    ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)
    mysql> create table t1(x float(255,30)); #建表成功
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> create table t2(x double(255,30)); #建表成功
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> create table t3(x decimal(66,31));
    ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.
    mysql> create table t3(x decimal(66,30));
    ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.
    mysql> create table t3(x decimal(65,30)); #建表成功
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> show tables;
    +---------------+
    | Tables_in_db1 |
    +---------------+
    | t1            |
    | t2            |
    | t3            |
    +---------------+
    rows in set (0.00 sec)
    
    
    
    mysql> insert into t1 values(1.1111111111111111111111111111111); #小数点后31个1
    Query OK, 1 row affected (0.01 sec)
    
    mysql> insert into t2 values(1.1111111111111111111111111111111);
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t3 values(1.1111111111111111111111111111111);
    Query OK, 1 row affected, 1 warning (0.01 sec)
    
    mysql> select * from t1; #随着小数的增多,精度开始不准确
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111164093017600000000000000 |
    +----------------------------------+
    row in set (0.00 sec)
    
    mysql> select * from t2; #精度比float要准确点,但随着小数的增多,同样变得不准确
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111200000000000000 |
    +----------------------------------+
    row in set (0.00 sec)
    
    mysql> select * from t3; #精度始终准确,d为30,于是只留了30位小数
    +----------------------------------+
    | x                                |
    +----------------------------------+
    | 1.111111111111111111111111111111 |
    +----------------------------------+
    row in set (0.00 sec)
    
    

    三、字符类型

    官网:https://dev.mysql.com/doc/refman/5.7/en/char.html
    注意:char和varchar括号内的参数指的都是字符的长度

    #char类型:定长,简单粗暴,浪费空间,存取速度快
        字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节)
        存储:
            存储char类型的值时,会往右填充空格来满足长度
            例如:指定长度为10,存>10个字符则报错,存<10个字符则用空格填充直到凑够10个字符存储
    
        检索:
            在检索或者说查询时,查出的结果会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)
    
    #varchar类型:不定长,精准,节省空间,存取速度慢
        字符长度范围:0-65535(如果大于21845会提示用其他类型 。mysql行最大限制为65535字节,字符编码为utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)
        存储:
            varchar类型存储数据的真实内容,不会用空格填充,如果'ab  ',尾部的空格也会被存起来
            强调:varchar类型会在真实数据前加1-2Bytes的前缀,该前缀用来表示真实数据的bytes字节数(1-2Bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用)
            如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)
            如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535)
        
        检索:
            尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容
    
    # eg:
    create table t15 (x char(4), y varchar(4));
    insert into t15 values("zero", 'owen'); # '' | "" 均可以表示字符
    select x,y from t15; # 正常
    insert into t15 values("yanghuhu", 'lxxVSegon'); # 非安全模式数据丢失,可以存放, 安全模式报错
    select x,y from t15; # 可以正常显示丢失后(不完整)的数据
    insert into t15 values('a', 'b');
    
    # 验证数据所在字符长度
    # 前提: 安全模式下以空白填充字符
    set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";
    # 重启连接
    select char_length(x), char_length(y) from t15; # a占4 b占1
    
    '''重点: 存储数据的方式 **  => 数据库优化
    char: 一定按规定的宽度存放数据, 以规定宽度读取数据, 通常更占空间
    varchar: 首先根据数据长度计算所需宽度, 并在数据开始以数据头方式将宽度信息保存起来, 是一个计算耗时过程, 取先读取宽度信息,以宽度信息为依准读取数据, 通常节省空间
    '''
    8: zero    egon    lxx     yanghuhu
    8: 4zero4egon3lxx8yanghuhu
    注: varchar的数据头占1~2字节
        规定char|varchar宽度均为4,用来存放4个字符的数据, char存取更高效,char占4字符,varchar占5字符,char更省空间
    
    总结: 数据长度相近的数据提倡用char来存放数据, 数据需要高速存取,以空间换时间, 采用char
    

    官方解释:

    #官网:https://dev.mysql.com/doc/refman/5.7/en/char.html
    CHAR 和 VARCHAR 是最常使用的两种字符串类型。
    一般来说
    CHAR(N)用来保存固定长度的字符串,对于 CHAR 类型,N 的范围 为 0 ~ 255
    VARCHAR(N)用来保存变长字符类型,对于 VARCHAR 类型,N 的范围为 0 ~ 65 535
    CHAR(N)和 VARCHAR(N) 中的 N 都代表字符长度,而非字节长度。
    ps:对于 MySQL 4.1 之前的版本,如 MySQL 3.23 和 MySQL 4.0,CHAR(N)和 VARCHAR (N)中的 N 代表字节长度。
    
    #CHAR类型
    对于 CHAR 类型的字符串,MySQL 数据库会自动对存储列的右边进行填充(Right Padded)操作,直到字符串达到指定的长度 N。而在读取该列时,MySQL 数据库会自动将 填充的字符删除。有一种情况例外,那就是显式地将 SQL_MODE 设置为 PAD_CHAR_TO_ FULL_LENGTH,例如:
    mysql> CREATE TABLE t ( a CHAR(10));
          Query OK, 0 rows affected (0.03 sec)
    mysql> INSERT INTO t SELECT 'abc';
          Query OK, 1 row affected (0.03 sec)
          Records: 1  Duplicates: 0  Warnings: 0
    mysql> SELECT a,HEX(a),LENGTH(a) FROM tG;
          *************************** 1. row ***************************
                  a: abc
             HEX(a): 616263
          LENGTH (a): 3
    row in set (0.00 sec)
          mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
          Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT a,HEX(a),LENGTH(a) FROM tG;
          *************************** 1. row ***************************
                  a: abc
             HEX(a): 61626320202020202020
          LENGTH (a): 10
    row in set (0.00 sec)
    
    在上述这个例子中,先创建了一张表 t,a 列的类型为 CHAR(10)。然后通过 INSERT语句插入值“abc”,因为 a 列的类型为 CHAR 型,所以会自动在后面填充空字符串,使其长 度为 10。接下来在通过 SELECT 语句取出数据时会将 a 列右填充的空字符移除,从而得到 值“abc”。通过 LENGTH 函数看到 a 列的字符长度为 3 而非 10。
    接着我们将 SQL_MODE 显式地设置为 PAD_CHAR_TO_FULL_LENGTH。这时再通过 SELECT 语句进行查询时,得到的结果是“abc ”,abc 右边有 7 个填充字符 0x20,并通 过 HEX 函数得到了验证。这次 LENGTH 函数返回的长度为 10。需要注意的是,LENGTH 函数返回的是字节长度,而不是字符长度。对于多字节字符集,CHAR(N)长度的列最多 可占用的字节数为该字符集单字符最大占用字节数 *N。例如,对于 utf8 下,CHAR(10)最 多可能占用 30 个字节。通过对多字节字符串使用 CHAR_LENGTH 函数和 LENGTH 函数, 可以发现两者的不同,示例如下:
    mysql> SET NAMES gbk;
         Query OK, 0 rows affected (0.03 sec)
    mysql> SELECT @a:='MySQL 技术内幕 '; Query OK, 0 rows affected (0.03 sec)
    mysql> SELECT @a,HEX(@a),LENGTH(@a),CHAR_LENGTH(@a)G; ***************************** 1. row **************************** a: MySQL 技术内幕
    HEX(a): 4D7953514CBCBCCAF5C4DAC4BB
    LENGTH (a): 13
    CHAR_LENGTH(a): 9
    row in set (0.00 sec)
    
    变 量 @ a 是 g b k 字 符 集 的 字 符 串 类 型 , 值 为 “ M y S Q L 技 术 内 幕 ”, 十 六 进 制 为 0x4D7953514CBCBCCAF5C4DAC4BB,LENGTH 函数返回 13,即该字符串占用 13 字节, 因为 gbk 字符集中的中文字符占用两个字节,因此一共占用 13 字节。CHAR_LENGTH 函数 返回 9,很显然该字符长度为 9。
    
    
    
    #VARCHAR类型
    VARCHAR 类型存储变长字段的字符类型,与 CHAR 类型不同的是,其存储时需要在 前缀长度列表加上实际存储的字符,该字符占用 1 ~ 2 字节的空间。当存储的字符串长度小 于 255 字节时,其需要 1 字节的空间,当大于 255 字节时,需要 2 字节的空间。所以,对 于单字节的 latin1 来说,CHAR(10)和 VARCHAR(10)最大占用的存储空间是不同的, CHAR(10)占用 10 个字节这是毫无疑问的,而 VARCHAR(10)的最大占用空间数是 11 字节,因为其需要 1 字节来存放字符长度。
    -------------------------------------------------
    注意 对于有些多字节的字符集类型,其 CHAR 和 VARCHAR 在存储方法上是一样的,同样 需要为长度列表加上字符串的值。对于 GBK 和 UTF-8 这些字符类型,其有些字符是以 1 字节 存放的,有些字符是按 2 或 3 字节存放的,因此同样需要 1 ~ 2 字节的空间来存储字符的长 度。
    -------------------------------------------------
    虽然 CHAR 和 VARCHAR 的存储方式不太相同,但是对于两个字符串的比较,都只比 较其值,忽略 CHAR 值存在的右填充,即使将 SQL _MODE 设置为 PAD_CHAR_TO_FULL_ LENGTH 也一样,例如:
    mysql> CREATE TABLE t ( a CHAR(10), b VARCHAR(10));
        Query OK, 0 rows affected (0.01 sec)
    mysql> INSERT INTO t SELECT 'a','a';
        Query OK, 1 row affected (0.00 sec)
        Records: 1  Duplicates: 0  Warnings: 0
    mysql> SELECT a=b FROM tG;
        *************************** 1. row ***************************
        a=b: 1
    row in set (0.00 sec)
        mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';
        Query OK, 0 rows affected (0.00 sec)
    mysql> SELECT a=b FROM tG;
        *************************** 1. row ***************************
        a=b: 1
    row in set (0.00 sec)
    
    Value CHAR(4) Storage Required VARCHAR(4) Storage Required
    '' ' ' 4 bytes '' 1 byte
    'ab' 'ab ' 4 bytes 'ab' 3 bytes
    'abcd' 'abcd' 4 bytes 'abcd' 5 bytes
    'abcdefgh' 'abcd' 4 bytes 'abcd' 5 bytes

    小结:

    #InnoDB存储引擎:建议使用VARCHAR类型
    单从数据类型的实现机制去考虑,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。
    
    但对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。
    
    #其他字符串系列(效率:char>varchar>text)
    TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT
    BLOB 系列    TINYBLOB BLOB MEDIUMBLOB LONGBLOB 
    BINARY系列 BINARY VARBINARY
    
    text:text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。
    mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.
    longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.
    

    四、日期类型

    官方:https://dev.mysql.com/doc/refman/5.6/en/datetime.html

    '''类型
    year:yyyy(1901/2155)
    date:yyyy-MM-dd(1000-01-01/9999-12-31)
    time:HH:mm:ss
    datetime:yyyy-MM-dd HH:mm:ss(1000-01-01 00:00:00/9999-12-31 23:59:59)
    timestamp:yyyy-MM-dd HH:mm:ss(1970-01-01 00:00:00/2038-01-19 03:14:07(UTC范围))
    '''
    
    # eg: 1
    create table t16(my_year year, my_date date, my_time time);
    insert into t16 values(); # 三个时间类型的默认值均是null
    insert into t16 values(2156, null, null); # 在时间范围外,不允许插入该数据
    insert into t16 values(1, '2000-01-01 12:00:00', null); # 2001 2000-01-01 null
    insert into t16 values(2019, '2019-01-08', "15-19-30"); # time报格式错误 => 按照时间规定格式存放数据
    
    alter table t16 change my_year myYear year(2); # 时间的宽度修改后还是采用默认宽度 => 不需要关系宽度
    
    
    # eg:2
    create table t17(my_datetime datetime, my_timestamp timestamp);
    insert into t17 values(null, null); # 可以为空, 不能为null,赋值null采用默认值current_timestamp
    insert into t17 values('4000-01-01 12:00:00', '2000-01-01 12:00:00'); # 在各自范围内可以插入对应格式的时间数据
    
    # datetime VS timestamp
    datetime:时间范围,不依赖当前时区,8字节,可以为null
    timestamp:时间范围,依赖当前时区,4字节,有默认值CURRENT_TIMESTAMP
    

    练习:

    ============year===========
    MariaDB [db1]> create table t10(born_year year); #无论year指定何种宽度,最后都默认是year(4)
    MariaDB [db1]> insert into t10 values  
        -> (1900),
        -> (1901),
        -> (2155),
        -> (2156);
    MariaDB [db1]> select * from t10;
    +-----------+
    | born_year |
    +-----------+
    |      0000 |
    |      1901 |
    |      2155 |
    |      0000 |
    +-----------+
    
    
    ============date,time,datetime===========
    MariaDB [db1]> create table t11(d date,t time,dt datetime);
    MariaDB [db1]> desc t11;
    +-------+----------+------+-----+---------+-------+
    | Field | Type     | Null | Key | Default | Extra |
    +-------+----------+------+-----+---------+-------+
    | d     | date     | YES  |     | NULL    |       |
    | t     | time     | YES  |     | NULL    |       |
    | dt    | datetime | YES  |     | NULL    |       |
    +-------+----------+------+-----+---------+-------+
    
    MariaDB [db1]> insert into t11 values(now(),now(),now());
    MariaDB [db1]> select * from t11;
    +------------+----------+---------------------+
    | d          | t        | dt                  |
    +------------+----------+---------------------+
    | 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |
    +------------+----------+---------------------+
    
    
    
    ============timestamp===========
    MariaDB [db1]> create table t12(time timestamp);
    MariaDB [db1]> insert into t12 values();
    MariaDB [db1]> insert into t12 values(null);
    MariaDB [db1]> select * from t12;
    +---------------------+
    | time                |
    +---------------------+
    | 2017-07-25 16:29:17 |
    | 2017-07-25 16:30:01 |
    +---------------------+
    
    
    
    ============注意啦,注意啦,注意啦===========
    1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入
    2. 插入年份时,尽量使用4位值
    3. 插入两位年份时,<=69,以20开头,比如50,  结果2050      
                    >=70,以19开头,比如71,结果1971
    MariaDB [db1]> create table t12(y year);
    MariaDB [db1]> insert into t12 values  
        -> (50),
        -> (71);
    MariaDB [db1]> select * from t12;
    +------+
    | y    |
    +------+
    | 2050 |
    | 1971 |
    +------+
    
    
    
    ============综合练习===========
    MariaDB [db1]> create table student(
        -> id int,
        -> name varchar(20),
        -> born_year year,
        -> birth date,
        -> class_time time,
        -> reg_time datetime);
    
    MariaDB [db1]> insert into student values
        -> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),
        -> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),
        -> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");
    
    MariaDB [db1]> select * from student;
    +------+------+-----------+------------+------------+---------------------+
    | id   | name | born_year | birth      | class_time | reg_time            |
    +------+------+-----------+------------+------------+---------------------+
    |    1 | alex |      1995 | 1995-11-11 | 11:11:11   | 2017-11-11 11:11:11 |
    |    2 | egon |      1997 | 1997-12-12 | 12:12:12   | 2017-12-12 12:12:12 |
    |    3 | wsb  |      1998 | 1998-01-01 | 13:13:13   | 2017-01-01 13:13:13 |
    +------+------+-----------+------------+------------+---------------------+
    
    

    datetime 与 timestamp区别

    在实际应用的很多场景中,MySQL的这两种日期类型都能够满足我们的需要,存储精度都为秒,但在某些情况下,会展现出他们各自的优劣。下面就来总结一下两种日期类型的区别。
    
    1.DATETIME的日期范围是1001——9999年,TIMESTAMP的时间范围是1970——2038年。
    
    2.DATETIME存储时间与时区无关,TIMESTAMP存储时间与时区有关,显示的值也依赖于时区。在mysql服务器,操作系统以及客户端连接都有时区的设置。
    
    3.DATETIME使用8字节的存储空间,TIMESTAMP的存储空间为4字节。因此,TIMESTAMP比DATETIME的空间利用率更高。
    
    4.DATETIME的默认值为null;TIMESTAMP的字段默认不为空(not null),默认值为当前时间(CURRENT_TIMESTAMP),如果不做特殊处理,并且update语句中没有指定该列的更新值,则默认更新为当前时间。
    
    
    
    mysql> create table t1(x datetime not null default now()); # 需要指定传入空值时默认取当前时间
    Query OK, 0 rows affected (0.01 sec)
    
    mysql> create table t2(x timestamp); # 无需任何设置,在传空值的情况下自动传入当前时间
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> insert into t1 values();
    Query OK, 1 row affected (0.00 sec)
    
    mysql> insert into t2 values();
    Query OK, 1 row affected (0.00 sec)
    
    mysql> select * from t1;
    +---------------------+
    | x                   |
    +---------------------+
    | 2018-07-07 01:26:14 |
    +---------------------+
    row in set (0.00 sec)
    
    mysql> select * from t2;
    +---------------------+
    | x                   |
    +---------------------+
    | 2018-07-07 01:26:17 |
    +---------------------+
    row in set (0.00 sec)
    

    五、枚举与集合

    字段的值只能在给定范围中选择,如单选框,多选框
    enum 单选 只能在给定的范围内选一个值,如性别 sex 男male/女female
    set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)

    枚举类型(enum)
    	An ENUM column can have a maximum of 65,535 distinct elements. (The practical limit is less than 3000.)
    	示例:
    	CREATE TABLE shirts (
    						name VARCHAR(40),
    						size ENUM('x-small', 'small', 'medium', 'large', 'x-large')
        					);
    						INSERT INTO shirts (name, size) VALUES ('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small');
    
      
    
    集合类型(set)
    	A SET column can have a maximum of 64 distinct members.
    	示例:
    		CREATE TABLE myset (col SET('a', 'b', 'c', 'd'));
    		INSERT INTO myset (col) VALUES ('a,d'), ('d,a'), ('a,d,a'), ('a,d,d'), ('d,a,d');
    
    练习
    create table t19(
        sex enum('male','female','wasai') not null default 'wasai', # 枚举
        hobbies set('play','read','music') # 集合
    );
    
    insert into t19 values (null, null); # sex不能设置null
    insert into t19 values (); # wasai null
    insert into t19 (hobbies) values ('play,read'), ('music,play'); # sex采用默认值, 对hobbies字段添加两条记录
    insert into t19 (sex,hobbies) values ('male,female', 'play'); # sex字段只能单选
    
    MariaDB [db1]> create table consumer( 
        -> name varchar(50),
        -> sex enum('male','female'),
        -> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定范围内,多选一
        -> hobby set('play','music','read','study') #在指定范围内,多选多
        -> );
    
    MariaDB [db1]> insert into consumer values  
        -> ('egon','male','vip5','read,study'),
        -> ('alex','female','vip1','girl');
    
    MariaDB [db1]> select * from consumer;
    +------+--------+-------+------------+
    | name | sex    | level | hobby      |
    +------+--------+-------+------------+
    | egon | male   | vip5  | read,study |
    | alex | female | vip1  |            |
    +------+--------+-------+------------+
    

    六、约束条件

    约束条件与数据类型的宽度一样,都是可选参

    作用:用于保证数据的完整型和一致性

    主要分为:

    PRIMARY KEY (PK)    标识该字段为该表的主键,可以唯一的标识记录
    FOREIGN KEY (FK)    标识该字段为该表的外键
    NOT NULL    标识该字段不能为空
    UNIQUE KEY (UK)    标识该字段的值是唯一的
    AUTO_INCREMENT    标识该字段的值自动增长(整数类型,而且为主键)
    DEFAULT    为该字段设置默认值
    
    UNSIGNED 无符号
    ZEROFILL 使用0填充
    
    primary key : 主键,唯一标识,表都会拥有,不设置默认找第一个不空、唯一字段,为表示则创建隐藏字段
    foreign key:外键,
    unique key:唯一性数据,该条字段的值需要保证唯一,不能重复
    auto_increment:自增,只能加给key字段辅助修饰
    注:
    1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值
    2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值
    sex enum('male','female') not null default 'male'
    age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20
    3. 是否是key
    主键 primary key
    外键 foreign key
    索引 (index,unique...)
    

    注:
    1.键是用来讲的io提供存取效率
    2.联合唯一
    ​ create table web (
    ip char(16),
    ​ port int,
    unique(ip,port)
    ​ );
    3.联合主键
    ​ create table web (
    ​ ip char(16),
    ​ port int,
    primary key(ip,port)
    ​ );

    # eg:1
    # 单列唯一
    create table t20 (
    	id int unique
    );
    # 联合唯一
    create table web (
        ip char(16),
        port int,
        unique(ip,port)
    );
    # 如果联合两个字段,两个字段全相同才相同,否则为不同
    insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);
    
    # 注: 
    # 1.表默认都有主键, 且只能拥有一个主键字段(单列主键 | 联合主键)
    # 2.没有设置主键的表, 数据库系统会自上而下将第一个规定为unique not null字段自动提升为primary key主键
    # 3.如果整个表都没有unique not null字段且没有primary key字段, 系统会默认创建一个隐藏字段作为主键
    # 4.通常必须手动指定表的主键, 一般用id字段, 且id字段一般类型为int, 因为int类型可以auto_increment
    
    # eg:2
    create table t21(id int auto_increment); # 自增约束必须添加给key的字段
    # eg:3
    create table t21(id int primary key auto_increment); # 自增要结合key,不赋值插入,数据会自动自增, 且自增的结果一直被记录保留
    # eg:4
    # 联合主键
    create table t22(
    	ip char(16),
        port int,
        primary key(ip,port)
    );
    # 如果联合两个字段,两个字段全相同才相同,否则为不同
    insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);
    

    not null 与 default

    是否可空, null表示空,非字符串

    创建列表时刻指定默认值,当插入数据时如果未主动设置,则自动添加默认

    ==================not null====================
    mysql> create table t1(id int); #id字段默认可以插入空
    mysql> desc t1;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | YES  |     | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    mysql> insert into t1 values(); #可以插入空
    
    
    mysql> create table t2(id int not null); #设置字段id不为空
    mysql> desc t2;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   |     | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    mysql> insert into t2 values(); #不能插入空
    ERROR 1364 (HY000): Field 'id' doesn't have a default value
    
    
    
    ==================default====================
    #设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值
    mysql> create table t3(id int default 1);
    mysql> alter table t3 modify id int not null default 1;
    
    
    
    ==================综合练习====================
    mysql> create table student(
        -> name varchar(20) not null,
        -> age int(3) unsigned not null default 18,
        -> sex enum('male','female') default 'male',
        -> hobby set('play','study','read','music') default 'play,music'
        -> );
    mysql> desc student;
    +-------+------------------------------------+------+-----+------------+-------+
    | Field | Type                               | Null | Key | Default    | Extra |
    +-------+------------------------------------+------+-----+------------+-------+
    | name  | varchar(20)                        | NO   |     | NULL       |       |
    | age   | int(3) unsigned                    | NO   |     | 18         |       |
    | sex   | enum('male','female')              | YES  |     | male       |       |
    | hobby | set('play','study','read','music') | YES  |     | play,music |       |
    +-------+------------------------------------+------+-----+------------+-------+
    mysql> insert into student(name) values('egon');
    mysql> select * from student;
    +------+-----+------+------------+
    | name | age | sex  | hobby      |
    +------+-----+------+------------+
    | egon |  18 | male | play,music |
    +------+-----+------+------------+
    

    unipue

    ============设置唯一约束 UNIQUE===============
    方法一:
    create table department1(
    id int,
    name varchar(20) unique,
    comment varchar(100)
    );
    
    
    方法二:
    create table department2(
    id int,
    name varchar(20),
    comment varchar(100),
    constraint uk_name unique(name)
    );
    
    
    mysql> insert into department1 values(1,'IT','技术');
    Query OK, 1 row affected (0.00 sec)
    mysql> insert into department1 values(1,'IT','技术');
    ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'
    
    not null+unique的化学反应:“
    ”
    mysql> create table t1(id int not null unique);
    Query OK, 0 rows affected (0.02 sec)
    
    mysql> desc t1;
    +-------+---------+------+-----+---------+-------+
    | Field | Type    | Null | Key | Default | Extra |
    +-------+---------+------+-----+---------+-------+
    | id    | int(11) | NO   | PRI | NULL    |       |
    +-------+---------+------+-----+---------+-------+
    row in set (0.00 sec)
    
    
    

    联合唯一

    create table service(
    id int primary key auto_increment,
    name varchar(20),
    host varchar(15) not null,
    port int not null,
    unique(host,port) #联合唯一
    );
    
    mysql> insert into service values
        -> (1,'nginx','192.168.0.10',80),
        -> (2,'haproxy','192.168.0.20',80),
        -> (3,'mysql','192.168.0.30',3306)
        -> ;
    Query OK, 3 rows affected (0.01 sec)
    Records: 3  Duplicates: 0  Warnings: 0
    
    mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80);
    ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'
    
    
    

    primary key.

    从约束角度看primary key字段的值不为空且唯一,那我们直接使用not null+unique不就可以了吗,要它干什么?

    主键primary key是innodb存储引擎组织数据的依据,innodb称之为索引组织表,一张表中必须有且只有一个主键。

    单列主键

    ============单列做主键===============
    #方法一:not null+unique
    create table department1(
    id int not null unique, #主键
    name varchar(20) not null unique,
    comment varchar(100)
    );
    
    mysql> desc department1;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | NO   | UNI | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.01 sec)
    
    #方法二:在某一个字段后用primary key
    create table department2(
    id int primary key, #主键
    name varchar(20),
    comment varchar(100)
    );
    
    mysql> desc department2;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.00 sec)
    
    #方法三:在所有字段后单独定义primary key
    create table department3(
    id int,
    name varchar(20),
    comment varchar(100),
    constraint pk_name primary key(id); #创建主键并为其命名pk_name
    
    mysql> desc department3;
    +---------+--------------+------+-----+---------+-------+
    | Field   | Type         | Null | Key | Default | Extra |
    +---------+--------------+------+-----+---------+-------+
    | id      | int(11)      | NO   | PRI | NULL    |       |
    | name    | varchar(20)  | YES  |     | NULL    |       |
    | comment | varchar(100) | YES  |     | NULL    |       |
    +---------+--------------+------+-----+---------+-------+
    rows in set (0.01 sec)
    

    多列主键

    ==================多列做主键================
    create table service(
    ip varchar(15),
    port char(5),
    service_name varchar(10) not null,
    primary key(ip,port)
    );
    
    
    mysql> desc service;
    +--------------+-------------+------+-----+---------+-------+
    | Field        | Type        | Null | Key | Default | Extra |
    +--------------+-------------+------+-----+---------+-------+
    | ip           | varchar(15) | NO   | PRI | NULL    |       |
    | port         | char(5)     | NO   | PRI | NULL    |       |
    | service_name | varchar(10) | NO   |     | NULL    |       |
    +--------------+-------------+------+-----+---------+-------+
    rows in set (0.00 sec)
    
    mysql> insert into service values
        -> ('172.16.45.10','3306','mysqld'),
        -> ('172.16.45.11','3306','mariadb')
        -> ;
    Query OK, 2 rows affected (0.00 sec)
    Records: 2  Duplicates: 0  Warnings: 0
    
    mysql> insert into service values ('172.16.45.10','3306','nginx');
    ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'
    
    多列主键
    
  • 相关阅读:
    Java静态类
    【Java TCP/IP Socket】深入剖析socket——TCP套接字的生命周期
    【Java TCP/IP Socket】深入剖析socket——TCP通信中由于底层队列填满而造成的死锁问题(含代码)
    【Java TCP/IP Socket】深入剖析socket——数据传输的底层实现
    【Java TCP/IP Socket】基于NIO的TCP通信(含代码)
    【Java TCP/IP Socket】Java NIO Socket VS 标准IO Socket
    【Java TCP/IP Socket】TCP Socket通信中由read返回值造成的的死锁问题(含代码)
    数据结构课后练习题(练习三)7-5 Tree Traversals Again (25 分)
    快速排序详解(lomuto划分快排,hoare划分快排,classic经典快排,dualpivot双轴快排源码)
    Java多线程(一)——线程基础和锁锁锁
  • 原文地址:https://www.cnblogs.com/prodigal/p/10244514.html
Copyright © 2020-2023  润新知