mysql移动记录指针_Mysql之库、表、记录相关操作1

本文详细介绍了MySQL中整型数据类型,包括tinyint、int、bigint,以及它们的无符号和零填充特性。内容涵盖数据范围、存储规则、约束条件和实际案例,帮助理解不同类型在不同场景下的适用性。
摘要由CSDN通过智能技术生成

Mysql之库、表、记录相关操作4

创建表完整语法

#语法:

create table 表名(

字段名1 类型[(宽度) 约束条件],

字段名2 类型[(宽度) 约束条件],

字段名3 类型[(宽度) 约束条件]

)engine=innodb charset=utf8;

#注意:

1. 在同一张表中,字段名是不能相同

2. 宽度和约束条件可选

3. 字段名和类型是必须的

4. []可选参数

# create table db1.t1(name char(3) not null);

# 数据插入时,name不能为空(null), 且最长只能存放三个字符

# 总结: 宽度和约束条件为可选参数, 用来限制存放数据的规则

数据库的模式

# sql_mode :反应数据库的全局变量

# 数据库模式限制的是客户端对服务器操作数据的方式(是否严格)

# 两种模式

no_engine_substitution:非安全性,默认

strict_trans_tables:安全模式

# 查看当前数据库模式

show variables like "%sql_models%";# 匹配0~n个人以字符=>模糊查询

# 设置安全模式

set global sql_mode="strict_trans_tables";

# 重启客户端

quit

数据类型

mysql 数据库支持存放的数据类型:

整型|浮点型|字符型|时间类型|枚举类型|集合类型

一、整型

整型类型:tinyint|smallint|mediumint|int|bigint

作用:存储年龄、等级、id、号码等

_____________________________________________________________________________

tinyint(1字节)

tinyint[(m)] [unsigned] [zerofill]

小整数,用于保存一些范围的整数数值范围:

有符号:-128~127

无符号:0~128

PS:Mysql中无布尔值,使用tinyint(1)构造~~~?

—————————————————————————————————————————————————————————————————————————————

int(4字节)

int[(m)][unsigned][zerofill]

整数,用于保存一些范围的整数数值范围:

有符号:-2147483648~2147483647

无符号:0~4294967295

—————————————————————————————————————————————————————————————————————————————

bigint(8字节)

bigint[(m)][unsigned][zerofill]

大整数,数据类型用于保存一些范围的整数数值范围:

有符号:-9223372036854775808~9223372036854775807

无符号:0~18446744073709551615

'''

约束条件:

undigned:无符号

zerofill:0填充

'''

不同类型所占字节数不一样,决定所占空间及存放数据的大小限制

create table t8(x tinyint);

insert into t8 values(200); # 非安全模式存入,值只能到最大值127

select (x) from t8;

'''

宽度:

1、不能决定整型存档数据的宽度,超过宽度可以存放,最终由数据类型所占字节决定

2、如果没有超过宽度,且有zerofill限制,会用0填充前置的不足位

3、没有必要规定整型的宽度,默认宽度即为整型能存放数据最大宽度

'''

# eg:1

create table t9(x int(5));

insert into t9 values(123456);

select (x) from t9; # 结果: 123456

insert into t9 values(2147483648);

select (x) from t9; # 结果: 2147483647

insert into t9 values(10);

select (x) from t9; # 结果: 10

# eg:2

create table t10(x int(5) unsigned zerofill); # 区域0~4294967295

insert into t10 values(10);

select x from t10; # 结果: 00010

insert into t10 values(12345678900);

select x from t10; # 结果: 4294967295

# 练习

=========有符号和无符号tinyint==========

#tinyint默认为有符号

MariaDB [db1]> create table t1(x tinyint); #默认为有符号,即数字前有正负号

MariaDB [db1]> desc t1;

MariaDB [db1]> insert into t1 values

-> (-129),

-> (-128),

-> (127),

-> (128);

MariaDB [db1]> select * from t1;

+------+

| x |

+------+

| -128 | #-129存成了-128

| -128 | #有符号,最小值为-128

| 127 | #有符号,最大值127

| 127 | #128存成了127

+------+

#设置无符号tinyint

MariaDB [db1]> create table t2(x tinyint unsigned);

MariaDB [db1]> insert into t2 values

-> (-1),

-> (0),

-> (255),

-> (256);

MariaDB [db1]> select * from t2;

+------+

| x |

+------+

| 0 | -1存成了0

| 0 | #无符号,最小值为0

| 255 | #无符号,最大值为255

| 255 | #256存成了255

