day41-- numeric types, integrity constraints

day41

Numeric types

Integer type

There are set of symbols
mysql> create table t1(id tinyint); # 默认有符号,即数字前有正负号
Set unsigned
mysql> create table t1(id tinyint unsigned);
zerofill usage

If the width is less than the set width (width of 4 herein), is automatically filled 0, it is noted that this is only the final displayed result is actually stored in MySQL or 1

Zerofill test with the display width of integer type

mysql> create table t7(x int(3) zerofill);
    mysql> insert into t7 values
        -> (1),
        -> (11),
        -> (111),
        -> (1111);
    mysql> select * from t7;
    +------+
    | x    |
    +------+
    |  001 |
    |  011 |
    |  111 |
    | 1111 | #超过宽度限制仍然可以存
    +------+

Note: For integer, the width of the latter type of data memory length is not limited, but the display limit, if: int (8), then the display is less than 8 bits is padded with zeros, the normal display is enough to 8, by zerofill test, a length of 4 bytes of memory length is int. The default display width is the maximum length of data that can be stored, for example: int unsigned type, then the default display width is int (10), signed is int (11), because more than one symbol, so we do not necessary to specify the type of integer data, no need to specify the width, because the default can be fully displayed your store raw data

Int memory width is 4 Bytes, i.e., 32 bit, i.e. 2 ** 32

Unsigned maximum value is: 4294967296-1

Signed maximum: 2147483648-1

Signed and unsigned largest digital display width required is 10, while the minimum for a signed 11 will need to show complete, so the default display type int width of 11 is very reasonable

  Finally: plastic types, in fact, not necessary to specify the display width, using the default on ok

MySQL's mode

Charles sql_mode

select @@sql_mode
select @@global.sql_mode

The following sql_mode used to solve these types of problems

  • By setting sql mode, you can perform different stringent data validation, data preparation of effective protection.
  • By setting sql model is loose mode to ensure the most sql sql-standard syntax, such applications when migrating between different databases, you do not need to make huge changes to business sql.
  • Before data migration between different databases, so that the data can be provided by the SQL Mode MySQL more easily migrate to the target database.

Common values ​​are sql_mode

Brief details: https: //www.cnblogs.com/clschao/articles/9962347.html

NO_ENGINE_SUBSTITUTION
宽松版——如果需要的存储引擎被禁用或未编译,那么抛出错误。不设置此值时,用默认的存储引擎替代,并抛出一个异常

STRICT_TRANS_TABLES
严格版——在该模式下,如果一个值不能插入到一个事务表中,则中断当前的操作,对非事务表不做限制
 NO_ZERO_IN_DATE:
    在严格模式下,不允许日期和月份为零

Note : MySQL5.6 and MySQL5.7 sql_mode default mode parameter is not the same

  • 5.6 is NO_ENGINE_SUBSTITUTION, in fact, represent a null value is equivalent to no mode setting, it can be understood as relaxed mode
  • mode 5.7 is STRICT_TRANS_TABLES, which is strict mode.
    如果设置的是宽松模式,那么我们在插入数据的时候,即便是给了一个错误的数据,也可能会被接受,并且不报错,例如:我在创建一个表时,该表中有一个字段为name,给name设置的字段类型时char(10),如果我在插入数据的时候,其中name这个字段对应的有一条数据的长度超过了10,例如'1234567890abc',超过了设定的字段长度10,那么不会报错,并且取前十个字符存上,也就是说你这个数据被存为了'1234567890',而'abc'就没有了,但是我们知道,我们给的这条数据是错误的,因为超过了字段长度,但是并没有报错,并且mysql自行处理并接受了,这就是宽松模式的效果,其实在开发、测试、生产等环境中,我们应该采用的是严格模式,出现这种错误,应该报错才对,所以MySQL5.7版本就将sql_mode默认值改为了严格模式,并且我们即便是用的MySQL5.6,也应该自行将其改为严格模式,而你记着,MySQL等等的这些数据库,都是想把关于数据的所有操作都自己包揽下来,包括数据的校验,其实好多时候,我们应该在自己开发的项目程序级别将这些校验给做了,虽然写项目的时候麻烦了一些步骤,但是这样做之后,我们在进行数据库迁移或者在项目的迁移时,就会方便很多,这个看你们自行来衡量。mysql除了数据校验之外,你慢慢的学习过程中会发现,它能够做的事情还有很多很多,将你程序中做的好多事情都包揽了。

