02 数据库入门学习-数据类型

一.数据存储引擎

1.什么是引擎 ?

引擎是一个功能的核心部分,现实中的引擎可以被分类。从动力来源来说,引擎可以分为汽油、 柴油、电动、混合动力等,需求场景的不同催生了不同的引擎类别。

 

在数据库中同样也是有引擎的。核心功能是存储数据 涉及到存储数据的代码 就称之为存储引擎

根据不同的需求,也有着不同的引擎分类。

创建表时在最后指定引擎名称 engine = xxx

create table t1(id int)engine=innodbcreate table t2(id int not null)engine=csvcreate table t3(id int)engine=memorycreate table t4(id int)engine=blackhole#innodb,默认的引擎,因为它是永久存储并且支持事务,行锁,外键#csv,不能为空#memory,在重启mysql或者重启机器后,表内数据清空#blackhole,往表内插入任何数据,都相当于丢入黑洞,表内永远不存记录insert into t1 value(1); insert into t2 value(1); insert into t3 value(1); insert into t4 value(1);select * from t1;#有值select * from t2;#有值select * from t3;#有值select * from t4;#为空

二.创建表的完整语句

create table 表名(

字段名 数据类型(显示的长度)约束条件,

字段名 数据类型(显示的长度)约束条件,

..........

字段名 数据类型(显示的长度)约束条件

);

mysql> create table s1(a int(19) not null, -> b int(12) not null -> );mysql> desc s1;+-------+---------+------+-----+---------+-------+| Field | Type | Null | Key | Default | Extra |+-------+---------+------+-----+---------+-------+| a | int(19) | NO | | NULL | || b | int(12) | NO | | NULL | |+-------+---------+------+-----+---------+-------+

 

注意:①与Python的不同,最后不需要加逗号

   ②表名、字段名和数据类型都是必须有的

   ③显示的长度和约束条件是可选的

   ④字段名、表名甚至库名都不能是关键字

 

三.数据类型

1.整型

类型大小范围(有符号)范围(无符号)
tinyint1-128~1270~255
smallint2-32768~327670~65535
mediumint3-8388608~83886070~16777215
int4-2147483648~21474836470~4294967295
bigint8-9223372036854775808~92233720368547758070~18446744073709551615

 

 

 

 

 

默认情况下,整型是有符号的,需要一个二进制位存储

创建表的时候,给整型加上约束unsigned来表示无符号

  create table i1 (id int unsigned);

 

1.1严格模式与非严格模式

  MySQL自身对数据进行严格的校验(格式、长度、类型等),比如一个整型字段我们写入一个字符串类型的数据,只有在严格模式下MySQL才会报错,非严格模式下不会报错,对于一些错误的输入,非严格模式会用0或空来替代

 

Mysql处于非严格模式下:

  如果数据超出范围

    无符号: 例如 tinyint,输入256,保存的255,最大值;输入-123,保存0,最小值
    有符号 :例如 tinyint,输入256,保存的127,最大值;输入-1280,存的是-128,最小值

Mysql处于严格模式下:

  如果值超出范围就直接报错

  

为了在开发中,我们应该先判断数据的正确性,所以应该用严格模式

  查看当前模式 show variables like "sql_mode";
  修改为严格模式 set global sql_mode = "STRICT_TRANS_TABLES";

1.2 长度限制对于整型的意义

mysql>create table i1(id int(2));mysql>insert into i1 value(454555);mysql>select *from i1;+--------+| id |+--------+| 454555 |+--------+1 row in set (0.00 sec)

发现这个数也存储成功,说明,这里长度指的不是存储容量限制,而是显示的宽度。
  如果你的数据超过了显示宽度,有几个显示几个。
  如果不足,则补全到指定长度 得告诉它用什么来补全。

mysql>create table i1(id int(10) zerofill);#zerofill,用0来补全mysql> insert into i1 value(12345);mysql> select * from i1;+------------+| id |+------------+| 0000012345 |+------------+1 row in set (0.00 sec)

总结:

要限制显示宽度
1.创建表时 给整型加上宽度
2.加上zerofill约束

有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能显示完全,所以int类型默认的显示宽度为11是非常合理的

2.浮点型

 

类型大小范围(有符号)范围(无符号)
float(m,d)4

-3.402823466E+38 to -1.175494351E-38

1.175494351E-38 to 3.402823466E+38

1.175494351E-38 to 3.402823466E+38
double(m,d)8

-1.7976931348623157E+308 to -2.2250738585072014E-308

2.2250738585072014E-308 to 1.7976931348623157E+308

2.2250738585072014E-308 to 1.7976931348623157E+308
decimal(m,d)                   动态

 

 

 

 

 

 

 

 

 

m表示 这个浮点数整体的长度
d表示 小数部分的长度
例如: float(5,3) 最大值: 99.999

相同点: float和double的小数部分最大长度都是30
     float和double的最大长度为255
不同点: decimal的整体最大长度65
     精度不同
      double 比 float 精度高
      decimal 是准确的 不会丢失精度

代码验证

mysql> create table i1(a float(100,20),b double(100,20),c decimal(65,20));
mysql> insert into i1 value(1.111111111111111111111111111111111,
1.11111111111111111111111111111111,
1.1111111111111111111111111);
mysql> select *from i1;+------------------------+------------------------+------------------------+| a | b | c |+------------------------+------------------------+------------------------+| 1.11111116409301760000 | 1.11111111111111120000 | 1.11111111111111111111 |+------------------------+------------------------+------------------------+

 

3.字符型

3.1char 定长字符

char类型的长度是固定 无论你存储的数据有多长 占用的容量都一样

