数据类型
数值类型:
- tinyint:1字节,-128~127,0~255
- smallint:2字节,-32768~32767,0~65535
- mediumint:3字节 ,-8388608~8388607 ,0~16777215
- int :4字节,-2147483648~2147483647……
- bigint:8字节
越界测试:
- create table tt1(num tinyint);
- insert into tt1 values(1);//成功
- insert into tt1 values(128);//失败,越界
在MySQl中,整形可以指定是有符号和无符号的,但是默认是有符号的
可以通过UNSIGNED来说明某个字段的无符号的
- create table tt2(num tinyint unsigned);
- insert into tt2 values(255);//成功
- insert into tt2 values(-1);//失败,无符号的
关于unsigned细节
unsigned为无符号,表示非负数,但是在事件使用中会带来一些负面的影响
创建一个表,俩个字段都是无符号
- create table tt3(a int unsigned ,b int unsigned);
- insert into tt3 values(1,2);
- select * from tt3;
- select a-b from tt3; //显示a-b为4294967295
- set sql_mode='NO_UNSIGNED_SUBTRACTION'
注:尽量不要使用unsigned,因为可能会带来一些意想不到的结果,对于int放不下的数据可能unsigned int同样放不下,与其如此,还不如直接将int提升为bigint。
bit的使用:
bit[(M)]:位字段,M表示每个值的位数,范围从1~64,如果M被忽略,默认为1
- create table tt4(a int ,b bit(8));
- insert into tt4 values(10,10);
- select * from tt4; //会发现,a的数据10没有出现
注:bit字段显示时,是按照ASCII码对应的值显示的
- insert into tt4 values(65,65);
- select * from tt4; // 65 A
小数的基本使用:
1.float[(m,d)][unsigned];m指定显示长度,d指定小数位数,占空间4个字节
- create table tt6(id int,salary float(4,2));
小数float(4,2)表示的范围时-99.99~99.99,MySql中保存至时会四舍五
2.decimal[(m,d)][unsigned]; m指定长度,d表示小数点的位数
- decimal整数的最大位数m为65,支持小数的最大位数d是30,如果d被省略,默认为0,如果m被省略,默认为10
- 看起来和float差不多,但是他们表示的精度不一样,decimal的精度更高。
字符串
- char(L):固定长度字符串,L表示可以存储的长度,单位是字符,最大长度可以为255
- varchar(L):可变长度字符串,L表示字符长度,最大长度65535个字节
- 验证char
create table tt9(id int,name char(2));
insert into tt9 values(100,'ab');
insert into tt9 values(100,'中国');
//char(2)表示可以存放俩个字符,可以是字母或汉字,但不能超过2个
//char最大为255
- 测试varchar
create table tt10(id int ,name varchar(6));
insert into tt10 values(100,'hello');
insert into tt10 values(100,'我爱你,中国');
- char和varchar的选择
- 如果数据的长度都是一样的(char),就使用定长,比如身份证,手机号……
- 如果数据长度是有变化的,就用变长的(varchar),比如名字,地址
- 定长的磁盘空间比较浪费,但是效率高
- 变长的磁盘空间比较节省,但是效率低
日期和时间类型:
- fatetime时间格式‘yyy-mmm-dd HH:ii:ss’表示范围从1000到9999,占8字节
- date日期:“yyy-mmm-dd” 占3字节
- timestamp:时间戳,从1970年开始的‘yyy-mm-dd HH:ii:ss’格式和datetime完全一致,占4字节
//创建一个表
- create table birthday (t1 date ,t2 datetime,t3 timestamp);
//插入数据
- insert into birthday(t1,t2) values('1997-7-1','2008-8-8 12:1:1');
//更新数据
- update birthday set t1=‘2000-1-1’;
枚举和set
- 枚举:enum,列出多个选项但是只能选其中的一个(单选),处于效率考虑,这些值的时间存储是“数字”,每个选项对应一个数字,最多65535,添加枚举时,可以直接添加其对应的数字(枚举从1开始)
- set:就是多选,设定时实际存储的是数字,依次对应“1,2,4,8,16……”最多64个
需求:一个调查表votes,调查人的喜好(登山,篮球,游泳,武术)中去选择,可以多选
男,女(选项)
- create tables votes(
- username varchar(30),
- hobby set('登山',‘篮球’,‘游泳’,‘武术’),
- gender enum(‘男’,‘女’)
- );
//插入数据:
- inster into votes values('张三','登山,武术','男');
//查询语句:
- select* from votes where hobby ='登山';
- //这样只能查询出爱好只有登山的人,而有些人的爱好有很多,登山只是其中的一部分,所以就查询不出来
要使用find_in_set(sub,str_list)查询
- select* from votes where find_in_set('登山',hobby);
//如果sub在str_list中,则返回下标,如果不在,返回0
表的约束:
空属性:
- null(默认的)和not null(不为空)
- 数据库默认的字段基本都为空,但是实际开发时,尽可能保证字段不为空,因为数据为空没办法参与运算
创建一个班级表,包含班级名和班级所在的教室,如果没有班级名字,不知道你在哪个教室上课,如果教室名字可以为空,就不知道在哪上课。
- cteate table class(
- class_name varchar(20) not null,
- class_name varchar(10) not null);
- inster into myclass(class_name)values('class1'); //插入失败,没有给教室数据
默认值:
- default:某一种数据会经常性的出现某个具体的值,可以在一开始就指定好,在需要真实数据的时候,用户可以选择性的使用默认值
注:set和enum不能设置为默认值
- create table tt10(
- name varchar(20) not null,
- age tinyint unsigned default 0,
- sex char(2) defalut '男');
列描述:
- 列描述comment没有实际含义,通过desc看不到注释信息,通过show可以看到
zerofill:
主键:
主键:primary key
- 用来唯一的约束该字段里面的数据,不能重复,不能为空,主键所在的列是整数类型
- 一张表最多只能由一个主键
创建表的时候直接在字段上指定主键
- create table tt13(
- id int unsigned primary key comment '学号不能为空',
- name varchar(20)not null
- );
在创建表的时候,在所有字段之后,使用primary key来创建主键,如果由多个字段多为主键,可以使用复合主键
- create table tt14(
- id int unsigned,
- course char(10) comment '课程代码',
- score tinyint unsigned default 60 comment '成绩',
- primary key(id,course));
表创建好以后可以在追加主键
- alter into tt13 add primary key(字段)
主键约束:主键对应的字段不能重复,一旦重复,操作失败
- 删除主键:alter table 表名 drop primary key;
自增长:
auto_increment:对应的字段不给值,就会自动的被系统触发,系统会从当前字段,已经有的最大值+1操作,得到一个新的不同的值,通常和主键搭配使用,作为逻辑主键
特点:
- 如何一个字段要做自增长,前提是本身是一个索引(key一栏有值)
- 自增长字段必须是整数
- 一张表最多只能有一个自增长
唯一键:
unique:一张表中往往有多个字段需要唯一性,数据不能重复,但是一张表中只能有一个主键,唯一键就可以解决表中有多个字段需要唯一约束的问题
- 唯一键的本质和主键差不多,唯一键允许为空,而且可以多个为空,空字段不做唯一性比较
表的增删查改:
增加:
- 语法:insert into tablename values()
例:创建一张商品表
- create table goods(
- id int unsigned primary key,
- goods_name varchar(50) not null default ' ',
- price float not null defalt 0.0
- );
插入俩条记录:
- insert into goods values(100,' 牛排',78.5);
- insert into goods values(100,‘披萨’,27.5);
- 插入的数据应用字段的数据类型相同
- 数据的大小应在规定范围内
- 在values中列出的数据位置必须与加入的列的位置相对应
- 日期和字符类型应包含在单引号内
- 插入空值,不指定或insert into table values(null)
- insert into table values(),(),()一次性添加多条记录
- 如果给表中的字段添加数据,可以不写前面的字段名称,但是给指定的字段添加数据,则需要写字段名
增加进阶:
- 在添加数据的时候,假设主键对应的值已经存在了 :插入失败
- 当主键冲突时,可以选择以下方式进行处理
1)更新操作
- insert table into goods values('101','ccc',20.5);
//提醒添加失败,id是主键,id=101,已经存在,所以不能赋值
- insert table into goods values on duplicate key update good_name='ccc',price=20.5;
2)替换:主键如果没有冲突,就之间插入
- replace into goods values(100,’华为‘,999);
修改
更新表中的数据
语法:update tbl_name set col_name1=expr1 where 列
例:
- 将所有产品的价格修改为300快
update goods set price=300//没有条件,整表修改
- 将id为100的产品价格修改为1000
update goods set price=1000 where id=100;
- 将id为101的产品价格增加200块
update goods set price=price 200 where id=101;
update使用细节:
- update语法可以用新值更新源有表中的各列
- set子句指示要修改哪些列和要给予哪些值
- where语句指示要更新哪些行,如果没有where语句就跟新所有行
- 如果需要更新多个字段,可以通过set字段1=值1,字段2=值2
更新还可以限制更新数量
update 表名 set 字段=值 [where 条件] [limit 更新数量]
例:
goods表中有五条ccc产品,我们希望将前三条改成ddd
- update goods set goods_name='ddd' where goods_name='ccc' limit 3;
删除:
语法:delete from tlb_name [where condition]
删除表中id为101的数据
- delete from goods where id=101;
删除时,可以复制一份表,避免数据删没了
- 复制表结构:create table goods2 like goods;
- 把goods表中的数据复制到goods2中:insert into goods2 select * from goods;
- 删除表中记录:delete from goods;//删除表中的数据,但是表的结构还在
- 使用truncate删除表中记录:truncate table goods;//这个指令把真个表记录删除
delete和truncate删除整表的区别:
- 效果一样,但是truncate速度快
- delete可以带where条件,删除更灵活
- delete可以返回被删除的记录数,而truncate返回0
- 推荐使用delete
delete使用细节
- 如果不使用where子句,将删除整个表中所有数据
- delete语句不能删除某一列的值(可以使用update置null)
- 使用delete语句仅删除记录,不删除表本身(drop table)
select
语法:select */{column1,column2……} from table;
- 指定查询某些列:查询id,name,math
selete id,name,math from student;
- *表示查询所有列(*的效率低,用哪些字段就取哪些字段)
- distinct:如果结果中有重复行,就删除重复行
select distinct math from student;
- select 语句中可以使用表达式对查询的列进行计算
- select语句中可以使用as对列起别名
- select column as 名字 from 表;
例:
1.在所有学生总分数上加十分
- select id,name,(math+chinese+english)+10 as total from student;
2.将所有姓唐的学生成绩增加60%
- select name ,(math+Chinese+English)*1.6 as total from student where name like '唐%'
select 的where语句
- between…and…:在某区间内;
- in(a,b):列表中的值
- like,not like :模糊查询
- and,or,not :与,或,非
查询姓李的学生的成绩:
- select * form student where name like '李%';
查询英语成绩大于90分的同学:
- select * from student where English>90;
查询总分大于200的所有同学
- select name,(math+english+chinese)as 'total' from student where math+english+chinese>200;
查询姓李并且id>10的同学
- select * from student where name like ‘李%’ and id>10;
查询英语成绩大于语文成绩的同学
- select * from student where English>chinese;
查询总分>200分并且数学成绩小于语文成绩的姓唐的学生
- select* from student where english+math+chinese>200 and math<chinese and name like '唐%';
查询英语成绩在80~90之间的同学
- select * from student where english between 80 and 90;
查询数学成绩为89,90,91的同学
- select * from student where math in(98,90,91);
select的order by语句
语法:select column1 …from table order by column asc/desc…
- order by指定排序的列,排序可以使用表中的列名,也可以使用别名
- asc,升序(从小到大),desc 降序(从大到小)
- order by 子句应该位于select语句的结尾
对数学成绩进行排序:
- select * from student order by math;
对总分进行排序后,按从高到低输出
- select id,name,math+English+Chinese as total from student order by total desc;
对姓李的学生按成绩进行从低到高排序
- select id,name,math+english+chinses as total from student where name like ‘李%’ order by total asc;
count:返回某列,行的总数
- 语法:select count(*)/count(列名) from table where condition
例:
统计一个班级有多少学生
- select count(id)from table ;//对某个列名进行统计,不包含null值
统计数学成绩大与等于90的学生人数
- select count(*)from student where math>=90;
统计总分大于250的人数
- select count(*)from student where math+e+c>250;
- count(*)会统计一共的记录数,count(列名)会派出null情况
sum:返回满足where条件的行的和
- 语法:select sum(列名) from table [where…]
例:
统计一个班的数学总成绩
- select sum(math)from student;
统计一个班级语文,英语,数学各科的总成绩
- select sum(Chinese),sum(math),sum(english)from student;
统计一个班语文,英语,数学的成绩总和
- select sum(c+e+m)from student
统计一个班的语文成绩 的平均成绩
- select sum(chinense)/count(name)from student;
注:sum仅对数值起作用,否则结果无意义
avg:返回满足where条件的一列的平均值
求一个班级的数学平均分
- select avg(math)from student;
求一个班及总分平均值
- select avg(m+c+e) from student;
max/min:返回满足where条件的最大/最小值
- 语法:select max(列名) from table [where…];
例:
求班级最高分和最低分
- select max(c+e+m),min(c+e+m)from student;
group by:对子句进行分组
- 语法:delect column1… from table group by column
显示一个部门的最高工资和平均工资
- select deptno,max(sal),avg(sal)from EMP group by deptno;
显示每个部门每个岗位平均工资和最低工资
- select depton,job,min(sal),avg(sal)from EMP group by depton ,job;
显示平均工资低于2000的部门和他的平均工资
- select depton,avg(sal)from EMP gurop by depton having avg(sal)<2000;
函数:
常用日期函数:
- current_date():获取年月日
- current_time():获取时分秒
- current_timestamp():获取使劲戳
- date(datetime):返回datetime的日期部分
- date_add(date2,interval date):在date2上加上一个时间
- date_sub(date2, interval date):在date2上减去一个时间
- datedeff(date1,date2):俩个日期差(结果是天数)
- now():当前时间