• Mysql基础(三):MySQL基础数据类型、完整性约束、sql_mode模式


    2、MySQL基础数据类型、完整性约束、sql_mode模式

    1. MySQL常用数据类型

    • MySQL常用数据类型预览

      1.数字:

      整型:
      tinyinit  int  bigint
      
      小数:
      float:在位数比较短的情况下不精准
      double:在位数比较长的情况下不精准
      decimal:精准、内部原理是以字符串形式去存,如果用小数,则用推荐使用decimal

      2.字符串:

      char(10):
      简单粗暴,浪费空间,存取速度快
      
      varchar(10):
      精准,节省空间,存取速度慢

      3.时间类型:

      最常用:datetime

      4.枚举类型与集合类型

    1. 1 数值类型

    • 整数类型

      1.整数类型:tinyint、smallint、mediumint、int、bigint

      2.插入超出范围的数字会储存为能达到的最大数字,(默认为宽松模式)

      3.作用:存储年龄,等级,id,各种号码等

      1.tinyint[(m)] [unsigned] [zerofill] 
        -- 小整数,数据类型用于保存一些范围的整数数值范围:
        -- 有符号范围:-128 ~ 127
        -- 无符号范围:0 ~ 255
      
      2.int[(m)][unsigned][zerofill]
        -- 整数,数据类型用于保存一些范围的整数数值范围:
        -- 有符号:-2147483648 ~ 2147483647
        -- 无符号:0 ~ 4294967295
      
      3.bigint[(m)][unsigned][zerofill]
        -- 大整数,数据类型用于保存一些范围的整数数值范围:
        -- 有符号:-9223372036854775808 ~ 9223372036854775807
        -- 无符号:0  ~  18446744073709551615

      sql语句示例:

      -- 创建有符号数值类型示例:
      mysql> create table t1(money tinyint); 
      
      -- 创建无符号数值类型示例:unsigned/约束无符号
      mysql> create table t2(id tinyint unsigned);
      
      -- 设置了数据类型,会有一个约束效果,只能表示自己范围内的数
    • 浮点型

      1.浮点型分类:float、double、decimal

      2.作用:存储薪资、身高、温度、体重、体质参数等

      1.FLOAT[(M,D)] [UNSIGNED] [ZEROFILL]
      -- 单精度浮点数(非准确小数值),M是整数部分+小数部分的总个数,D是小数点后个数。
      -- M最大值为255,D最大值为30,例如:float(255,30)/小数点不占位
      -- 有符号:-3.402823466E+38 ~ -1.175494351E-38,
      --        1.175494351E-38 ~ 3.402823466E+38
      -- 无符号:1.175494351E-38 ~ 3.402823466E+38
      -- 精确度:**** 随着小数的增多,精度变得不准确 ****
      
      2.DOUBLE[(M,D)] [UNSIGNED] [ZEROFILL]
      -- 双精度浮点数(非准确小数值),M是整数部分+小数部分的总个数,D是小数点后个数。
      -- M最大值也为255,D最大值也为30
      -- 有符号:-1.7976931348623157E+308 ~ -2.2250738585072014E-308
      --        2.2250738585072014E-308 ~ 1.7976931348623157E+308
      -- 无符号: 2.2250738585072014E-308 ~ 1.7976931348623157E+308          
      -- 精确度:****随着小数的增多,精度比float要高,但也会变得不准确 ****
      
      3.decimal[(M,D)] [unsigned] [zerofill]
      -- 准确的小数值,M是整数部分+小数部分的总个数(负号不算),D是小数点后个数。 
      -- M最大值为65,D最大值为30。比float和double的整数个数少,但是小数位数都是30位
      -- 精确度: **** 随着小数的增多,精度始终准确 ****
      -- decimal能够存储精确值的原因在于其内部按照字符串存储,对于精确数值计算时需要用此类型
      
      -- 总结:
      -- 精度从高到低:decimal、double、float
      -- decimal精度高,但是整数位数少
      -- float和double精度低,但是整数位数多

      sql语句示例:

      -- float示例:
      mysql> create table t3(price float(60,30));
      -- double示例:
      mysql> create table t4(price double(60,30));
      -- decimal示例:
      mysql> create table t5(price decimal(60,30));

    1.2 日期类型

    • 日期类型定义:

      1.类型:DATE,TIME,DATETIME ,IMESTAMP,YEAR

      2.作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等

      1.YEAR:YYYY(范围:1901/2155)2018
      2.DATE:YYYY-MM-DD(范围:1000-01-01/9999-12-31)例:2018-01-01 
      3.TIME:HH:MM:SS(范围:'-838:59:59'/'838:59:59')例:12:09:32
      4.DATETIME:YYYY-MM-DD HH:MM:SS(范围:1000-01-01 00:00:00/9999-12-31 23:59:59    Y)
      5.TIMESTAMP:YYYYMMDD HHMMSS(范围:1970-01-01 00:00:00/2037 年某时)/-- 由于日期马上到了,现在基本不怎么使用了
    • sql语句示例:

      -- year、date、datetime示例:
      mysql> create table t6(d1 year ,d2 date,d3 datetime);
      -- 插入当前时间示例:
      mysql> insert into t6 values(now(),now(),now());

    1.3 字符串类型

    • 字符串类型定义:

      1.类型:char,varchar 内部存储的空间定长不定长

      2.作用:名字,信息等等

      3.注意:char和varchar括号内的参数指的都是字符的长度(5.6版本以前指的是字节,5.6版本以前指的是字符)

      1.char类型:定长,简单粗暴,浪费空间,存取速度快
      -- 字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节)
      -- 存储:存储char类型的值时,会往右填充空格来满足长度
      -- 例如:指定长度为10,存大于10个字符则报错(严格模式下),存小于10个字符则用空格填充直到凑够10个字符存储
      -- 检索:在检索或者查询时,查出的结果会自动删除尾部的空格,如果想看到它补全空格之后的内容,除非我们打开pad_char_to_full_length SQL模式(SET sql_mode = 'strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH';)
      
      2.varchar类型:变长,精准,节省空间,存取速度慢
      -- 字符长度范围:0-65535(如果大于21845会提示用其他类型,mysql行最大限制为65535字节,字符编码为utf-8)
      -- 存储:varchar类型存储数据的真实内容,不会用空格填充,如果'ab  ',尾部的空格也会被存起来
      -- 如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)
      -- 如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535) 
      -- 检索:尾部有空格会保存下来,在检索或者查询时,也会正常显示包含空格在内的内容
      
      -- 总结:
      -- varchar在存数据的时候,会在每个数据前面加上一个头,这个头是1-2个bytes的数据,这个数据指的是后面跟着的这个数据的长度,1bytes能表示2**8=256,两个bytes表示2**16=65536,能表示0-65535的数字,所以存的时候会比较麻烦,导致效率比char慢,取的时候也慢,先拿长度,再取数据。
      -- 优点:节省了一些硬盘空间,一个acsii码的字符用一个bytes长度就能表示,但是也并不一定比char省,看一下官网给出的一个表格对比数据,当存的数据正好是规定的字段长度的时候,varchar反而占用的空间比char要多

      char和varchar对比示例图:

    1.5 枚举和集合类型

    • 枚举和集合类型定义:

      1.enum中文名称叫枚举类型,它的值范围需要在创建表时通过枚举方式显示。enum只允许从值集合中选取单个值,而不能一次取多个值。如性别 sex: 男:male/女:female

      2.set类型可以允许值集合中任意选择1或多个元素进行组合,里面可以包含0-64个成员,对超出范围的内容将不允许注入,而对重复的值将进行自动去重

    • sql语句示例:

      mysql> create table consumer( 
          -> name varchar(50),
          -> sex enum('male','female'),
          -> hobby set('play','music','read','study')  -- 在指定范围内,多选多
          -> );
      
      -- 错误示范:
          create table t5(sex char(16) enum('male','female') default 'male');
      -- 正确示范:
        create table t5(sex enum('male','female') default 'male');
      -- 注意:枚举前面的字段不需要加属性

    2. 完整性约束

    • not null 不为空

      create table t1(name char(10) not null);
    • default 默认值

      create table t1(name char(10) not null default 'zhangsan');
      
      -- 设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值
    • unique 唯一/字段数据不能重复

      create table t1(name char(10) unique);
      
      --设置联合唯一约束示例:
      create table service(
      id int primary key auto_increment,
      name varchar(20),
      host varchar(15) not null,
      port int not null,
      unique(host,port) -- 联合唯一
      );
    • primary key 主键

      -- 建表时指定主键:
      create table t1(id int primary key);
      -- 建表后指定主键:
      constraint pk_name primary key(id);  -- 创建主键并为其命名pk_name
      
      -- 约束效果:不为空且唯一  not null +  unique
    • 联合主键

      mysql> create table t1(
                 ->id int,
                 ->port int,
                 ->primary key(id,port)
                 -> );
      
      -- 和联合唯一是类似的, 看key,两个都写的是pri,两个联合起来作为主键,他们两个作为一个主键,不能再有其他的主键了,也就是在创建表的时候,只能出现一次primary key方法。
    • auto_increment 自增

      create table t1(id int primary key auto_increment); 
      -- 前面必须是primary key
      
      -- 在创建完表后,修改自增字段的起始值
      alter table student auto_increment=3;
      
      -- 创建表时指定自增字段的初始值,注意初始值的设置为表选项,应该放到括号外
      create table student(
          id int primary key auto_increment,
          name varchar(20),
          sex enum('male','female') default 'male'
        )auto_increment=3;
      
      -- 自增的步长相关:
      -- 基于表级别
      SET @@auto_increment_increment=10;
      
      -- 查看当前会话自增的步长:
      show session variables like 'auto_inc%';
      
      -- 基于会话级别/修改会话级别的步长
      set session auto_increment_increment=2
      
      -- 基于全局级别的/修改全局级别的步长(所有会话都生效)
      set global auto_increment_increment=2 
    • foreign key 外键 建立表关系使用的约束条件

      多对一 / 一对多

      foreign key  -- 外键其实就是标明表和表之间的关系
      -- 一对多或为多对一
      -- 两张张表:出版社,书
      
      -- 一个出版社可以出版多本书
      
      create table press(
      id int primary key auto_increment,
      name varchar(20)
      );
      
      create table book(
      id int primary key auto_increment,
      name varchar(20),
      press_id int not null,
      foreign key(press_id) references press(id)
      on delete cascade
      on update cascade
      );

      总结:

      1、先要建立被关联的表才能建立关联表
      2、在插入数据记录的时候,要先在被关联表中插入数据,才能往关联表里面插入数据
      3、更新或者删除数据的时候,都需要考虑关联表和被关联表的关系
      解决方案:
      a.删除表的时候,先删除关联表,再删除被关联表
      b.重建表的时候,在加外键关联的时候加上这两句:on delete cascade 和 on update cascade

      一对一

      -- 两张表:学生表和客户表
      -- 一个学生是一个客户
      
      create table customer(
          -> id int primary key auto_increment,
          -> name varchar(20) not null,
          -> qq varchar(10) not null,
          -> phone char(16) not null
          -> );
      
      create table student(
          -> id int primary key auto_increment,
          -> class_name varchar(20) not null,
          -> customer_id int unique,  -- 该字段一定要是唯一的
          -> foreign key(customer_id) references customer(id) -- 外键的字段一定要保证unique
          -> on delete cascade
          -> on update cascade
          -> );

      多对多

      -- 两张表:作者信息,书
      -- 一个作者可以写多本书,一本书也可以有多个作者,双向的一对多,即多对多
      -- 关联方式:foreign key+一张新的表
      
      create table author(
      id int primary key auto_increment,
      name varchar(20)
      );
      
      
      -- 这张表就存放作者表与书表的关系,即查询二者的关系查这表就可以了
      create table author2book(
      id int not null unique auto_increment,
      author_id int not null,
      book_id int not null,
      constraint fk_author foreign key(author_id) references author(id)
      on delete cascade
      on update cascade,
      constraint fk_book foreign key(book_id) references book(id)
      on delete cascade
      on update cascade,
      primary key(author_id,book_id)
      );

      外键相关操作:

      -- 1.查看外键关系名称
      show create table book;
      
      -- 2.删除外键关系
      alter table book drop foreign key book_ibfk_1(外键名称)
      
      -- 3.创建表完成之后,添加外键
      alter table book add foreign key(pid) references publish(id);
      
      -- 4.创建外键时指定外键名称
      1.create table t1(
          id int,
          pid int,
          constraint fk_name foreign key(pid) references publish(id)
      );
      2.创建表完成之后,后添加外键关系
      alter table book add constraint fk_name foreign key(pid) references 
      3.创建外键时指定外键名称(创建后不能修改外键名称,只能删除后再添加)
      
      -- 5.查看所有外键的信息
      select                                                        REFERENCED_TABLE_SCHEMA,REFERENCED_TABLE_NAME,REFERENCED_COLUMN_NAME,table_name,CONSTRAINT_NAME from information_schema.key_column_usage;

      外键约束之级联

      级联的三种模式:级联中有一种模式是级联模式
      外键约束的三种约束方式:
      
      -- 模式一: 
      district:严格约束(默认的):父表不能删除或者更新已经被子表数据引用的记录
      
      -- 模式二:
      cascade:级联模式:父表的操作,对应的子表关联的数据也跟着操作 。
      constraint fk_t1_publish foreign key(pid) references publish(id) on delete cascade on update cascade;
      
      -- 模式三:
      set null:置空模式:父表操作之后,子表对应的数据(外键字段)也跟着被置空,被关联字段删除时,关联它的数据会置成null
      
      1.通常的一个合理的约束模式是:删除的时候子表置空;更新的时候子表级联。
      2.指定模式的语法:foreign key(外键字段)references 父表(主键字段)on delete 模式 on update 模式;
      3.外键虽然很强大,能够进行各种约束,但是外键的约束降低了数据的可控性和可拓展性。通常在实际开发时,很少使用外键来约束。

    3. MySQL的sql_mode模式说明以及设置

    • sql_mode简述:

      sql_mode是个很容易被忽视的变量,默认值是空值,在这种设置下是可以允许一些非法操作的,在生产环境必须将这个值设置为严格模式,所以开发、测试环境的数据库也必须要设置,这样在开发测试阶段就可以发现问题.

    • MySQL的sql_mode的四种模式

      ANSI模式/宽松模式

      对插入数据进行校验,如果不符合定义类型或长度,对数据类型调整或截断保存,报warning警告

      STRICT_TRANS_TABLES模式/严格模式

      进行数据的严格校验,错误数据不能插入,报error错误。只对支持事务的表有效。

      STRICT_ALL_TABLES模式/严格模式

      进行数据的严格校验,错误数据不能插入,报error错误。对所有表都有效。

      TRADITIONAL模式/严格模式

      当向mysql数据库插入数据时,进行数据的严格校验,保证错误数据不能插入,报error错误。用于事务时,会进行事务的回滚。
    • 严格模式设置和修改

      方式一:当前会话配置

      -- 查看当前会话sql_mode模式
      select @@sql_mode
      
      -- 设置当前会话sql_mode模式
      set sql_mode = '修改后的值';
      set session sql_mode='修改后的值';
      例如:set session sql_mode='STRICT_TRANS_TABLES';
      
      -- 改为严格模式,session可以不用写   
      -- 此方法只在当前会话中生效,关闭当前会话就不生效了。

      方式二:全局配置/当前服务

      -- 查看全局sql_mode模式
      select @@global.sql_mode
      -- 设置全局sql_mode模式
      set global sql_mode = '修改后的值'。
      
      -- 此方法在当前服务中生效,重新MySQL服务后失效

      方法三:全局配置/永久

      sql_mode = STRICT_TRANS_TABLES
      -- 在mysql配置文件my.cnf文件(windows系统是my.ini文件),添加sql_mode
      
      -- 示例如下:
      [mysqld]          sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES
      
      -- ONLY_FULL_GROUP_BY:限制必须是分组依据,或统计结果
      -- STRICT_TRANS_TABLES:严格模式
  • 相关阅读:
    lnmp环境搭建
    Git常用命令
    博客园写随笔环境搭建
    Win常用软件
    Docker环境搭建
    ESP-8266 RTOS 环境搭建
    查看Linux信息
    博客园markdown语法
    Java后台技术(TDDL)
    Java后台技术(Dubbo入门)
  • 原文地址:https://www.cnblogs.com/qiu-hua/p/12486668.html
Copyright © 2020-2023  润新知