zoukankan      html  css  js  c++  java
  • mysql数据库之数据类型,约束条件

    一、创建表的完成语法

    1.语法
    create table 表名(
        字段名1 类型[(宽度) 约束条件],
        字段名2 类型[(宽度) 约束条件],
        字段名3 类型[(宽度) 约束条件]
    );
    PS:注意事项:
        1. 在同一张表中,字段名不能相同
        2. 宽度和约束条件可选,字段名和类型是必须的
        3. 最后一个字段后不能加逗号!
    2.补充
    (1)宽度指的是对存储数据的限制
        create table userinfo(name char);
        insert into userinfo values('lisi');
    
        1.没有安全模式的数据库版本,能够存放数据但是只会存进去一个j
        2.最新数据库版本直接报错提示无法存储(我装的是5.7 直接出现下面的结果):
        mysql>  insert into userinfo values('lisi');
        ERROR 1406 (22001): Data too long for column 'name' at row 1
    
    (2) 约束条件初识>>> null 与 nut null
        create table t1(id int,name char not null);
        insert into t1 values(1,'j');  # 正常存储
        insert into t1 values(2,null);  # 报错
        
    # 总结 类型与约束条件区别
    # 类型:限制字段必须以什么样的数据类型存储
    # 约束条件:约束条件是在类型之外添加一种额外的限制

    二、字段类型

    2.1 整型
    create table t1(x tinyint);
    insert into t1 values(128),(-129);
    
    输出结果:
    mysql> insert into t1 values(-1),(-129);
    ERROR 1264 (22003): Out of range value for column 'x' at row 2
    
    
    create table t2(x tinyint unsigned);
    insert into t2 values(-1),(256);
    
    输出结果:
    mysql> insert into t2 values(-1),(256);
    ERROR 1264 (22003): Out of range value for column 'x' at row 1
    
    
    create table t3(x int unsigned);
    insert into t3 values(4294967296);
    
    输出结果:
    mysql> insert into t3 values (4283942745);
    Query OK, 1 row affected (0.07 sec)
    
    说明:由于开启了严格模式,导致t1,t2表插入数据失败
    在不开启严格模式下,可以顺利的写数据,但是:
     (1)tinyint:默认情况下是有符号的
        有符号:-128 ~ 127
        无符号:0 ~ 255
     (2)unsigned:表示无符号
    2.1.2 两点补充
    
    (1)Q:类型后面的宽度能否改变字段存储的大小限制?
    A:对于整型来说,数据类型后的宽度并不是存储限制,而是显示限制,所以在创建表时,
    如果字段内采用的是整型类型,完全无需指定显示宽度,默认的是显示宽度,足够
    完整的显示当初存放的数据。
    
        create table t4(x int(8));
        insert into t4 values(1232983640223);
        
        # 显示时,不够8位用0填充,如果超出8位则正常显示
        create table t5(x int(8) unsigned zerofill);
        insert into t5 values(1232983640223);
        
        # create table t6(id int(10) unsigned);
        # create table t7(id int(11));
    
    (2) 严格模式补充
    在上面设置了char,tinyint,存储数据时超过它们的最大存储长度,
    发现数据也能正常存储进去,只是mysql帮我们自动截取了最大长度。
    但在实际情况下,我们应该尽量减少数据库的操作,缓解数据库的压力,
    让它仅仅只管理数据即可,这样的情况下就需要设置安全模式
    
        how variables like "%mode%";  # 查看数据库配置中变量名包含mode的配置参数
        # 修改安全模式
        set session # 只在当前操作界面有效
        set global  # 全局有效
    
        set global sql_mode ='STRICT_TRANS_TABLES'
        # 修改完之后退出当前客户端重新登陆即可
    2.2 浮点型
    分类:FLOAT DOUBLE decimal
    应用场景:身高、体重、利率
    
    字段限制特点: (5,3)前一位表示所有的位数,后一位表示小数个数
    
    三者最大整数位和小数位对比: ----> 单写一个测试博客
    # 存储限制
        float(255,30)  # 表示一共位数为255位,小数位为30位
        double(255,30)  # 表示一共位数为255位,小数位为30位
        decimal(255,30)  # 表示一共位数为65位,小数位为30位
    
    # 精确度验证
        create table t5(x float(255,30));
        create table t6(x double(255,30));
        create table t7(x decimal(65,30));
    
    三者区别:
        精度不同:
            精度由低到高:float --> double --> decimal
    
    代码输出结果:
    (1) float
        mysql> create table t5 (x float(255, 30));
        Query OK, 0 rows affected (0.54 sec)
        
        mysql> insert into t5 values(1.111111111111111111111111111111);
        Query OK, 1 row affected (0.08 sec)
        
        mysql> select * from t5;
        +----------------------------------+
        | x                                |
        +----------------------------------+
        | 1.111111164093017600000000000000 |
        +----------------------------------+
        1 row in set (0.00 sec)
    
    (2) double
        mysql> create table t6 (x double(255, 30));
        Query OK, 0 rows affected (0.32 sec)
        
        mysql>  insert into t6 values(1.111111111111111111111111111111);
        Query OK, 1 row affected (0.06 sec)
        
        mysql> select * from t6;
        +----------------------------------+
        | x                                |
        +----------------------------------+
        | 1.111111111111111200000000000000 |
        +----------------------------------+
        1 row in set (0.00 sec)
    
    (3) decimal
        mysql> create table t7 (x decimal(65, 30));
        Query OK, 0 rows affected (0.30 sec)
        
        mysql>  insert into t7 values(1.111111111111111111111111111111);
        Query OK, 1 row affected (0.06 sec)
        
        mysql> select * from t7;
        +----------------------------------+
        | x                                |
        +----------------------------------+
        | 1.111111111111111111111111111111 |
        +----------------------------------+
        1 row in set (0.06 sec)
    2.3 字符类型
    (1)分类:
        char:定长
        varchar:变长
    (2)作用:姓名、地址、描述类信息
    
        create table t8 (name char(4));  # 超过四个字符报错,不够四个字符空格补全
        create table t9 (name varchar(4));  # 超过四个字符报错,不够四个有几个就存几个
    
        # 验证存储限制
        insert into t8 values('hello');
        insert into t9 values('hello');
    
        # 验证存储长度
        insert into t8 values('a'); #'a    '
        insert into t9 values('a'); #'a'
    
        select * from t8
        select * from t9  # 无法查看真正的结果
    
        select char_length(name) from t8;
        select char_length(name) from t9;  # 仍然无法查看到真正的结果
    
        mysql> select char_length(name) from t8;
        +-------------------+
        | char_length(name) |
        +-------------------+
        |                 1 |
        +-------------------+
        1 row in set (0.37 sec)
    
        mysql> select char_length(name) from t9;
        +-------------------+
        | char_length(name) |
        +-------------------+
        |                 1 |
        +-------------------+
        1 row in set (0.00 sec)
    
    (3) char 和 varchar 的优缺点:
        char:
        缺点:浪费空间
        优点:存取速度都快
    
        varchar:
        缺点:存储速度慢
        优点:节省时间
    2.4 时间类型
    (1) 分类
        date: 2019-05-01
        time: 17:13:32
        datetime: 2019-05-01 17:13:32
        year:2019
    (2) 测试
           create table student(
               id int,
               name char(16),
               yy year,
               birth date,
               study_time time,
               reg_time datetime
            );
    
        insert into student values(1,'lisi','2019','2019-05-13','17:17:32','2019-05-13 17:17:32');
    
        mysql> select * from student;
        +------+------+------+------------+------------+---------------------+
        | id   | name | yy   | birth      | study_time | reg_time            |
        +------+------+------+------------+------------+---------------------+
        |    1 | lisi | 2019 | 2019-05-13 | 17:17:32   | 2019-05-13 17:17:32 |
        +------+------+------+------------+------------+---------------------+
        1 row in set (0.00 sec)
    2.5 枚举与集合类型
    (1)分类:
        枚举enum多选一
        集合set多选多(可以多选一)
    
     (2)测试:
     (a)枚举enum
        create table user(
            id int,
            name char(16),
            gender enum('male','female')
        );
    
        insert into user values(1, 'lisi','male');  # 正确
        # Query OK, 1 row affected (0.06 sec)
    
        insert into user values(2, 'zhangsan','xxx');  # 报错
        # ERROR 1265 (01000): Data truncated for column 'gender' at row 1
    
    
      (b)集合set
        create table teacher(
            id int,
            name char(16),
            hobby set('read','music','sleep','run')
        );
    
        insert into teacher values(1, 'zhangsan','music,sleep');  # 正确
        # Query OK, 1 row affected (0.06 sec)
    
        insert into teacher values(2, 'lisi','sleep');  # 正确 集合可以只选一个
        # Query OK, 1 row affected (0.06 sec)
    
        insert into teacher values(3, 'wangwu','heihei');  # 报错
        # ERROR 1265 (01000): Data truncated for column 'hobby' at row 1

    三、约束条件

    3.1 约束条件
    PRIMARY KEY (PK)    标识该字段为该表的主键,可以唯一的标识记录
    FOREIGN KEY (FK)    标识该字段为该表的外键
    NOT NULL    标识该字段不能为空
    UNIQUE KEY (UK)    标识该字段的值是唯一的
    AUTO_INCREMENT    标识该字段的值自动增长(整数类型,而且为主键)
    DEFAULT    为该字段设置默认值
    
    UNSIGNED 无符号
    ZEROFILL 使用0填充
    3.2 not null + default
    (a)not null:
        create table user(
            id int,
            name char(16)
        );
        insert into user values(1,null)  # 可以修改
        # Query OK, 1 row affected (0.10 sec)
    
        alter table user modify name char(16) not null;
        # 报错:
            ERROR 1138 (22004): Invalid use of NULL value
            查了一下,应该是由于表里有数据,所以不可以改
            mysql> delete from user;
            Query OK, 1 row affected (0.10 sec)
    
        mysql> alter table user modify name char(16) not NULL;
        Query OK, 0 rows affected (0.42 sec)
        Records: 0  Duplicates: 0  Warnings: 0
    
        insert into user(name,id) values(null,2);  # 报错 插入数据可以在表名后面指定插入数据对应的字段
        # ERROR 1048 (23000): Column 'name' cannot be null
    
    (b) default:
        create table student(
            id int,
            name char(16) not null,
            gender enum('male','female','others') default 'male'
        );
        
        insert into student(id,name) values(1,'zhangsan')  # 成功
        # Query OK, 1 row affected (0.09 sec)
    
    3.3 unique
    (a) 单列唯一:某一项值为独一无二的
        create table user1(
            id int unique,
            name char(16)
        );
    
        insert into user1 values(1,'lisi'),(1,'wawu');  # 报错
        # ERROR 1062 (23000): Duplicate entry '1' for key 'id'
    
        insert into user1 values(1,'lisi'),(2,'wawu');  # 成功
        # Query OK, 2 rows affected (0.06 sec)
        # Records: 2  Duplicates: 0  Warnings: 0
    
    (b) 联合唯一:多项值,只要不全相同就ok
        create table server(
            id int,
            ip char(16),
            port int,
            unique (ip,port)
        );
    
        insert into server values(1,'127.0.0.1',8080);
        # Query OK, 1 row affected (0.06 sec)
    
        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);
        # Query OK, 1 row affected (0.06 sec)
    
    3.4 primary key + auto_increment
    (a) 单从约束角度来说 primary key <==> not null unique
        create table t10 (id int primary key);
        desc t10;
    
        +-------+---------+------+-----+---------+-------+
        | Field | Type    | Null | Key | Default | Extra |
        +-------+---------+------+-----+---------+-------+
        | id    | int(11) | NO   | PRI | NULL    |       |
        +-------+---------+------+-----+---------+-------+
        1 row in set (0.00 sec)
    
        insert into t10 values(1),(1);  # 报错
        # ERROR 1062 (23000): Duplicate entry '1' for key 'PRIMARY'
        insert into t10 values(1),(2);
        # Query OK, 2 rows affected (0.06 sec)
        # Records: 2  Duplicates: 0  Warnings: 0
    
    # 除了约束之外,它还是innodb引擎组织数据的依据,提升查询效率
    (b) 强调:
        1.一张表中必须有且只有一个主键,如果你没有设置主键,
        那么会从上到下搜索直到遇到一个非空且唯一的字段自动将其设置为主键
    
        create table t11(
            id int,
            name char(16),
            age int not null unique,
            addr char(16) not null unique
        )engine=innodb;
        desc t11;
    
        mysql> desc t11;
        +-------+----------+------+-----+---------+-------+
        | 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    |       |
        +-------+----------+------+-----+---------+-------+
        4 rows in set (0.01 sec)
    
        2.如果表里面没有指定任何的可以设置为主键的字段,那么innodb会采用自己默认的一个隐藏字段作为主键,隐藏意味着你在查询的时候无法根据这个主键字段加速查询了
        索引:类似于书的目录,没有主键就相当于一页一页翻着查
        3.一张表中通常都应该有一个id字段,并且通常将改id字段作成主键
    
    (c) 联合主键:多个字段联合起来作为表的一个主键,本质还是一个主键
        create table t12(
            ip char(16),
            port int,
            primary key(ip, port)
        );
    
        desc t12;
    
        mysql> desc t12;
        +-------+----------+------+-----+---------+-------+
        | Field | Type     | Null | Key | Default | Extra |
        +-------+----------+------+-----+---------+-------+
        | ip    | char(16) | NO   | PRI | NULL    |       |
        | port  | int(11)  | NO   | PRI | NULL    |       |
        +-------+----------+------+-----+---------+-------+
        2 rows in set (0.01 sec)
    
    (d) 主键id作为数据的编号,每次最好能自动递增
        create table t13(
            id int primary key auto_increment,
            name char(16)
        );
        insert into t13 name values ('jason','jason','jason');
        
        Query OK, 3 rows affected (0.36 sec)
        Records: 3  Duplicates: 0  Warnings: 0
        
        # id字段自动从1开始递增
        # 注意:auto_increment通常都是加在主键上,并且只能给设置为key的字段加
  • 相关阅读:
    设置Jmeter默认中文页面
    spring boot controller设置 @Transactional 不回滚的解决办法
    SpringBoot事务注解@Transactional
    spring boot @Transactional事物处理
    Spring事务管理中@Transactional
    @Transactional 注解的使用和注意
    spring的@Transactional注解详细用法
    【Developer Log】ProGuard扰码可执行JAR包
    使用Jprofiler+jmeter进行JVM性能调优
    SQL中如何使用EXISTS替代IN
  • 原文地址:https://www.cnblogs.com/wangtenghui/p/10940857.html
Copyright © 2011-2022 走看看