There may be a problem later changed to strict mode

    若设置模式中包含了NO_ZERO_DATE,那么MySQL数据库不允许插入零日期,插入零日期会抛出错误而不是警告。例如表中含字段TIMESTAMP列(如果未声明为NULL或显示DEFAULT子句)将自动分配DEFAULT '0000-00-00 00:00:00'(零时间戳),也或者是本测试的表day列默认允许插入零日期 '0000-00-00' COMMENT '日期';这些显然是不满足sql_mode中的NO_ZERO_DATE而报错。

And a mode setting change method

  • method one

    先执行select @@sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set sql_mode = '修改后的值'或者set session sql_mode='修改后的值';,例如:set session sql_mode='STRICT_TRANS_TABLES';改为严格模式
    
            此方法只在当前会话中生效,关闭当前会话就不生效了。
  • Method Two

    先执行select @@global.sql_mode,复制查询出来的值并将其中的NO_ZERO_IN_DATE,NO_ZERO_DATE删除,然后执行set global sql_mode = '修改后的值'。
    
            此方法在当前服务中生效,重新启动MySQL服务后失效
  • Method Three

    在mysql的安装目录下,或my.cnf文件(windows系统是my.ini文件),新增 sql_mode = ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER,NO_ENGINE_SUBSTITUTION,
    添加my.cnf如下:
            [mysqld] sql_mode=ONLY_FULL_GROUP_BY,STRICT_TRANS_TABLES,ERROR_FOR_DIVISION_BY_ZERO,NO_AUTO_CREATE_USER
    
            然后重启mysql。
        此方法永久生效.当然生产环境上是禁止重启MySQL服务的,所以采用方式二加方式三来解决线上的问题,那么即便是有一天真的重启了MySQL服务,也会永久生效了。

Float

Note: float only accurate 8, from left to right from the start integer

测试
mysql> create table t3(id float(60,30));
Query OK, 0 rows affected (1.70 sec)

mysql> create table t4(id double(60,30));
Query OK, 0 rows affected (0.88 sec)

mysql> create table t5(id decimal(60,30));
Query OK, 0 rows affected (0.96 sec)

mysql> insert into t3 values(1.1111111111111111111111);
Query OK, 1 row affected (0.13 sec)

mysql> insert into t4 values(1.1111111111111111111111);
Query OK, 1 row affected (0.22 sec)

mysql> insert into t5 values(1.1111111111111111111111);
Query OK, 1 row affected (0.09 sec)

mysql> select * from t3;
mysql> select * from t4;
mysql> select * from t5;

Bit type

Can be stored in binary or hexadecimal

For more details, see: https: //www.cnblogs.com/clschao/articles/9959559.html

Date Type

  • year
YYYY(范围:1901~2155) ——2018
  • date
YYYY-MM-DD (范围:1000-01-01~9999-12-31) ——2018-01-01
  • time
HH:MM:SS ——12:09:32
  • datetime
YYYY-MM-DD HH:MM:SS(范围:1000-01-01 00:00:00~9999-12-31 23:59:59  )——2018-01-01 12:09:32

test

mysql> create table t6(d1 year ,d2 date,d3 datetime);
Query OK, 0 rows affected (1.75 sec)

mysql> insert into t6 values(now(),now(),now());
Query OK, 1 row affected, 1 warning (0.12 sec)

mysql> select * from t6;

String type

Details: https: //www.cnblogs.com/clschao/articles/9959559.html

For char type, mysql when the stored data is less than a predetermined length will be used later (right complement) is added in the form of a space completion, and then stored in the hard disk, but it is automatically removed to use when reading or you fill the whole space content, because these spaces are not our own data store, so for us users is useless.

performance comparison char and varchar

