zoukankan      html  css  js  c++  java
  • 数据类型、约束条件

    前言(创建表的完整语法)

      语法:
      create table 表名(
        字段名1    类型    (宽度)    约束条件,
        字段名2    类型    (宽度)    约束条件,​​
        ​字段名3    类型    (宽度)    约束条件
      ​​)​
    ​
      注意:
      1. 在同一张表中,字段名不能相同
      2. 宽度和约束条件可选,字段名和类型必须有
      3. 最后一个字段不能加逗号!​​​​

      补充:

      补充:
      1. 宽度指的是对存储数据的限制​​
      create table userinfo(name char);
      insert into userinfo values('jason');
      '''
      1. 没有安全模式的数据库版本,是可以存放数据 但是只会存进去一个j (char默认存储一个字符)
      2. 最新数据库版本直接报错,提示无法存储:​​Data too long for column 'name' at row 1
      '''​​​​
    
      2. 约束条件初识>>>null 和not null
      create table t1(id int, name char not null);​​​​
      insert into t1 values(1, 'j')​;  # 正常存储
      insert into t1 values(2, null)​;  # 报错

      总结(约束和类型的区别):

      类型:限制字段必须以什么样的数据类型存储
      约束条件:是在类型之外,添加一种额外的限制​​

    数据类型

      建表的时候,字段都有对应的数据类型
      整型、浮点型、字符类型、日期类型、枚举和集合​

      整型

      分类:TINYINT、SMALLINT、MEDIUMINT、INT、BIGINT
      作用:存储年龄,等级,id,各种号码等​​​

      类型存储范围

      

      验证整型字段有无符号及范围(unsigned取消范围限制)

      
    create table t1(x tinyint); 
    insert into t1 values(128),(-129);
    ​select * from t1;
    '''执行结果:
    +------+
    | x    |
    +------+
    |  127 |
    | -128 |
    +------+
    '''​​
    
    create table t2(x tinyint unsigned);
    insert into t2 values(-1),(256);  
    ​select * from t2;
    '''执行结果​
    +------+
    | x    |
    +------+
    |    0 |
    |  255 |
    +------+
    '''
    
    create table t3(x int unsigned);
    insert into t3 values(4294967296);
    select * from t3;
    '''执行结果:​
    +------------+
    | x          |
    +------------+
    | 4294967295 |
    | 4294967295 |
    +------------+
    ​'''
    验证整型字段有无符号及范围

      疑问:类型后面的宽度能否改变字段存储的大小限制

      
    create table t4(x int(8));
    insert into t4 values(4294967296123);
    select * from t4;
    '''执行结果:​
    +------------+
    | x          |
    +------------+
    | 2147483647 |
    +------------+
    ​'''# 显示时,不够8位用0填充,如果超出8位则正常显示
    create table t5(x int(8) unsigned zerofill);
    insert into t5 values(123);
    select * from t5;
    '''执行结果:​
    +----------+
    | x        |
    +----------+
    | 00000123 |
    +----------+
    '''​
    ​
    # create table t6(id int(10) unsigned);
    # create table t7(id int(11));
    View Code

      强调

      对于整型来说,数据类型后的宽度并不是存储限制,而是显示限制,
      ​所以在创建表时,如果字段采用的是整型类型,完全无需指定显示宽度, 
      ​默认的显示宽度,足够显示完整当初存放的数据

      严格模式补充

      我们刚刚在上面设置了char,tinyint,存储数据时超过它们的最大存储长度,
    ​  发现数据也能正常存储进去,只是mysql帮我们自动截取了最大长度。
    ​  但在实际情况下,我们应该尽量减少数据库的操作,缓解数据库的压力,
      ​让它仅仅只管理数据即可,这样的情况下就需要设置安全模式
      
    show variables like "%mode%";  # 查看数据库配置中变量名包含mode的配置参数
    +----------------------------------------+--------------------------------------+
    | Variable_name              | Value                                                                  |
    +----------------------------------------+--------------------------------------+
    | binlogging_impossible_mode | IGNORE_ERROR                          |
    | block_encryption_mode            | aes-128-ecb                                  |
    | gtid_mode                                        | OFF                                                    |
    | innodb_autoinc_lock_mode    | 1                                                         |
    | innodb_strict_mode                    | OFF                                                    |
    | pseudo_slave_mode                   | OFF                                                    |
    | slave_exec_mode                         | STRICT                                              |
    | sql_mode                                          | NO_ENGINE_SUBSTITUTION |
    +----------------------------+---------------------------------------------------+# 修改安全模式
    set session # 只在当前操作界面有效
    set global  # 全局有效
    ​
    set global sql_mode ='STRICT_TRANS_TABLES';
    # 修改完之后退出当前客户端重新登陆即可
    sql语句示例

      浮点型

      分类:FLOAT、DOUBLE、decimal
      应用场景:身高、体重。薪资​​

      存储限制

      字段限制特点(5,3)
      ​前一位表示所有的位数,后一位表示小数个数​​
      ​float(255,30)
      double(255,30)
      decimal(255,30)

      精度验证

      
    create table t9(x float(255,30));
    create table t10(x double(255,30));
    create table t11(x decimal(65,30));
    ​
    insert into t9 values(1.111111111111111111111111111111);
    insert into t10 values(1.111111111111111111111111111111);
    insert into t11 values(1.111111111111111111111111111111);
    ​
    select * from t9;
    +---------------------------------------------------+
    |      x                                                            |
    +---------------------------------------------------+
    | 1.111111164093017600000000000000  |
    +---------------------------------------------------+
    ​​ select * from t10;
    ​+---------------------------------------------------+
    |      x                                                            |
    +---------------------------------------------------+
    | 1.111111111111111111111111111111  |
    +---------------------------------------------------+
    ​​select * from t11;
    ​+---------------------------------------------------+
    |      x                                                            |
    +---------------------------------------------------+
    | 1.111111111111111200000000000000         |
    +---------------------------------------------------+​
    View Code

      字符类型

      分类:char(定长)、varchar(变长)
      作用:姓名,地址,描述类信息​​
      
    create table t12(name char(4));  # 超出四个字符报错,不够四个字符空格补全
    create table t13(name varchar(4));  # 超出四个字符报错,不够四个有几个就存几个
    # 验证存储限制
    insert into t12 values('hello');
    insert into t13 values('hello');
    ​
    select的结果一样:
     select * from t12;
    +------+
    | name|
    +------+
    | hell   |
    +------+
     select * from t13;
    +------+
    | name|
    +------+
    | hell   |
    +------+# 验证存储长度
    insert into t12 values('a');  # 'a    ' 空格补充的
    insert into t13 values('a');  # 'a'
    select * from t12
    +---------------------------+
    | char_length(name)        |
    +---------------------------+
    |                 1                  |
    +------------------------ --+
    ​
    select * from t13  # 无法查看真正的结果,看起来跟char的结果一样
    ​
    select char_length(name) from t12
    select char_length(name) from t13  # 仍然无法查看到真正的结果,看起来跟char的结果一样
    """首先应该肯定的是在硬盘上存的绝对是真正的数据,
    ​但显示的时候mysql会自动将末尾的空格去掉"""# 如果不想让mysql帮你做自动去除末尾空格的操作,需要再添加一个模式
    set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";
    ​
    # 退出客户端重新登陆
    select char_length(x) from t12; #4
    select char_length(y) from t13; #1
    '''针对char类型,mysql在存储时会将数据用空格补全存放到硬盘中。
    ​但是会在读出结果的时候自动取掉末尾的空格
    '''
    sql语句验证

      char 和varchar的区别

      
    name char(5)
    # 缺点:浪费空间
    # 优点:存取速度都快
    egon alex lxx  jxx  txx  
    ​
    name varchar(5)
    # 缺点:存取速度慢
    # 优点:节省空间
    1bytes+egon 1bytes+alex 1bytes+lxx  1bytes+jxx  1bytes+txx
    View Code

      时间类型

      分类:
      data:2019-05-01
      time:11:11:11
      Datetime:2019-01-02 11:11:11
      Year:2019​​​​
    create table student(
        id int,
      name char(16),
      born_year year,
      birth date,
      study_time time,
      reg_time datetime
    );
    ​
    insert into student values(1,'egon','2019','2019-05-09','11:11:00','2019-11-11 11:11:11');
    select * from student;
    +------+--------+--------------+-------------+----------------+---------------------------------+
    | id      | name | born_year | birth          | study_time  | reg_time                                 |
    +------+--------+--------------+-------------+----------------+---------------------------------+
    |    1     | egon  |      2019   | 2019-05-09  | 11:11:00        | 2019-11-11 11:11:11          |
    +------+--------+--------------+-------------+----------------+---------------------------------+
    ​​
    sql语句演示

      枚举和集合类型

      分类:
          枚举enum多选一
          集合set多选多
      
    create table user(
        id int,
      name char(16),
      gender enum('male','female','others')
    );
    ​
    insert into user values(1,'jason','xxx');  
    ​# 报错  ERROR 1265 (01000): Data truncated for column 'gender' at row 1
    insert into user values(2,'egon','female')  # 正确!​
    ​
    ​
    create table teacher(
        id int,
      name char(16),
      gender enum('male','female','others'),
      hobby set('read','sleep','sanna','dbj')
    );
    ​
    insert into teacher values(1,'egon', 'male', 'read,sleep,dbj')  # 集合也可以只存一个
    select *from teacher;
    '''执行结果:
    +------+---------+-----------+--------------------+
    | id      | name   | gender   | hobby                 |
    +------+---------+-----------+--------------------+
    |    1     | egon    | male       | read,sleep,dbj |
    +------+---------+-----------+--------------------+
    ​​​'''
    sql语句演示

    约束条件

    PRIMARY KEY (PK)    标识该字段为该表的主键,可以唯一的标识记录
    FOREIGN KEY (FK)    标识该字段为该表的外键
    NOT NULL            标识该字段不能为空
    UNIQUE KEY (UK)     标识该字段的值是唯一的
    AUTO_INCREMENT      标识该字段的值自动增长(整数类型,而且为主键)
    DEFAULT             为该字段设置默认值
    UNSIGNED            无符号
    ZEROFILL            使用0填充

      not null+default

      
    create table user2(
        id int,
      name char(16)
    );
    ​
    insert into user2 values(1,null)  # 可以修改
    ​select * from user2;
    +------+--------+
    | id      | name |
    +------+--------+
    |    1    | NULL  |
    +------+--------+
    ​
    alter table user modify name char(16) not null;​
    select * from user2;
    +------+--------+
    | id      | name |
    +------+--------+
    |    1    |          |
    +------+--------+
    ​
    ​​insert into user(name,id) values(null,2);  
    ​# 报错 插入数据可以在表名后面指定插入数据对应的字段
    ERROR 1048 (23000): Column 'name' cannot be null​
    ​
    create table student(
        id int,
      name char(16) not null,
      gender enum('male','female','others') default 'male'
    )
    ​
    insert into student(id,name) values(1,'jason')  # 成功
    select id, name, gender from student2 where id=1;
    +------+---------+----------+
    | id      | name   | gender   |
    +------+---------+----------+
    |    1     | jason   | male     |
    +------+---------+----------+
    ​
    ​​
    View Code

      unique

    # 单列唯一
    ​create table user1(
        id int unique, 
      name char(16)
    );
    insert into user1 values(1,'jason'),(1,'egon');  # 成功
    ​select * from users;
    +------+----------+
    | id      | name    |
    +------+----------+
    |    1     | jason    |
    |    2     | tank      |
    +------+----------+
    insert into user1 values(1,'jason'),(2,'egon');  # 报错
    ​ERROR 1062 (23000): Duplicate entry '1' for key 'id'# 多列唯一
    ​​create table server(
        id int,
      ip char(16),
      port int,
      unique(ip,port)
    )
    insert into server values(1,'127.0.0.1',8080);
    insert into server values(2,'127.0.0.1',8080);  # 报错(原因是联合唯一)
    ERROR 1062 (23000): Duplicate entry '127.0.0.1-8080' for key 'ip'​
    insert into server values(1,'127.0.0.1',8081);  # 不报错​
    View Code

      primary key

    # 单从约束角度来说primary key就等价于not null 加unique
    (补充: 除了约束之外,它还是innodb引擎组织数据的依据,提升查询效率)​
    create table t20(id int primary key);​
    desc t20;​
    +-------+---------+------+-----+------------+-------+
    | Field  | Type    | Null | Key | Default   | Extra |
    +-------+---------+------+-----+------------+-------+
    | id        | int(11) | NO   | PRI | NULL       |            |
    +-------+---------+------+-----+------------+-------+
    ​insert into t20 values(1),(2);  # 没报错
    insert into t20 values(1),(2);​  # 报错
    ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'​
    ​
    View Code

      primary key 注意事项

    1.  一张表中必须有且只有一个主键,如果没有设置主键,
    ​那么会从上往下搜索直到与发哦一个非空且唯一的字段,自动将其设置为主键
    create table t21(
        id int,
      name char(16),
      age int not null unique,
      addr char(16) not null unique
    )
    ​desc t21;
    +----------+--------------+------+-----+-----------+-------+
    | Field      | Type            | Null | Key | Default | Extra |
    +----------+--------------+------+-----+-----------+-------+
    | id            | int(11)         | YES  |          | NULL     |            |
    | name    | char(16)      | YES  |         | NULL      |            |
    | age         | int(11)         | NO   | PRI | NULL      |            |
    | addr       | char(16)     | NO   | UNI | NULL     |            |
    +----------+--------------+------+-----+-----------+-------+
    ​
    ​2.  如果表里面没有指定任何的可以设置为主键的字段,
    ​那么innodb会采用自己默认的一个隐藏字段作为主键,
    隐藏意味着在查询的时候无法根据这个主键字段加速查询了​
    ​
    索引:类似于书的目录,没有主键就相当于一页一页翻着查
    
    3.  一张表中通常都应该有一个id字段,并且​​​通常将该id字段作成 主键
    View Code

      联合主键

    #  多个字段联合起来作为表的一个主键,本质还是一个主键
    ​ create table server2(ip int, port char(16), addr char(16), primary key(ip, port));
    desc server2;
    +-------+-------------+------+------+-----------+-------+
    | Field | Type           | Null | Key  | Default  | Extra |
    +-------+-------------+------+------+-----------+-------+
    | ip       | int(11)        | NO   | PRI  | 0               |            |
    | port  | char(16)     | NO   | PRI  |                  |            |
    | addr  | char(16   ) | YES  |          | NULL      |            |
    +-------+--------------+------+-----+-----------+-------+
    View Code

      auto_increment

    #  主键作为数据的编号,每次最好能自动递增
     create table t40(id int auto_increment primary key, name char(16));
    ​​insert into t41(name) values('jason'),('tank');
    ​select * from t41;
    +----+----------+
    | id   | name    |
    +----+----------+
    |  1   | jason     |
    |  2   | tank       |
    +----+----------+
    # id字段自动从1开始递增
    # 注意:auto_increment通常都是加在主键上,并且只能给设置为key的字段加
    View Code

      auto_increment 补充

    delete from t41;
    强调:上边这条命令确实可以将表里的所有记录都删除,
    但是不会讲id充值为0,
    所以该条命令​​​根本是不是用来清空表的
    ​delete是用来删除表中某些符合条件的记录 例如:delete from t41 where id > 10;
    
    如果要清空表,使用  truncate​​ t41;
    作用:将整张表初始化,id重新开始从0记录​
  • 相关阅读:
    代理模式
    面向对象设计原则
    砝码破碎
    阿里EasyExcel使用
    IBM的OpenJ9
    java反射 (复习)
    DecimalFormat保留小数
    Object类
    SQLMAP用法
    SQL盲注之时间注入
  • 原文地址:https://www.cnblogs.com/buzaiyicheng/p/11379918.html
Copyright © 2011-2022 走看看