+------+

============有符号和无符号int=============

#int默认为有符号

MariaDB [db1]> create table t3(x int); #默认为有符号整数

MariaDB [db1]> insert into t3 values

-> (-2147483649),

-> (-2147483648),

-> (2147483647),

-> (2147483648);

MariaDB [db1]> select * from t3;

+-------------+

| x |

+-------------+

| -2147483648 | #-2147483649存成了-2147483648

| -2147483648 | #有符号,最小值为-2147483648

| 2147483647 | #有符号,最大值为2147483647

| 2147483647 | #2147483648存成了2147483647

+-------------+

#设置无符号int

MariaDB [db1]> create table t4(x int unsigned);

MariaDB [db1]> insert into t4 values

-> (-1),

-> (0),

-> (4294967295),

-> (4294967296);

MariaDB [db1]> select * from t4;

+------------+

| x |

+------------+

| 0 | #-1存成了0

| 0 | #无符号,最小值为0

| 4294967295 | #无符号,最大值为4294967295

| 4294967295 | #4294967296存成了4294967295

+------------+

==============有符号和无符号bigint=============

MariaDB [db1]> create table t6(x bigint);

MariaDB [db1]> insert into t5 values

-> (-9223372036854775809),

-> (-9223372036854775808),

-> (9223372036854775807),

-> (9223372036854775808);

MariaDB [db1]> select * from t5;

+----------------------+

| x |

+----------------------+

| -9223372036854775808 |

| -9223372036854775808 |

| 9223372036854775807 |

| 9223372036854775807 |

+----------------------+

MariaDB [db1]> create table t6(x bigint unsigned);

MariaDB [db1]> insert into t6 values

-> (-1),

-> (0),

-> (18446744073709551615),

-> (18446744073709551616);

MariaDB [db1]> select * from t6;

+----------------------+

| x |

+----------------------+

| 0 |

| 0 |

| 18446744073709551615 |

| 18446744073709551615 |

+----------------------+

======用zerofill测试整数类型的显示宽度=============

MariaDB [db1]> create table t7(x int(3) zerofill);

MariaDB [db1]> insert into t7 values

-> (1),

-> (11),

-> (111),

-> (1111);

MariaDB [db1]> select * from t7;

+------+

| x |

+------+

| 001 |

| 011 |

| 111 |

| 1111 | #超过宽度限制仍然可以存

+------+

# 注意:为该类型指定宽度时,仅仅只是指定查询结果的显示宽度,与存储范围无关,存储范围如下

761613f67fcf6b5bb7a810822f736cbb.png

'''

int的存储宽度是4个Bytes,即32个bit,即2**32

无符号最大值为:4294967296-1

有符号最大值:2147483648-1

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

最后:整形类型,其实没有必要指定显示宽度,使用默认的就ok

'''

二、浮点型

浮点类型: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能够存储精确值的原因在于其内部按照字符串存储。

'''

宽度:

限制存储宽度

(M,D)=>M为位数,D为小数位

float(255, 30):精度最低,最常用

double(255, 30):精度高,占位多

decimal(65, 30):字符串存,全精度

'''

# eg:1

create table t11 (age float(256, 30)); # Display width out of range for column 'age' (max = 255)

create table t11 (age float(255, 31)); # Too big scale 31 specified for column 'age'. Maximum is 30.

# eg:2

create table t12 (x float(255, 30));

create table t13 (x double(255, 30));

create table t14 (x decimal(65, 30));

insert into t12 values(1.11111111111111111111);

insert into t13 values(1.11111111111111111111);

insert into t14 values(1.11111111111111111111);

select * from t12; # 1.111111164093017600000000000000 => 小数据,精度要求不高, 均采用float来存储 *

select * from t13; # 1.111111111111111200000000000000

select * from t14; # 1.111111111111111111110000000000

alter table t14 modify x decimal(10, 5); # 1.11111 => 限制了数据的存储宽度

# 练习

mysql> create table t1(x float(256,31));

ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.

mysql> create table t1(x float(256,30));

ERROR 1439 (42000): Display width out of range for column 'x' (max = 255)

mysql> create table t1(x float(255,30)); #建表成功

Query OK, 0 rows affected (0.02 sec)

mysql> create table t2(x double(255,30)); #建表成功

Query OK, 0 rows affected (0.02 sec)

mysql> create table t3(x decimal(66,31));

ERROR 1425 (42000): Too big scale 31 specified for column 'x'. Maximum is 30.

mysql> create table t3(x decimal(66,30));