以char(5)和varchar(5)来比较,加入我要存三个人名:sb,ssb1,ssbb2
    char:
      优点:简单粗暴,不管你是多长的数据,我就按照规定的长度来存,5个5个的存,三个人名就会类似这种存储:sb ssb1 ssbb2,中间是空格补全,取数据的时候5个5个的取,简单粗暴速度快
      缺点:貌似浪费空间,并且我们将来存储的数据的长度可能会参差不齐

    varchar:
      varchar类型不定长存储数据,更为精简和节省空间
      例如存上面三个人名的时候类似于是这样的:sbssb1ssbb2,连着的,如果这样存,请问这三个人名你还怎么取出来,你知道取多长能取出第一个吗?(超哥,我能看出来啊,那我只想说:滚犊子!)
      不知道从哪开始从哪结束,遇到这样的问题,你会想到怎么解决呢?还记的吗?想想?socket?tcp?struct?把数据长度作为消息头。

      
      所以,varchar在存数据的时候,会在每个数据前面加上一个头,这个头是1-2个bytes的数据,这个数据指的是后面跟着的这个数据的长度,1bytes能表示2**8=256,两个bytes表示2**16=65536,能表示0-65535的数字,所以varchar在存储的时候是这样的:1bytes+sb+1bytes+ssb1+1bytes+ssbb2,所以存的时候会比较麻烦,导致效率比char慢,取的时候也慢,先拿长度,再取数据。

      优点:节省了一些硬盘空间,一个acsii码的字符用一个bytes长度就能表示,但是也并不一定比char省,看一下官网给出的一个表格对比数据,当你存的数据正好是你规定的字段长度的时候,varchar反而占用的空间比char要多。

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
        
      缺点:存取速度都慢
  总结:
    所以需要根据业务需求来选择用哪种类型来存
    其实在多数的用户量少的工作场景中char和varchar效率差别不是很大,最起码给用户的感知不是很大,并且其实软件级别的慢远比不上硬件级别的慢,所以你们公司的运维发现项目慢的时候会加内存、换nb的硬盘,项目的效率提升的会很多,但是我们作为专业人士,我们应该提出来这样的技术点来提高效率。

    但是对于InnoDB数据表,内部的行存储格式没有区分固定长度和可变长度列(所有数据行都使用指向数据列值的头指针),因此在本质上,使用固定长度的CHAR列不一定比使用可变长度VARCHAR列性能要好。因而,主要的性能因素是数据行使用的存储总量。由于CHAR平均占用的空间多于VARCHAR,因此使用VARCHAR来最小化需要处理的数据行的存储总量和磁盘I/O是比较好的。

    所以啊,两个选哪个都可以,如果是大型并发项目,追求高性能的时候,需要结合你们服务器的硬件环境来进行测试,看一下char和varchar哪个更好,这也能算一个优化的点吧~~~~

Enumerated types and collection types

test:

枚举类型(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');

Integrity constraints

For more details, see: https: //www.cnblogs.com/clschao/articles/9968396.html

not null is not empty
create table t1(name char(10) not null);
default defaults
create table t1(name char(10) not null default 'xx');
The only unique, field data can not be duplicated
create table t1(name char(10) unique);
primary key primary key constraint effects: not empty and the only
create table t1(id int primary key);
auto_increment increment
create table t1(id int primary key auto_increment); 前面必须是个key
foreign key foreign key constraints to establish relationships between tables used
  • Many-to (many)

在多的表里面添加一个字段,并给这个字段加foreign key,比如:
出版社对于书籍是多对一的关系
1、先创建出版社表 publish表
2、创建书籍表,外键写法:
create table book(
        id int primary key,
        name char(10),
        pid int,
        foreign key(pid) references publish(id)
        );
3、先给出版社插入数据
  • One relationship

学生表(student)和客户表(customer)
在数据少的表添加字段,如果一样多随便哪个表都行
create table student(
        id int primary key,
        name char(10),
        cid int unique,
        foreign key(cid) references customer(id)
        );

Qq students get to the table

  • Many relationship

作者表和书籍表
需要借助第三张表来完整两者的关系记录
第三张表最后创建
create table authortobook(
            id int primary key,
            aurhor_id int,
            book_id int,
            foreign key(author_id) references author1(id),
            foreign key(book_id) references book1(id)
            )

Find the code:

Guess you like

Origin www.cnblogs.com/NiceSnake/p/11574954.html