数据库之数据类型、约束条件

数据库之数据类型、约束条件

1.数据类型

建表时,字段都有对应的数据类型

  • 整型
  • 浮点型
  • 字符类型(char与varchar)
  • 日期类型
  • 枚举与集合

2.约束条件

  • primary key 主键
  • unique key 唯一键
  • not null 不为空
  • foreign key 外键

创建表的完整语法 []内为可选参数

#语法:
create table 表名(
	字段名1 类型[(宽度) 约束条件],
    字段名2 类型[(宽度) 约束条件],
    字段名3 类型[(宽度) 约束条件]
);
#注意:
1. 在同一张表中,字段名不能相同
2. 宽度和约束条件可选,字段名和类型是必须的
3. 最后一个字段后不能加逗号!

# 补充:
# 1.宽度指的是对存储数据的限制
create table userinfo(name char);
insert into userinfo values(‘jason‘);
"""
1.没有安全模式的数据库版本,能够存放数据但是只会存进去一个j
2.最新数据库版本直接报错提示无法存储:Data too long for column ‘name‘ at row 1
"""
?
# 2.约束条件初识>>> null 与 not null     null等同于python中的None
create table t1(id int,name char not null);
insert into t1 values(1,‘j‘);  # 正常存储   《==》  insert into t1(name,id) values("j",1);
insert into t1 values(2,null);  # 报错  ERROR 1048 (23000): Column ‘name‘ cannot be null
?
# ==总结 类型与约束条件区别==
# 类型:限制字段必须以什么样的数据类型存储
# 约束条件:约束条件是在类型之外添加一种额外的限制

基本数据类型

整型

  • 分类:TINYINT SMALLINT MEDIUMINT INT BIGINT

  • 应用场景:存储年龄、等级、id、各种号码等

  • 疑问:类型后面的宽度能否改变字段存储的大小限制

  • 强调:对于整型来说,数据类型后的宽度并不是存储限制,而是显示限制,所以在创建表时,如果字段采用的是整型类型,完全无需指定显示宽度, 默认的显示宽度,足够显示完整当初存放的数据

浮点型

  • 分类:FLOAT DOUBLE DECIMAL

  • 应用场景:身高、体重、薪资

字段限制特点:

? (5,3)前一位表示所有的位数,后一位表示小数个数

总结:float\double\decimal形式保存的字符串精度依次提高,但即使是float也能精确到小数点后12位,一般的业务需求float即可满足,金融类的使用decimal

字符类型

  • 分类:char(定长)、varchar(变长)
  • 应用场景:姓名、地址、描述类信息
针对char类型,mysql在存储时会将数据用空格补全存放到硬盘中。但是会在读出结果的时候自动取掉末尾的空格

char 与 varchar的使用区别:
char->
# 缺点:浪费空间
# 优点:存取速度都快
内部原理:不管存的数据多长,只要低于设定位数,在存的时候在右边自动补空格,取的时候不核实数据长度,取设定长度的数据,自动去掉空格

varchar->
# 缺点:存取速度慢
# 优点:节省空间
内部原理:在真实数据前都被封装了报头,长度为1~2字节,先读取报头,获取数据真实长度,再读取真实数据;在存之前先为数据封装报头

时间类型

  • 分类:
    • date :2019-08-01
    • time:11:11:11
    • Datetime:2019-01-01 11:11:11
    • Year:2019

枚举和集合类型

  • 分类:

    • 枚举enum 多选一 示例:对性别进行限制,给定值范围,存的时候只允许出现已经限定的值,否则报错

    • 集合set 多选多   示例:一个人可以拥有多个标签,存数据的时候可以存多个已设定的值,用一个字符串包括,不同标签用逗号隔开

  • 测试

create table user(
    id int,
  name char(16),
  gender enum(‘male‘,‘female‘,‘others‘)
);
insert into user values(1,‘jason‘,‘xxx‘)  # 报错
insert into user values(2,‘egon‘,‘female‘)  # 正确!
?
?
create table teacher(
    id int,
  name char(16),
  gender enum(‘male‘,‘female‘,‘others‘),
  hobby set(‘read‘,‘sleep‘,‘sanna‘,‘dbj‘)
);
insert into teacher values(1,‘egon‘,‘male‘,‘read,sleep,dbj‘)  # 集合也可以只存一个