ERROR 1426 (42000): Too-big precision 66 specified for 'x'. Maximum is 65.

mysql> create table t3(x decimal(65,30)); #建表成功

Query OK, 0 rows affected (0.02 sec)

mysql> show tables;

+---------------+

| Tables_in_db1 |

+---------------+

| t1 |

| t2 |

| t3 |

+---------------+

rows in set (0.00 sec)

mysql> insert into t1 values(1.1111111111111111111111111111111); #小数点后31个1

Query OK, 1 row affected (0.01 sec)

mysql> insert into t2 values(1.1111111111111111111111111111111);

Query OK, 1 row affected (0.00 sec)

mysql> insert into t3 values(1.1111111111111111111111111111111);

Query OK, 1 row affected, 1 warning (0.01 sec)

mysql> select * from t1; #随着小数的增多,精度开始不准确

+----------------------------------+

| x |

+----------------------------------+

| 1.111111164093017600000000000000 |

+----------------------------------+

row in set (0.00 sec)

mysql> select * from t2; #精度比float要准确点,但随着小数的增多,同样变得不准确

+----------------------------------+

| x |

+----------------------------------+

| 1.111111111111111200000000000000 |

+----------------------------------+

row in set (0.00 sec)

mysql> select * from t3; #精度始终准确,d为30,于是只留了30位小数

+----------------------------------+

| x |

+----------------------------------+

| 1.111111111111111111111111111111 |

+----------------------------------+

row in set (0.00 sec)

三、字符类型

#char类型:定长,简单粗暴,浪费空间,存取速度快

字符长度范围:0-255(一个中文是一个字符,是utf8编码的3个字节)

存储:

存储char类型的值时,会往右填充空格来满足长度

例如:指定长度为10,存>10个字符则报错,存<10个字符则用空格填充直到凑够10个字符存储

检索:

在检索或者说查询时,查出的结果会自动删除尾部的空格,除非我们打开pad_char_to_full_length SQL模式(SET sql_mode = 'PAD_CHAR_TO_FULL_LENGTH';)

#varchar类型:不定长,精准,节省空间,存取速度慢

