文章目录
mysql的数据类型
数值类型
MySQL中支持多种整型,其实很大程度上是相同的,只是存储值的大小范围不同而已。
tinyint:占用1个字节,相对于java中的byte
smallint:占用2个字节,相对于java中的short
int:占用4个字节,相对于java中的int
bigint:占用8个字节,相对于java中的long
其次是浮点类型即:float和double类型
float:4字节单精度浮点类型,相对于java中的float
double:8字节双精度浮点类型,相对于java中的double
字符串类型
1、char(n) 定长字符串,最长255个字符。n表示字符数,例如:
– 创建user表,指定用户名为char类型,字符长度不超过10
create table user(
username char(10),
...
);
所谓的定长,是当插入的数据的长度小于指定的长度时,剩余的空间会用空格填充。(这样会浪费空间)
char类型往往用于存储长度固定的数据。
2、varchar(n) 变长字符串,最长不超过65535个字节,n表示字符数,一般超过255个字符,会使用text类型,例如:
iso8859-1码表:一个字符占用1个字节,1*n < 65535, n最多等于 65535
utf8码表:一个中文汉字占用3个字节,3*n < 65535,n最多等于 65535/3
GBK码表:一个中文汉字占用2个字节,2*n < 65535,n最多等于 65535/2
– 创建user表,指定用户名为varchar类型,长度不超过10个字符
create table user(
username varchar(10)
);
所谓的不定长,是当插入的数据的长度小于指定的长度时,剩余的空间可以留给别的数据使用。(节省空间)
总结:长度固定的数据,用char类型,这样既不会浪费空间,效率也比较高
如果长度不固定,使用varchar类型,这样不会浪费空间。
3、大文本(长文本)类型
最长65535个字节,一般超过255个字符列的会使用text。
– 创建user表:
create table user(
resume text
);
另外,text也分多种,其中bigtext存储数据的长度约为4GB。
扩展内容3:(面试题)char(n)、varchar(n)、text都可以表示字符串类型,其区别在于:
(1)char(n)在保存数据时,如果存入的字符串长度小于指定的长度n,后面会用空格补全,因此可能会造成空间浪费,但是char类型的存储速度较varchar和text快。
因此char类型适合存储长度固定的数据,这样就不会有空间浪费,存储效率比后两者还快!
(2)varchar(n)保存数据时,按数据的真实长度存储,剩余的空间可以留给别的数据用,因此varchar不会浪费空间。
因此varchar适合存储长度不固定的数据,这样不会有空间的浪费。
(3)text是大文本类型,一般文本长度超过255个字符,就会使用text类型存储。
日期类型
date:年月日
time:时分秒
datetime:年月日 时分秒
timestamp:时间戳(实际存储的是一个时间毫秒值),与datetime存储日期格式相同。两者的区别是:
-
timestamp最大表示2038年,而datetime范围是1000~9999
-
timestamp在插入数据、修改数据时,可以自动更新成系统当前时间(后面用到时再做讲解)
mysql的字段约束
字段约束/列约束 --> 约束: 限制
主键约束
主键约束:如果为一个列添加了主键约束,那么这个列就是主键,主键的特点是唯一且不能为空。
主键的作用: 作为一个唯一标识,唯一的表示一条表记录(作用类似于人的身份证号,可以唯一的表示一个人一样。)
添加主键约束,例如将id设置为主键:
create table stu(
id int primary key,
...
);
如果主键是数值类型,为了方便插入主键(并且保证插入数据时,主键不会因为重复而报错),可以设置一个主键自增策略。
create table stu(
id int primary key auto_increment,
...
);
主键自增策略是指:设置了自增策略的主键,可以在插入记录时,不给id赋值,只需要设置一个null值,数据库会自动为id分配一个值(AUTO_INCREMENT变量,默认从1开始,后面依次+1),这样既可以保证id是唯一的,也省去了设置id的麻烦。
将id主键设置为自增:
create table stu(
id int primary key auto_increment,
...
);
非空约束
非空约束:如果为一个列添加了非空约束,那么这个列的值就不能为空,但可以重复。
添加非空约束,例如为password添加非空约束:
create table user(
password varchar(50) not null,
...
);
唯一约束
唯一约束:如果为一个列添加了唯一约束,那么这个列的值就必须是唯一的(即不能重复),但可以为空。
添加唯一约束,例如为username添加唯一约束及非空约束:
create table user(
username varchar(50) unique not null,
...
);
外键约束
外键其实就是用于通知数据库两张表数据之间对应关系的这样一个列。
这样数据库就会帮我们维护两张表中数据之间的关系。
(1) 创建表的同时添加外键
create table emp(
id int,
name varchar(50),
dept_id int,
foreign key(dept_id) references dept(id)
);
(1)如果是要表示两张表的数据之间存在对应关系,只需要在其中的一张表中添加一个列,保存另外一张表的主键,就可以保存两张表数据之间的关系。
但是添加的这个列(dept_id)对于数据库来说就是一个普通列,数据库不会知道两张表存在任何关系,因此数据库也不会帮我们维护这层关系。
(2)如果将dept_id列设置为外键,等同于通知数据库,部门表和员工表之间存在对应关系,dept_id列中的数据要参考部门的主键,数据库一旦知道部门和员工表之间存在关系,就会帮我们维护这层关系。
Alter
现创建学生表:
use test; -- 进入test库
drop table if exists stu; -- 删除学生表(如果存在)
create table stu( -- 创建学生表
id int, -- 学生id
name varchar(20), -- 学生姓名
gender char(1), -- 学生性别
birthday date -- 出生年月
);
修改表—新增列
语法:ALTER TABLE tabname ADD col_name datatype [DEFAULT expr][,ADD col_name datatype…];
1、往stu表中添加score列,double类型
alter table stu add score double;
修改表—修改列
语法:ALTER TABLE tabname MODIFY (col_name datatype [DEFAULT expr][,MODIFY col_name datatype]…);
1、修改id列,将id设置为主键
alter table stu modify id int primary key;
2、修改id列,将id主键设置为自动增长
alter table stu modify id int auto_increment;
修改表—删除列
语法:ALTER TABLE tabname DROP [COLUMN] col_name;
1、删除stu表中的score列
alter table stu drop score;
添加或删除主键及自增
思考:a) 在建表时,如何为id指定主键约束和自增?
b) 建好的表,如何通过修改添加主键约束和自增?
c) 如何删除表中的主键约束和自增?
1、创建stu学生表,不添加主键自增, 查看表结果
use mydb1; -- 切换到mydb1库
drop table if exists stu; -- 删除stu学生表(如果存在)
create table stu( -- 重建stu学生表,没有主键自增
id int,
name varchar(20),
gender char(1),
birthday date
);
desc stu; -- 查看表结构
表结构如下: 没有主键约束和自增。
2、如果表没有创建,或者要删除重建,在创建时可以指定主键或主键自增
drop table if exists stu; -- 删除stu表
create table stu( -- 重新创建stu表时,指定主键自增
id int primary key auto_increment,
name varchar(20),
gender char(1),
birthday date
);
desc stu; -- 查看表结构
表结构如下: 已经添加了主键约束和自增。
3、如果不想删除重建表,也可以通过修改表添加主键或主键自增
再次执行第1步,创建stu学生表,不添加主键自增,查看表结果
– 例如: 将stu学生表中的id设置为主键和自动增长
alter table stu modify id int primary key auto_increment;
desc stu; -- 查看表结构
如果只添加主键约束,不设置自增
alter table stu modify id int **primary key**;
如果已经添加主键约束,仅仅设置自增,但需注意:
(1)如果没有设置主键,不可添加自增
(2)只有当主键是数值时,才可以添加自增
alter table stu modify id int **auto_increment**;
4、如果想删除主键自增
– 删除主键自增时,要先删除自增
alter table stu modify id int;
– 再删除主键约束
alter table stu drop primary key;
desc stu; -- 查看表结构
添加外键约束
1、添加外键方式一:建表时添加外键
现有部门表如下:
– 创建部门表
create table dept(
id int primary key auto_increment, -- 部门编号
name varchar(20) -- 部门名称
);
要求创建员工表,并在员工表中添加外键关联部门主键
– 创建员工表
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(20), -- 员工姓名
dept_id int, -- 部门编号
foreign key(dept_id) references dept(id) -- 指定dept_id为外键
);
2、添加外键方式二:建表后添加外键
现有部门表和员工表:
– 创建部门表
create table dept(
id int primary key auto_increment, -- 部门编号
name varchar(20) -- 部门名称
);
– 创建员工表
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(20), -- 员工姓名
dept_id int -- 部门编号
);
– 如果表已存在,可以使用下面这种方式:
alter table emp add constraint fk_dept_id foreign key(dept_id) references dept(id);
其中 fk_dept_id (名字由自己定义),是指外键约束名称,也可以将【constraint fk_dept_id】省略,MySQL会自动分配一个外键名称,将来可以通过该名称删除外键。
foreign key(dept_id)中的dept_id为外键
删除外键约束
1、首先通过 “show create table 表名”语法,查询含有外键表的建表语句,例如:
show create table emp;
显示结果如下:
其中,emp_ibfk_1是在创建表时,数据库为外键约束指定的一个名字,删除这个名字即可删除外键关系,例如:
alter table emp drop foreign key emp_ibfk_1;
外键删除成功!
添加外键约束(多对多)
– 现有学生(stu)表和教师(tea)表:
– 创建学生表
create table stu(
stu_id int primary key auto_increment, -- 学生编号
name varchar(20) -- 学生姓名
);
– 创建教师表
create table tea(
tea_id int primary key auto_increment, -- 教师编号
name varchar(20) -- 教师姓名
);
– 添加第三方表(stu_tea)表示学生表和教师表关系
– 创建学生和教师关系表
create table stu_tea(
stu_id int, -- 学生编号
tea_id int, -- 教师编号
primary key(stu_id,tea_id), -- 设置联合主键
foreign key(stu_id) references stu(stu_id), -- 添加外键
foreign key(tea_id) references tea(tea_id) -- 添加外键
);
其中为了防止重复数据,将stu_id和tea_id设置为联合主键。
将stu_id设置为外键,参考stu表中的stu_id列
并将tea_id设置为外键,参考tea表中的tea_id列
级联更新、级联删除
– 创建db20库、dept表、emp表并插入记录
– 删除db20库(如果存在),并重新创建db20库
drop database if exists db20;
create database db20 charset utf8;
use db20;
– 创建部门表, 要求id, name字段
create table dept(
id int primary key auto_increment, -- 部门编号
name varchar(20) -- 部门名称
);
– 往部门表中插入记录
insert into dept values(null, '财务部');
insert into dept values(null, '人事部');
insert into dept values(null, '科技部');
insert into dept values(null, '销售部');
– 创建员工表, 要求id, name, dept_id
create table emp(
id int primary key auto_increment, -- 员工编号
name varchar(20), -- 员工姓名
dept_id int, -- 部门编号
foreign key(dept_id) references dept(id) -- 指定外键
on update cascade -- 级联更新
on delete cascade -- 级联删除
);
insert into emp values(null, '张三', 1);
insert into emp values(null, '李四', 2);
insert into emp values(null, '老王', 3);
insert into emp values(null, '赵六', 4);
insert into emp values(null, '刘能', 4);
级联更新:主表(dept表)中的主键发生更新时(例如将销售部的id改为40),从表(emp表)中的记录的外键数据也会跟着该表(即赵六和刘能的部门编号也会更新为40)
级联删除:如果不添加级联删除,当删除部门表中的某一个部门时(例如删除4号部门),若该部门在员工表中有对应的员工(赵六和刘能),删除会失败!
若果添加了级联删除,当删除部门表中的某一个部门时,若该部门在员工表中有对应的员工,会在删除部门的同时,将员工表中对应的员工也删除!
where中不能使用列别名
SQL语句的书写顺序:
select * | 列名 -- 确定要查询的列有哪些
from 表名 -- 确定查询哪张表
where 条件 -- 通过筛选过滤,剔除不符合条件的记录
group by 分组的列 -- 指定根据哪一列进行分组
having 条件 -- 通过条件对分组后的数据进行筛选过滤
order by 排序的列 -- 指定根据哪一列进行排序
limit (countPage-1)*rowCount, rowCount -- 指定返回第几页记录以及每页显示多少条
SQL语句的执行顺序:
from 表名 -- 确定查询哪张表
where 条件 -- 通过筛选过滤,剔除不符合条件的记录
select * | 列名 列别名 -- 确定要查询的列有哪些,
group by 分组的列 -- 指定根据哪一列进行分组
having 条件 -- 通过条件对分组后的数据进行筛选过滤
order by 排序的列 -- 指定根据哪一列进行排序
limit (countPage-1)*rowCount, rowCount
**** 关于where中不能使用列别名但是可以使用表别名?**
是因为,表别名是声明在from中,from先于where执行,先声明再使用没有问题,但是列别名是声明在select中,where先于select执行,如果先使用列别名,再声明,这样执行会报错!!