char(3) 存储的数据为 "a" 在硬盘保存的数据还是占3字符长度 实际保存的是"a "

如果你的数据不足指定长度 就在后面用空格补全

在硬盘中存储的是一连串的二进制,char类型取的时候是按照指定长度。

 

3.2varchar 变长字符

varchar 长度是可变的 存储的数据有多长就占用多长

varchar(3) 存储的数据为 "a" 在硬盘保存的数据还是占1字符长度 实际保存的是"a"

varchar存储数据时,会在数据前会用1~2Bytes显示后面的数据的长度,方便取。

vharchar 能支持的最大长度是65535 用于保存数据长度的数据最长两个bytes

 

3.3验证:

使用一个 char_length的函数 可以查看字符的长度

mysql> create table i1(a char(4),b varchar(4));mysql> insert into i1 value(‘x‘,‘x‘);mysql> select char_length(a),char_length(b) from i1;+----------------+----------------+| char_length(a) | char_length(b) |+----------------+----------------+| 1 | 1 |+----------------+----------------+#两个字段的长度都为1

 

3.4结论:

这是因为,mysql在存储时,自动加上的空格,对使用者而言是没有意义的,所以mysql自动帮你处理空格了,我们可以设置sql模式 来让它现出原形。

mysql> set global sql_mode = "PAD_CHAR_TO_FULL_LENGTH,STRICT_TRANS_TABLES";

设置完成后重启msyql 再次查询长度

mysql> select char_length(a),char_length(b) from i1;+----------------+----------------+| char_length(a) | char_length(b) |+----------------+----------------+| 4 | 1 |+----------------+----------------+

 

3.5注意:

当你在执行这样的查询语句时 mysql会自动将参数末尾的空格去除

mysql> select *from i1 where name = "xcq ";+------+------------+| id | name |+------+------------+| 1 | xcq |+------+------------+

 

当你在使用模糊搜索时 要注意 定长字符 后面可能会有空格 所以最好在后面加上百分号 %

mysql> select *from i1 where name like "xcq%";+------+------------+| id | name |+------+------------+| 1 | xcq |+------+------------+1 row in set (0.00 sec)mysql> select *from i1 where name like "xcq";Empty set (0.00 sec)# % 任意个数的任意字符# _ 1个任意字符

 

4.时间和日期

4.1time

 

时分秒 HH:MM:SS 

#手动输入时分秒mysql> create table i1 (a time);mysql> insert into i1 value(‘19:32:56‘);mysql> select *from i1;+----------+| a |+----------+| 19:32:56 |+----------+#也可以用now()来获取当前年月日时分秒mysql> insert into i1 value(now());mysql> select *from i1;+----------+| a |+----------+| 19:33:41 |+----------+

 

4.2year

年份 

#手动输入年份mysql> create table i1 (a year);mysql> insert into i1 value(‘2019‘);mysql> select *from i1;+------+| a |+------+| 2019 |+------+#通过now()获取当前年月日时分秒mysql> insert into i1 value(now());mysql> select *from i1;+------+| a |+------+| 2018 |+------+

 

4.3date

日期 年月日 

#手动输入年月日mysql> create table i1 (a date);mysql> insert into i1 value(‘2019-1-1‘);mysql> select *from i1;+------------+| a |+------------+| 2019-01-01 |+------------+#通过now()获取当前年月日时分秒mysql> insert into i1 value(now());mysql> select *from i1;+------------+| a |+------------+| 2018-09-12 |+------------+

 

4.4 datetime和timestamp

 

日期加时间 年月日 时分秒 年份最大是9999 

时间戳 从1970-1-1开始算 年份最大是2037 

#手动输入年月日 时分秒mysql> create table i1 (a datetime);#timestampmysql> insert into i1 value(‘2019-1-1 1:1:1‘);mysql> select *from i1;+---------------------+| a |+---------------------+| 2019-01-01 01:01:01 |+---------------------+#通过now()获取当前年月日时分秒mysql> insert into i1 value(now());mysql> select *from i1;+---------------------+| a |+---------------------+| 2018-09-12 19:43:36 |+---------------------+

 

4.5总结:

共同点: 时间的存取通过字符串类型

    都可以使用now()函数来插入当前时间

    datetime 和 时间戳都能够表示日期和时间

不同之处是: 年份最大范围不同

      时间戳可以为空 代表当前时间

      时间戳在你更新记录时 会自动更新为当前时间

 

5.枚举和集合

5.1枚举

enum,提前设置?个范围 你的数据只能是 其中之?(多选?) 例如性别

#正确情况mysql> create table i1 (id int,name char(10),sex enum(‘man‘,‘woman‘,‘othor‘))mysql> insert into i1 value(1,‘sql‘,‘man‘);mysql> select *from i1;+------+------------+------+| id | name | sex |+------+------------+------+| 1 | sql | man |+------+------------+------+#错误示范:不能添加不在枚举里的字符mysql> insert into i1 value(1,‘sql‘,‘123‘);#报错ERROR 1064 (42000): You have an error in your SQL syntaxcheck the manual that corresponds to your MySQL server version for the right syntax to use near ‘mysql> insert into i1 value(1,‘sql‘,‘123‘)‘ at line 1

 

 

5.2集合

set,提前设置?个范围 你的数据只能是其 中?部分(多选多) 例如爱好

mysql> create table i1 (id int,name char(10),hobby set(‘eat‘,‘play‘,‘sleep‘));mysql> insert into i1 value(1,‘sql‘,‘eat,play‘);mysql> select *from i1;+------+------------+----------+| id | name | hobby |+------+------------+----------+| 1 | sql | eat,play |+------+------------+----------+

相关文章