表相当于文件,表中的一条记录就相当于文件的一行内容,不同的是,表中的一条记录有对应的标题,称为表的字段。
idnameage字段:一条记录对应的标题称为一个字段,如id,name,age1kiessling37记录:一行内容称为一条记录2lars303leno28注意:
1.在同一张表中,字段名是不能相同的;
2.宽度和约束条件可选;
3.字段名和类型是必须的;
4.表中的最后一个字段不要加逗号!!
存储引擎决定了表的类型,而表内存放的数据也要有不同的类型,每种数据类型都有自己的宽度,但是宽度是可选的。
1.mysql常用数据类型概览:
#1. 数字: 整型:tinyinit int bigint 小数: float :在位数比较短的情况下不精准 double :在位数比较长的情况下不精准 0.000001230123123123 存成:0.000001230000 decimal:(如果用小数,则用推荐使用decimal) 精准 内部原理是以字符串形式去存 #2. 字符串: char(10):简单粗暴,浪费空间,存取速度快 root存成root000000 varchar:精准,节省空间,存取速度慢 sql优化:创建表时,定长的类型往前放,变长的往后放 比如性别 比如地址或描述信息 >255个字符,超了就把文件路径存放到数据库中。 比如图片,视频等找一个文件服务器,数据库中只存路径或url。 #3. 时间类型: 最常用:datetime #4. 枚举类型与集合类型 整数类型:TINYINT SMALLINT MEDIUMINT INT BIGINT
作用:存储年龄,等级,id,各种号码等。
强调:整型的宽度是显示宽度(如tinyint(4) ),无需设置,存储宽度是固定死的。默认的显示宽度,都是在最大值的基础上加1。
# 常用类型详解 ======================================== tinyint[(m)] [unsigned] [zerofill] 小整数,数据类型用于保存一些范围的整数数值范围: 有符号: -128 ~ 127 无符号: 0 ~ 255 PS: MySQL中无布尔值,使用tinyint(1)构造。 ======================================== int[(m)][unsigned][zerofill] 整数,数据类型用于保存一些范围的整数数值范围: 有符号: -2147483648 ~ 2147483647 无符号: 0 ~ 4294967295 ======================================== bigint[(m)][unsigned][zerofill] 大整数,数据类型用于保存一些范围的整数数值范围: 有符号: -9223372036854775808 ~ 9223372036854775807 无符号: 0 ~ 18446744073709551615 代码验证:
# 1、=====================表字段类型之整型======================= # =========有符号和无符号tinyint========== # tinyint默认为有符号 mysql> insert t4 values(128); ERROR 1264 (22003): Out of range value for column 'id' at row 1 # 严格模式,超出范围会报错,若不是严格模式,则会把数字存成最近的极值。 mysql> insert t4 values(127); Query OK, 1 row affected (0.01 sec) mysql> select * from t4; +------+ | id | +------+ | 127 | +------+ 1 row in set (0.00 sec) 类型大小范围(有符号)范围(无符号)用途TINYINT1 字节(-128,127)(0,255)小整数值SMALLINT2 字节(-32 768,32 767)(0,65 535)大整数值MEDIUMINT3 字节(-8 388 608,8 388 607)(0,16 777 215)大整数值INT或INTEGER4 字节(-2 147 483 648,2 147 483 647)(0,4 294 967 295)大整数值BIGINT8 字节(-9 233 372 036 854 775 808,9 223 372 036 854 775 807)(0,18 446 744 073 709 551 615)极大整数值FLOAT4 字节(-3.402 823 466 E+38,1.175 494 351 E-38),0,(1.175 494 351 E-38,3.402 823 466 351 E+38)0,(1.175 494 351 E-38,3.402 823 466 E+38)单精度,浮点数值DOUBLE8 字节(1.797 693 134 862 315 7 E+308,2.225 073 858 507 201 4 E-308),0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)0,(2.225 073 858 507 201 4 E-308,1.797 693 134 862 315 7 E+308)双精度,浮点数值DECIMAL对DECIMAL(M,D) ,如果M>D,为M+2否则为D+2依赖于M和D的值依赖于M和D的值小数值 1) int的存储宽度是4Bytes,即32个bit,即2**32; 2) 无符号最大值:4294967296-1; 3) 有符号最大值:2147483648-1; 4) 有符号和无符号的最大数字需要的显示宽度均为10,而针对有符号的最小值则需要11位才能完全显示,所以int类型默认的显示宽度为11是非常合理的。 5) 最后,整型类型,其实没有必要指定显示宽度,使用默认的就OK。定点数类型 DEC等同于DECIMAL
浮点类型:float double
作用:存储薪资、身高、体重、体质参数等
# 常用类型详解 ====================================== float[(M,D) [unsigned] [zerofill]] 定义: 单精度浮点数(非准确小数),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30。 有符号: -3.402823466E+38 to -1.175494351E-38, 1.175494351E-38 to 3.402823466E+38 无符号: 1.175494351E-38 to 3.402823466E+38 精确度: **** 随着小数的增多,精度变得不准确 **** ====================================== double[(M,D) [unsigned] [zerofill]] 定义: 双精度浮点数(非准确小数值),m是数字总个数,d是小数点后个数。m最大值为255,d最大值为30。 有符号: -1.7976931348623157E+308 to -2.2250738585072014E-308 2.2250738585072014E-308 to 1.7976931348623157E+308 无符号: 2.2250738585072014E-308 to 1.7976931348623157E+308 精确度: ****随着小数的增多,精度比float要高,但也会变得不准确 **** ====================================== decimal[(M,D) [unsigned] [zerofill]] 定义: 准确的小数值,m是数字总个数(符号不算),d是小数点后个数。m最大值为65,d最大值为30。 精确度: **** 随着小数的增多,精度始终准确 **** 对于精确数值计算时需要用此类型 decaimal能够存储精确值的原因在于其内部按照字符串存储。 # 2、=====================表字段类型之浮点类型======================= mysql> create table t7(x float(255,30),y double(255,30),z decimal(65,30)); mysql> insert t7 values(1.11111111111111111111,1.11111111111111111111,1.11111111111111111111); mysql> select * from t7; # 显示的精度问题,decimal精度最高 +----------------------------------+----------------------------------+----------------------------------+ | x | y | z | +----------------------------------+----------------------------------+----------------------------------+ | 1.111111164093017600000000000000 | 1.111111111111111200000000000000 | 1.111111111111111111110000000000 | +----------------------------------+----------------------------------+----------------------------------+ 1 row in set (0.00 sec) date time datetime timestamp year
作用:存储用户注册时间,文章发布时间,员工入职时间,出生时间,过期时间等等。
year(1901/2155) time 时:分:秒 ('-838:59:59'/'838:59:59') date 年:月:日 (1000-01-01/9999-12-31) datetime 年:月:日 时:分:秒 1000-01-01 00:00:00/9999-12-31 23:59:59 timestamp 年:月:日 时:分:秒 1970-01-01 00:00:00/2037 # 3、=====================表字段类型之日期类型====================== # 使用函数now() mysql> create table t8(y year,t time,d date,dt datetime,ts timestamp); Query OK, 0 rows affected (0.03 sec) mysql> insert t8 values(now(),now(),now(),now(),now()); Query OK, 1 row affected, 1 warning (0.01 sec) mysql> select * from t8; +------+----------+------------+---------------------+---------------------+ | y | t | d | dt | ts | +------+----------+------------+---------------------+---------------------+ | 2020 | 11:09:30 | 2020-09-02 | 2020-09-02 11:09:30 | 2020-09-02 11:09:30 | +------+----------+------------+---------------------+---------------------+ # 手动传时间参数 mysql> create table student(id int,name char(10),born_year year,birth date,reg_time datetime); Query OK, 0 rows affected (0.03 sec) mysql> insert student values(1,"xxx","1911","1911-11-11","1911-11-11 11:11:11"); Query OK, 1 row affected (0.01 sec) mysql> select * from student; +------+------+-----------+------------+---------------------+ | id | name | born_year | birth | reg_time | +------+------+-----------+------------+---------------------+ | 1 | xxx | 1911 | 1911-11-11 | 1911-11-11 11:11:11 | +------+------+-----------+------------+---------------------+ 1 row in set (0.00 sec) ============!!!注意!!!!!!!=========== 1) 单独插入时间是,需要以字符串的显露出,按照对应的格式插入 2) 插入年份时,尽量使用4位值 3) 插入两位年份时,<=69,以20开头,比如50,结果2050 >=70,以19开头,比如71,结果1971datetime与timestamp的区别
# 在实际应用的很多场景中,MySQL的这两种日期类型都能够满足我们的需要,存储精度都为秒,但在某些情况下,会展现出他们各自的优劣。下面就来总结一下两种日期类型的区别。 1) DATETIME的日期范围是1001——9999年,TIMESTAMP的时间范围是1970——2038年。 2) datetime存储时间与失去无关,timestamp存储时间与失去有关,显示的值也依赖于时区。在MySQL服务器,操作系统以及客户端连接都有时区的设置。 3) datetime使用8字节存储时间,timestamp的搓出空间为4字节。因此,timestamp比datetime的空间利用率更高。 4) datetime的默认值为null,timestamp的字段默认不为空(not null),默认值为当前时间(current_timestamp),如果不做特殊处理,并且update语句中没有指定该列的更新值,则默认更新至为当前时间。**!!!注意:**针对datetime或者timestamp如果是用作注册时间,那么指定not null default now()自动填充时间即可,如果是用作更新时间那么需要额外指定on update now(),该配置timestamp自带。
# 测试1:基础性质 mysql> create table t9(reg_time datetime not null default now()); mysql> create table t10(reg_time timestamp); mysql> insert t9 values(); mysql> insert t10 values(); mysql> select * from t9; +---------------------+ | reg_time | +---------------------+ | 2020-09-02 11:28:40 | +---------------------+ mysql> select * from t10; +---------------------+ | reg_time | +---------------------+ | 2020-09-02 11:28:49 | +---------------------+ mysql> desc t9; # 用于记录注册时间, +----------+----------+------+-----+-------------------+-------+ | Field | Type | Null | Key | Default | Extra | +----------+----------+------+-----+-------------------+-------+ | reg_time | datetime | NO | | CURRENT_TIMESTAMP | | +----------+----------+------+-----+-------------------+-------+ mysql> desc t10; # 用于记录更新时间 +----------+-----------+------+-----+-------------------+-----------------------------+ | Field | Type | Null | Key | Default | Extra | +----------+-----------+------+-----+-------------------+-----------------------------+ | reg_time | timestamp | NO | | CURRENT_TIMESTAMP | on update CURRENT_TIMESTAMP | +----------+-----------+------+-----+-------------------+-----------------------------+ # 测试2: mysql> create table t9( -> id int, -> name varchar(16), -> -- update_time datetime not null default now() on update now() # --是注释的意思, -> update_time timestamp, -> reg_time datetime not null default now() -> ); mysql> insert into t9(id,name) values(1,"xxx"); # 测试效果 mysql> select * from t9; +------+------+---------------------+---------------------+ | id | name | update_time | reg_time | +------+------+---------------------+---------------------+ | 1 | xxx | 2020-09-02 11:37:21 | 2020-09-02 11:37:21 | +------+------+---------------------+---------------------+ mysql> update t9 set name="XXXX" where id=1; mysql> select * from t9; +------+------+---------------------+---------------------+ | id | name | update_time | reg_time | +------+------+---------------------+---------------------+ | 1 | XXXX | 2020-09-02 11:39:13 | 2020-09-02 11:37:21 | +------+------+---------------------+---------------------+**示例:**以4字节为例,对比char与varchar存储空间数量。**特殊情况:**在接近数据存储满的时候,varchar反而更费空间。
ValueCHAR(4)Storage RequiredVARCHAR(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 字段的值只能在给定范围中选择,如单选框,多选框;
enum 单选,只能在给定的范围内选一个值,如性别 sex 男male/女female
set 多选,在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3…)
# 示例enum: mysql> create table shirts( -> name varchar(40), -> size enum('x-small', 'small', 'medium', 'large', 'x-large') -> ); # 正常插入值 mysql> insert shirts(name,size) values('dress shirt','large'), ('t-shirt','medium'),('polo shirt','small'); mysql> select * from shirts; +-------------+--------+ | name | size | +-------------+--------+ | dress shirt | large | | t-shirt | medium | | polo shirt | small | +-------------+--------+ # 非正常插入值 mysql> insert shirts values("abc shirts","xxxxxx"); mysql> select * from shirts; +-------------+--------+ | name | size | +-------------+--------+ | dress shirt | large | | t-shirt | medium | | polo shirt | small | | abc shirts | | +-------------+--------+ # 如果是严格模式,则会报错,不允许传入值; # 示例:set mysql> create table user( -> name varchar(16), -> hobbies set("read","chou","drink","tang") -> ); # 正常传值 mysql> insert user values("xxx","tang,chou"); mysql> select * from user; +------+-----------+ | name | hobbies | +------+-----------+ | xxx | chou,tang | +------+-----------+ # 非正常传值 mysql> insert user values("qqq","tangchou"); mysql> select * from user; +------+-----------+ | name | hobbies | +------+-----------+ | xxx | chou,tang | | qqq | | +------+-----------+ # 非正常传值,空PS:关于虚拟表:硬盘上不存在表,表存在于内存中,表是硬盘上数据的被select语句组织出来的。