严格模式补充

设置了char,tinyint,存储数据时超过它们的最大存储长度,发现数据也能正常存储进去,只是mysql帮我们自动截取了最大长度。但在实际情况下,我们应该尽量减少数据库对数据的处理操作,缓解数据库的压力,让它仅仅只管理数据即可,这样的情况下就需要设置安全模式

show variables like ‘%mode%‘; -- 查看数据库配置中变量名包含mode的配置参数
-- 修改安全模式
set session -- 只在当前操作界面有效
set global -- 全局有效

set global sql_mode = ‘STRICT_TRANS_TABLES‘
-- 修改完后退出当前客户端重新登录即可

约束条件

"""
PRIMARY KEY (PK)    标识该字段为该表的主键,可以唯一的标识记录
FOREIGN KEY (FK)    标识该字段为该表的外键
NOT NULL    标识该字段不能为空
UNIQUE KEY (UK)    标识该字段的值是唯一的
AUTO_INCREMENT    标识该字段的值自动增长(整数类型,而且为主键)
DEFAULT    为该字段设置默认值
?
UNSIGNED 无符号
ZEROFILL 使用0填充
"""

not null + default

unique

  • 单列唯一
  • 联合唯一
# 单列唯一
create table user1(
    id int unique, 
  name char(16)
);
insert into user1 values(1,‘jason‘),(1,‘egon‘)  # 报错
insert into user1 values(1,‘jason‘),(2,‘egon‘)  # 成功
?
# 联合唯一
create table server(
    id int,
  ip char(16),
  port int,
  unique(ip,port)
)
insert into server values(1,‘127.0.0.1‘,8080);
insert into server values(2,‘127.0.0.1‘,8080);  # 同时相同报错
insert into server values(1,‘127.0.0.1‘,8081);

primary key + auto_increment

# 单从约束角度来说primary key就等价于not null unique
create table t11(id int primary key);
desc t11;
insert into t11 values(1),(1);  # 报错
insert into t11 values(1),(2);
?
# 除了约束之外,它还是innodb引擎组织数据的依据,提升查询效率
"""
强调:
1.一张表中必须有且只有一个主键,如果你没有设置主键,那么会从上到下搜索直到遇到一个非空且唯一的字段自动将其设置为主键
"""
create table t12(
    id int,
  name char(16),
  age int not null unique,
  addr char(16) not null unique
)engine=innodb;限定存储引擎
desc t12;
"""
2.如果表里面没有指定任何的可以设置为主键的字段,那么innodb会采用自己默认的一个隐藏字段作为主键,隐藏意味着你在查询的时候无法根据这个主键字段加速查询了
索引:类似于书的目录,没有主键就相当于一页一页翻着查
3.一张表中通常都应该有一个id字段,并且通常将改id字段作成主键
"""
# 联合主键:多个字段联合起来作为表的一个主键,本质还是一个主键
create table t18(
    ip char(16),
  port int,
  primary key(ip,port)
);
desc t18;
?
# 主键id作为数据的编号,每次最好能自动递增
create table t13(
    id int primary key auto_increment,
  name char(16)
);
insert into t13(‘jason‘),(‘jason‘),(‘jason‘);  # id字段自动从1开始递增
# 注意:auto_increment通常都是加在主键上,并且只能给设置为key的字段加

补充:

delete from tb1;
强调:上面的这条命令确实可以将表里的所有记录都删掉,但不会将id重置为0,
所以该条命令根本不是用来清空表的,==delete是用来删除表中某一些符合条件的记录==
delete from tb1 where id > 10;
?
如果要清空表,使用truncate tb1;
作用:将整张表重置,id重新从0开始记录

删除索引(约束条件):drop index 字段名 on 表名

参考博文:https://www.cnblogs.com/dongxixi/p/10857438.html

?大佬很赞!!!??????????