字符长度范围:0-65535(如果大于21845会提示用其他类型 。mysql行最大限制为65535字节,字符编码为utf-8:https://dev.mysql.com/doc/refman/5.7/en/column-count-limit.html)

存储:

varchar类型存储数据的真实内容,不会用空格填充,如果'ab ',尾部的空格也会被存起来

强调:varchar类型会在真实数据前加1-2Bytes的前缀,该前缀用来表示真实数据的bytes字节数(1-2Bytes最大表示65535个数字,正好符合mysql对row的最大字节限制,即已经足够使用)

如果真实的数据<255bytes则需要1Bytes的前缀(1Bytes=8bit 2**8最大表示的数字为255)

如果真实的数据>255bytes则需要2Bytes的前缀(2Bytes=16bit 2**16最大表示的数字为65535)

检索:

尾部有空格会保存下来,在检索或者说查询时,也会正常显示包含空格在内的内容

# eg:

create table t15 (x char(4), y varchar(4));

insert into t15 values("zero", 'owen'); # '' | "" 均可以表示字符

select x,y from t15; # 正常

insert into t15 values("yanghuhu", 'lxxVSegon'); # 非安全模式数据丢失,可以存放, 安全模式报错

select x,y from t15; # 可以正常显示丢失后(不完整)的数据

insert into t15 values('a', 'b');

# 验证数据所在字符长度

# 前提: 安全模式下以空白填充字符

set global sql_mode="strict_trans_tables,PAD_CHAR_TO_FULL_LENGTH";

# 重启连接

select char_length(x), char_length(y) from t15; # a占4 b占1

'''重点: 存储数据的方式 ** => 数据库优化

char: 一定按规定的宽度存放数据, 以规定宽度读取数据, 通常更占空间

varchar: 首先根据数据长度计算所需宽度, 并在数据开始以数据头方式将宽度信息保存起来, 是一个计算耗时过程, 取先读取宽度信息,以宽度信息为依准读取数据, 通常节省空间

'''

8: zero egon lxx yanghuhu

8: 4zero4egon3lxx8yanghuhu

注: varchar的数据头占1~2字节

规定char|varchar宽度均为4,用来存放4个字符的数据, char存取更高效,char占4字符,varchar占5字符,char更省空间

总结: 数据长度相近的数据提倡用char来存放数据, 数据需要高速存取,以空间换时间, 采用char

官方解释:

#官网:https://dev.mysql.com/doc/refman/5.7/en/char.html

CHAR 和 VARCHAR 是最常使用的两种字符串类型。

一般来说

CHAR(N)用来保存固定长度的字符串,对于 CHAR 类型,N 的范围 为 0 ~ 255

VARCHAR(N)用来保存变长字符类型,对于 VARCHAR 类型,N 的范围为 0 ~ 65 535

CHAR(N)和 VARCHAR(N) 中的 N 都代表字符长度,而非字节长度。

ps:对于 MySQL 4.1 之前的版本,如 MySQL 3.23 和 MySQL 4.0,CHAR(N)和 VARCHAR (N)中的 N 代表字节长度。

#CHAR类型

对于 CHAR 类型的字符串,MySQL 数据库会自动对存储列的右边进行填充(Right Padded)操作,直到字符串达到指定的长度 N。而在读取该列时,MySQL 数据库会自动将 填充的字符删除。有一种情况例外,那就是显式地将 SQL_MODE 设置为 PAD_CHAR_TO_ FULL_LENGTH,例如:

mysql> CREATE TABLE t ( a CHAR(10));

Query OK, 0 rows affected (0.03 sec)

mysql> INSERT INTO t SELECT 'abc';

Query OK, 1 row affected (0.03 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;

*************************** 1. row ***************************

a: abc

HEX(a): 616263

LENGTH (a): 3

row in set (0.00 sec)

mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a,HEX(a),LENGTH(a) FROM t\G;

*************************** 1. row ***************************

a: abc

HEX(a): 61626320202020202020

LENGTH (a): 10

row in set (0.00 sec)

在上述这个例子中,先创建了一张表 t,a 列的类型为 CHAR(10)。然后通过 INSERT语句插入值“abc”,因为 a 列的类型为 CHAR 型,所以会自动在后面填充空字符串,使其长 度为 10。接下来在通过 SELECT 语句取出数据时会将 a 列右填充的空字符移除,从而得到 值“abc”。通过 LENGTH 函数看到 a 列的字符长度为 3 而非 10。

接着我们将 SQL_MODE 显式地设置为 PAD_CHAR_TO_FULL_LENGTH。这时再通过 SELECT 语句进行查询时,得到的结果是“abc ”,abc 右边有 7 个填充字符 0x20,并通 过 HEX 函数得到了验证。这次 LENGTH 函数返回的长度为 10。需要注意的是,LENGTH 函数返回的是字节长度,而不是字符长度。对于多字节字符集,CHAR(N)长度的列最多 可占用的字节数为该字符集单字符最大占用字节数 *N。例如,对于 utf8 下,CHAR(10)最 多可能占用 30 个字节。通过对多字节字符串使用 CHAR_LENGTH 函数和 LENGTH 函数, 可以发现两者的不同,示例如下:

mysql> SET NAMES gbk;

Query OK, 0 rows affected (0.03 sec)

mysql> SELECT @a:='MySQL 技术内幕 '; Query OK, 0 rows affected (0.03 sec)

mysql> SELECT @a,HEX(@a),LENGTH(@a),CHAR_LENGTH(@a)\G; ***************************** 1. row **************************** a: MySQL 技术内幕

HEX(a): 4D7953514CBCBCCAF5C4DAC4BB

LENGTH (a): 13

CHAR_LENGTH(a): 9

row in set (0.00 sec)

变 量 @ a 是 g b k 字 符 集 的 字 符 串 类 型 , 值 为 “ M y S Q L 技 术 内 幕 ”, 十 六 进 制 为 0x4D7953514CBCBCCAF5C4DAC4BB,LENGTH 函数返回 13,即该字符串占用 13 字节, 因为 gbk 字符集中的中文字符占用两个字节,因此一共占用 13 字节。CHAR_LENGTH 函数 返回 9,很显然该字符长度为 9。

#VARCHAR类型

VARCHAR 类型存储变长字段的字符类型,与 CHAR 类型不同的是,其存储时需要在 前缀长度列表加上实际存储的字符,该字符占用 1 ~ 2 字节的空间。当存储的字符串长度小 于 255 字节时,其需要 1 字节的空间,当大于 255 字节时,需要 2 字节的空间。所以,对 于单字节的 latin1 来说,CHAR(10)和 VARCHAR(10)最大占用的存储空间是不同的, CHAR(10)占用 10 个字节这是毫无疑问的,而 VARCHAR(10)的最大占用空间数是 11 字节,因为其需要 1 字节来存放字符长度。

-------------------------------------------------

注意 对于有些多字节的字符集类型,其 CHAR 和 VARCHAR 在存储方法上是一样的,同样 需要为长度列表加上字符串的值。对于 GBK 和 UTF-8 这些字符类型,其有些字符是以 1 字节 存放的,有些字符是按 2 或 3 字节存放的,因此同样需要 1 ~ 2 字节的空间来存储字符的长 度。

-------------------------------------------------

虽然 CHAR 和 VARCHAR 的存储方式不太相同,但是对于两个字符串的比较,都只比 较其值,忽略 CHAR 值存在的右填充,即使将 SQL _MODE 设置为 PAD_CHAR_TO_FULL_ LENGTH 也一样,例如:

mysql> CREATE TABLE t ( a CHAR(10), b VARCHAR(10));

Query OK, 0 rows affected (0.01 sec)

mysql> INSERT INTO t SELECT 'a','a';

Query OK, 1 row affected (0.00 sec)

Records: 1 Duplicates: 0 Warnings: 0

mysql> SELECT a=b FROM t\G;

*************************** 1. row ***************************

a=b: 1

row in set (0.00 sec)

mysql> SET SQL_MODE='PAD_CHAR_TO_FULL_LENGTH';

Query OK, 0 rows affected (0.00 sec)

mysql> SELECT a=b FROM t\G;

*************************** 1. row ***************************

a=b: 1

row in set (0.00 sec)

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

小结:

#InnoDB存储引擎:建议使用VARCHAR类型

单从数据类型的实现机制去考虑,char数据类型的处理速度更快,有时甚至可以超出varchar处理速度的50%。

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

#其他字符串系列(效率:char>varchar>text)

TEXT系列 TINYTEXT TEXT MEDIUMTEXT LONGTEXT

BLOB 系列 TINYBLOB BLOB MEDIUMBLOB LONGBLOB

BINARY系列 BINARY VARBINARY

text:text数据类型用于保存变长的大字符串,可以组多到65535 (2**16 − 1)个字符。

mediumtext:A TEXT column with a maximum length of 16,777,215 (2**24 − 1) characters.

longtext:A TEXT column with a maximum length of 4,294,967,295 or 4GB (2**32 − 1) characters.

四、日期类型

'''类型

year:yyyy(1901/2155)

date:yyyy-MM-dd(1000-01-01/9999-12-31)

time:HH:mm:ss

datetime:yyyy-MM-dd HH:mm:ss(1000-01-01 00:00:00/9999-12-31 23:59:59)

timestamp:yyyy-MM-dd HH:mm:ss(1970-01-01 00:00:00/2038-01-19 03:14:07(UTC范围))

'''

# eg: 1

create table t16(my_year year, my_date date, my_time time);

insert into t16 values(); # 三个时间类型的默认值均是null

insert into t16 values(2156, null, null); # 在时间范围外,不允许插入该数据

insert into t16 values(1, '2000-01-01 12:00:00', null); # 2001 2000-01-01 null

insert into t16 values(2019, '2019-01-08', "15-19-30"); # time报格式错误 => 按照时间规定格式存放数据

alter table t16 change my_year myYear year(2); # 时间的宽度修改后还是采用默认宽度 => 不需要关系宽度

# eg:2

create table t17(my_datetime datetime, my_timestamp timestamp);

insert into t17 values(null, null); # 可以为空, 不能为null,赋值null采用默认值current_timestamp

insert into t17 values('4000-01-01 12:00:00', '2000-01-01 12:00:00'); # 在各自范围内可以插入对应格式的时间数据

# datetime VS timestamp

datetime:时间范围,不依赖当前时区,8字节,可以为null

timestamp:时间范围,依赖当前时区,4字节,有默认值CURRENT_TIMESTAMP

练习:

============year===========

MariaDB [db1]> create table t10(born_year year); #无论year指定何种宽度,最后都默认是year(4)

MariaDB [db1]> insert into t10 values

-> (1900),

-> (1901),

-> (2155),

-> (2156);

MariaDB [db1]> select * from t10;

+-----------+

| born_year |

+-----------+

| 0000 |

| 1901 |

| 2155 |

| 0000 |

+-----------+

============date,time,datetime===========

MariaDB [db1]> create table t11(d date,t time,dt datetime);

MariaDB [db1]> desc t11;

+-------+----------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+----------+------+-----+---------+-------+

| d | date | YES | | NULL | |

| t | time | YES | | NULL | |

| dt | datetime | YES | | NULL | |

+-------+----------+------+-----+---------+-------+

MariaDB [db1]> insert into t11 values(now(),now(),now());

MariaDB [db1]> select * from t11;

+------------+----------+---------------------+

| d | t | dt |

+------------+----------+---------------------+

| 2017-07-25 | 16:26:54 | 2017-07-25 16:26:54 |

+------------+----------+---------------------+

============timestamp===========

MariaDB [db1]> create table t12(time timestamp);

MariaDB [db1]> insert into t12 values();

MariaDB [db1]> insert into t12 values(null);

MariaDB [db1]> select * from t12;

+---------------------+

| time |

+---------------------+

| 2017-07-25 16:29:17 |

| 2017-07-25 16:30:01 |

+---------------------+

============注意啦,注意啦,注意啦===========

1. 单独插入时间时,需要以字符串的形式,按照对应的格式插入

2. 插入年份时,尽量使用4位值

3. 插入两位年份时,<=69,以20开头,比如50, 结果2050

>=70,以19开头,比如71,结果1971

MariaDB [db1]> create table t12(y year);

MariaDB [db1]> insert into t12 values

-> (50),

-> (71);

MariaDB [db1]> select * from t12;

+------+

| y |

+------+

| 2050 |

| 1971 |

+------+

============综合练习===========

MariaDB [db1]> create table student(

-> id int,

-> name varchar(20),

-> born_year year,

-> birth date,

-> class_time time,

-> reg_time datetime);

MariaDB [db1]> insert into student values

-> (1,'alex',"1995","1995-11-11","11:11:11","2017-11-11 11:11:11"),

-> (2,'egon',"1997","1997-12-12","12:12:12","2017-12-12 12:12:12"),

-> (3,'wsb',"1998","1998-01-01","13:13:13","2017-01-01 13:13:13");

MariaDB [db1]> select * from student;

+------+------+-----------+------------+------------+---------------------+

| id | name | born_year | birth | class_time | reg_time |

+------+------+-----------+------------+------------+---------------------+

| 1 | alex | 1995 | 1995-11-11 | 11:11:11 | 2017-11-11 11:11:11 |

| 2 | egon | 1997 | 1997-12-12 | 12:12:12 | 2017-12-12 12:12:12 |

| 3 | wsb | 1998 | 1998-01-01 | 13:13:13 | 2017-01-01 13:13:13 |

+------+------+-----------+------------+------------+---------------------+

datetime 与 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语句中没有指定该列的更新值,则默认更新为当前时间。

mysql> create table t1(x datetime not null default now()); # 需要指定传入空值时默认取当前时间

Query OK, 0 rows affected (0.01 sec)

mysql> create table t2(x timestamp); # 无需任何设置,在传空值的情况下自动传入当前时间

Query OK, 0 rows affected (0.02 sec)

mysql> insert into t1 values();

Query OK, 1 row affected (0.00 sec)

mysql> insert into t2 values();

Query OK, 1 row affected (0.00 sec)

mysql> select * from t1;

+---------------------+

| x |

+---------------------+

| 2018-07-07 01:26:14 |

+---------------------+

row in set (0.00 sec)

mysql> select * from t2;

+---------------------+

| x |

+---------------------+

| 2018-07-07 01:26:17 |

+---------------------+

row in set (0.00 sec)

五、枚举与集合

字段的值只能在给定范围中选择,如单选框,多选框

enum 单选只能在给定的范围内选一个值,如性别 sex 男male/女female

set 多选 在给定的范围内可以选择一个或一个以上的值(爱好1,爱好2,爱好3...)

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

练习

create table t19(

sex enum('male','female','wasai') not null default 'wasai', # 枚举

hobbies set('play','read','music') # 集合

);

insert into t19 values (null, null); # sex不能设置null

insert into t19 values (); # wasai null

insert into t19 (hobbies) values ('play,read'), ('music,play'); # sex采用默认值, 对hobbies字段添加两条记录

insert into t19 (sex,hobbies) values ('male,female', 'play'); # sex字段只能单选

MariaDB [db1]> create table consumer(

-> name varchar(50),

-> sex enum('male','female'),

-> level enum('vip1','vip2','vip3','vip4','vip5'), #在指定范围内,多选一

-> hobby set('play','music','read','study') #在指定范围内,多选多

-> );

MariaDB [db1]> insert into consumer values

-> ('egon','male','vip5','read,study'),

-> ('alex','female','vip1','girl');

MariaDB [db1]> select * from consumer;

+------+--------+-------+------------+

| name | sex | level | hobby |

+------+--------+-------+------------+

| egon | male | vip5 | read,study |

| alex | female | vip1 | |

+------+--------+-------+------------+

六、约束条件

约束条件与数据类型的宽度一样,都是可选参

作用:用于保证数据的完整型和一致性

主要分为:

PRIMARY KEY (PK) 标识该字段为该表的主键,可以唯一的标识记录

FOREIGN KEY (FK) 标识该字段为该表的外键

NOT NULL 标识该字段不能为空

UNIQUE KEY (UK) 标识该字段的值是唯一的

AUTO_INCREMENT 标识该字段的值自动增长(整数类型,而且为主键)

DEFAULT 为该字段设置默认值

UNSIGNED 无符号

ZEROFILL 使用0填充

primary key : 主键,唯一标识,表都会拥有,不设置默认找第一个不空、唯一字段,为表示则创建隐藏字段

foreign key:外键,

unique key:唯一性数据,该条字段的值需要保证唯一,不能重复

auto_increment:自增,只能加给key字段辅助修饰

注:

1. 是否允许为空,默认NULL,可设置NOT NULL,字段不允许为空,必须赋值

2. 字段是否有默认值,缺省的默认值是NULL,如果插入记录时不给字段赋值,此字段使用默认值

sex enum('male','female') not null default 'male'

age int unsigned NOT NULL default 20 必须为正值(无符号) 不允许为空 默认是20

3. 是否是key

主键 primary key

外键 foreign key

索引 (index,unique...)

注:

1.键是用来讲的io提供存取效率

2.联合唯一

​create table web (

ip char(16),

​ port int,

unique(ip,port)

​);

3.联合主键

​create table web (

​ ip char(16),

​ port int,

primary key(ip,port)

​);

# eg:1

# 单列唯一

create table t20 (

id int unique

);

# 联合唯一

create table web (

ip char(16),

port int,

unique(ip,port)

);

# 如果联合两个字段,两个字段全相同才相同,否则为不同

insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);

# 注:

# 1.表默认都有主键, 且只能拥有一个主键字段(单列主键 | 联合主键)

# 2.没有设置主键的表, 数据库系统会自上而下将第一个规定为unique not null字段自动提升为primary key主键

# 3.如果整个表都没有unique not null字段且没有primary key字段, 系统会默认创建一个隐藏字段作为主键

# 4.通常必须手动指定表的主键, 一般用id字段, 且id字段一般类型为int, 因为int类型可以auto_increment

# eg:2

create table t21(id int auto_increment); # 自增约束必须添加给key的字段

# eg:3

create table t21(id int primary key auto_increment); # 自增要结合key,不赋值插入,数据会自动自增, 且自增的结果一直被记录保留

# eg:4

# 联合主键

create table t22(

ip char(16),

port int,

primary key(ip,port)

);

# 如果联合两个字段,两个字段全相同才相同,否则为不同

insert into web values ('10.10.10.10', 3306), ('10.10.10.10', 3306);

not null 与 default

是否可空, null表示空,非字符串

创建列表时刻指定默认值,当插入数据时如果未主动设置,则自动添加默认

==================not null====================

mysql> create table t1(id int); #id字段默认可以插入空

mysql> desc t1;

+-------+---------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------+------+-----+---------+-------+

| id | int(11) | YES | | NULL | |

+-------+---------+------+-----+---------+-------+

mysql> insert into t1 values(); #可以插入空

mysql> create table t2(id int not null); #设置字段id不为空

mysql> desc t2;

+-------+---------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------+------+-----+---------+-------+

| id | int(11) | NO | | NULL | |

+-------+---------+------+-----+---------+-------+

mysql> insert into t2 values(); #不能插入空

ERROR 1364 (HY000): Field 'id' doesn't have a default value

==================default====================

#设置id字段有默认值后,则无论id字段是null还是not null,都可以插入空,插入空默认填入default指定的默认值

mysql> create table t3(id int default 1);

mysql> alter table t3 modify id int not null default 1;

==================综合练习====================

mysql> create table student(

-> name varchar(20) not null,

-> age int(3) unsigned not null default 18,

-> sex enum('male','female') default 'male',

-> hobby set('play','study','read','music') default 'play,music'

-> );

mysql> desc student;

+-------+------------------------------------+------+-----+------------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+------------------------------------+------+-----+------------+-------+

| name | varchar(20) | NO | | NULL | |

| age | int(3) unsigned | NO | | 18 | |

| sex | enum('male','female') | YES | | male | |

| hobby | set('play','study','read','music') | YES | | play,music | |

+-------+------------------------------------+------+-----+------------+-------+

mysql> insert into student(name) values('egon');

mysql> select * from student;

+------+-----+------+------------+

| name | age | sex | hobby |

+------+-----+------+------------+

| egon | 18 | male | play,music |

+------+-----+------+------------+

unipue

============设置唯一约束 UNIQUE===============

方法一:

create table department1(

id int,

name varchar(20) unique,

comment varchar(100)

);

方法二:

create table department2(

id int,

name varchar(20),

comment varchar(100),

constraint uk_name unique(name)

);

mysql> insert into department1 values(1,'IT','技术');

Query OK, 1 row affected (0.00 sec)

mysql> insert into department1 values(1,'IT','技术');

ERROR 1062 (23000): Duplicate entry 'IT' for key 'name'

not null+unique的化学反应:“

mysql> create table t1(id int not null unique);

Query OK, 0 rows affected (0.02 sec)

mysql> desc t1;

+-------+---------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+-------+---------+------+-----+---------+-------+

| id | int(11) | NO | PRI | NULL | |

+-------+---------+------+-----+---------+-------+

row in set (0.00 sec)

联合唯一

create table service(

id int primary key auto_increment,

name varchar(20),

host varchar(15) not null,

port int not null,

unique(host,port) #联合唯一

);

mysql> insert into service values

-> (1,'nginx','192.168.0.10',80),

-> (2,'haproxy','192.168.0.20',80),

-> (3,'mysql','192.168.0.30',3306)

-> ;

Query OK, 3 rows affected (0.01 sec)

Records: 3 Duplicates: 0 Warnings: 0

mysql> insert into service(name,host,port) values('nginx','192.168.0.10',80);

ERROR 1062 (23000): Duplicate entry '192.168.0.10-80' for key 'host'

primary key.

从约束角度看primary key字段的值不为空且唯一,那我们直接使用not null+unique不就可以了吗,要它干什么?

主键primary key是innodb存储引擎组织数据的依据,innodb称之为索引组织表,一张表中必须有且只有一个主键。

单列主键

============单列做主键===============

#方法一:not null+unique

create table department1(

id int not null unique, #主键

name varchar(20) not null unique,

comment varchar(100)

);

mysql> desc department1;

+---------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------+--------------+------+-----+---------+-------+

| id | int(11) | NO | PRI | NULL | |

| name | varchar(20) | NO | UNI | NULL | |

| comment | varchar(100) | YES | | NULL | |

+---------+--------------+------+-----+---------+-------+

rows in set (0.01 sec)

#方法二:在某一个字段后用primary key

create table department2(

id int primary key, #主键

name varchar(20),

comment varchar(100)

);

mysql> desc department2;

+---------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------+--------------+------+-----+---------+-------+

| id | int(11) | NO | PRI | NULL | |

| name | varchar(20) | YES | | NULL | |

| comment | varchar(100) | YES | | NULL | |

+---------+--------------+------+-----+---------+-------+

rows in set (0.00 sec)

#方法三:在所有字段后单独定义primary key

create table department3(

id int,

name varchar(20),

comment varchar(100),

constraint pk_name primary key(id); #创建主键并为其命名pk_name

mysql> desc department3;

+---------+--------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+---------+--------------+------+-----+---------+-------+

| id | int(11) | NO | PRI | NULL | |

| name | varchar(20) | YES | | NULL | |

| comment | varchar(100) | YES | | NULL | |

+---------+--------------+------+-----+---------+-------+

rows in set (0.01 sec)

多列主键

==================多列做主键================

create table service(

ip varchar(15),

port char(5),

service_name varchar(10) not null,

primary key(ip,port)

);

mysql> desc service;

+--------------+-------------+------+-----+---------+-------+

| Field | Type | Null | Key | Default | Extra |

+--------------+-------------+------+-----+---------+-------+

| ip | varchar(15) | NO | PRI | NULL | |

| port | char(5) | NO | PRI | NULL | |

| service_name | varchar(10) | NO | | NULL | |

+--------------+-------------+------+-----+---------+-------+

rows in set (0.00 sec)

mysql> insert into service values

-> ('172.16.45.10','3306','mysqld'),

-> ('172.16.45.11','3306','mariadb')

-> ;

Query OK, 2 rows affected (0.00 sec)

Records: 2 Duplicates: 0 Warnings: 0

mysql> insert into service values ('172.16.45.10','3306','nginx');

ERROR 1062 (23000): Duplicate entry '172.16.45.10-3306' for key 'PRIMARY'

多列主键

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值