目录:
1.列属性--主键
2.列属性--自增
3.列属性--唯一键
4.索引
5.关系
6.范式
7.数据高级操作--主键冲突
8.蠕虫复制
9.更新数据时limit限制更新多少条记录
10.删除操作
11.查询的高级操作
12.字段别名
13.查询--where子句
14.group by子句
15.having子句
16.order by子句
17.limit子句
1.列属性--主键 <--返回目录
* 主键:primary key,一张表只能有一个字段可以使用对应的键,用来唯一的约束该字段里面的数据,
不能重复;一张表只能有一个主键;
* SQL增加主键
- 方法一:
create table tb_stu(
sid varchar(32) primary key comment ‘学号:itcast+0000‘,
name varchar(20) not null comment ‘姓名‘
)charset utf8;
- 方法二:
create table tb_stu(
sid varchar(32) comment ‘学号:itcast+0000‘,
number varchar(50) comment ‘身份证号‘,
name varchar(20) not null comment ‘姓名‘,
primary key(sid,number) -- 复合主键
)charset utf8;
- 方法三:当表已经创建好,追加主键
alter table tb_stu add primary key(字段列表);
* 主键约束特点:非空,唯一,被引用
* 删除主键:alter table tb_stu drop primary key;
* 【业务主键和逻辑主键】
在实际开发中,一般不会将业务字段设置为主键,通常使用没有业务含义的逻辑主键。
create table tb_stu(
id int primary key auto_increment comment ‘逻辑主键‘,
name varchar(20)
)charset utf8;
2.列属性--自增 auto_increment <--返回目录
* auto_increment:当对应的字段不给值,或者给默认值,或者给null值,触发自增。
create table tb_stu(
id int primary key auto_increment comment ‘逻辑主键‘,
name varchar(20)
)charset utf8;
插入一条记录:insert into tb_stu values (null,‘zs‘);
然后查询创建语句:show create table tb_stu;
结果:
CREATE TABLE `tb_stu` (
`id` int(11) NOT NULL AUTO_INCREMENT COMMENT ‘逻辑主键‘,
`name` varchar(20) DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=MyISAM AUTO_INCREMENT=2 DEFAULT CHARSET=utf8
* 某个字段能使用auto_increment,需要满足两个条件:
1)该字段是一个索引,即表结构key栏有值(desc 表名查询表结构);
2)该字段列类型是整型。
* 一张表只能有一个自增字段
* 删除自增属性
自增长是字段的一个属性,可以通过modify来进行修改(保证字段没有auto_increment即可)
alter table tb_stu 字段名 列类型;
* 修改当前字段自增长的值 alter table tb_stu auto_increment=4; 新值必须更大
* 为什么自增起始值为1,步长为1?
查看自增变量 show variables like ‘auto_increment%‘;
3.列属性--唯一键 <--返回目录
* 唯一键unique key:唯一键默认允许数据为null,而且可以多个数据位null
* 一张表可以有多个唯一键
* 创建唯一键:
- 方法一:
create table tb_stu(
number int unique [key] comment ‘学号:唯一,允许为空‘
)charset utf8;
注意:唯一键的字段key显示为UNI;
当指定唯一键的字段同时指定not null,并且该表没有主键,desc表结构时该字段的key显示为PRI
- 方法二:
create table tb_stu(
number int comment ‘学号‘,
unique [key|index] [别名](number)
)charset utf8;
- 创建表后新增唯一键
alter table 表名 add unique key(字段列表);
* 删除唯一键
alter table 表名 drop index 唯一键的索引名(默认与字段名相同);
4.索引 <--返回目录
* 几乎所有的索引都是建立在字段上的
* 索引:系统根据某种算法,将已有的数据(未来可能更新的数据),单独建立一个文件,文件能够实现快速的匹配数据,并且
能够快速找到对应表中的记录。
* 索引的意义:
1)提升查询数据的效率
2)约束数据的有效性(唯一性等) 对数据进行约束,比如数据唯一性
* 增加索引的前提条件:索引本身会产生索引文件,有时候可能比数据文件还大,会消耗磁盘空间
* 如果某个字段需要作为查询的条件经常使用,那么可以使用索引
如果某个字段需要进行数据的有效性约束,比如主键,唯一键,可以使用索引
* mysql中提供的索引:
主键索引 primary key
唯一索引 unique key
全文索引 fulltext index myISAM引擎才可用,innodb不可用
普通索引 index
5.关系 <--返回目录
* 一对一
* 多对一
* 多对多
6.范式 <--返回目录
* 范式:Normal Format [?f?:mæt],是离散数学的知识,是为了解决一种数据的存储与优化的问题
保存数据的存储之后,凡是能够通过关系寻找出来的数据,坚决不再重复存储,终极目标是为了
减少数据的冗余
* 范式:是一种分层的规范,分为6层,每一层都比上一层更加严格,若要满足下一层范式,前提是满足上一层范式
* 6层范式:1NF,2NF...6NF;1NF是最底层,要求最低,6NF最高层,要求最严格
* 一般mysql只要满足前【3层范式】;范式在数据的设计中有指导意义,但不是强制规范
* 1NF:第一范式。在数据表存储数据的时候,如果表中设计的字段存储的数据,在取出来使用之前
还需要额外的处理(拆分),那么所表的设计不满足第一范式;第一范式要求字段的数据具有原子性,不可再分
* 2NF:第二范式。在数据表设计的过程中,如果有复合主键,且表中有字段并不是由整个主键来确定,而是
依赖主键中的某个字段(主键的部分);存在字段依赖主键的的部分的问题,称之为【部分依赖】。
第二范式就是要解决表设计不允许出现部分依赖。
举例: 学生表:复合主键 姓名 班级 ,性别学号等学生信息依赖姓名,而与班级无关,这就是部分依赖。
* 3NF:第三范式。前提是先满足第二范式。理论上讲,一张表中所有的字段都应该直接依赖主键(逻辑主键,代表的是业务主键),
如果表设计中存在一个字段,并不直接依赖主键,而是通过某个非主键字段依赖,最终实现依赖主键,把这种不是直接依赖主键
而是依赖非主键字段的依赖关系称之为【传递依赖】。第三范式就是要解决传递依赖的问题。
7.数据高级操作--主键冲突 <--返回目录
* 数据操作:增删改查
* 新增数据
- 基本语法 insert into tb_stu(字段1,字段2...)values(值1,值2...);
- 主键冲突,进行更新和替换
insert into 表名(字段列表,包含主键)values(值列表) on duplicate key update 字段=新值;
例子:主键冲突--更新
create table tb_stu (
id varchar(32) primary key,
name varchar(30),
age int
)charset utf8;
insert into tb_stu values(‘0001‘,‘张三‘,10);
insert into tb_stu values(‘0001‘,‘张三1‘,20) on duplicate key update name=‘张三11‘,age=30;
结果:2 row(s) affected,这条记录更新为 ‘0001‘ ‘张三11‘ 30
例子:主键冲突--替换
drop table tb_stu;
create table tb_stu (
id varchar(32) primary key,
name varchar(30),
age int
)charset utf8;
insert into tb_stu values(‘0001‘,‘张三‘,10);
replace into tb_stu values(‘0001‘,‘张三1‘,20); -- 结果:2 row(s) affected
如果没有主键冲突,replace语句直接插入,结果时候1 row(s) affected
8.蠕虫复制 <--返回目录
* 通过复制表创建新表
create table tb_stu like [数据库名.]tb_stu1; -- 同一数据库时,可以省略数据库名
* 蠕虫复制:先查询数据,然后将查出的数据新增一遍
insert into 表名(字段列表) select 字段列表/* from 表名;
* 蠕虫复制的意义:
1)从已有的表拷贝数据到新表;
2)可以让表中的数据膨胀到一定的数量级,测试表的压力以及效率
insert into tb_stu select * from tb_stu;
9.更新数据时limit限制更新多少条记录 <--返回目录
create table tb_stu (
id int primary key auto_increment,
name varchar(30),
age int
)charset utf8;
insert into tb_stu values(null,‘张三1‘,10),(null,‘张三2‘,20),(null,‘张三3‘,30);
update tb_stu set age = 50 where name like ‘张%‘ limit 3;
10.删除操作 <--返回目录
* delete from tb_stu where age = 10 limit 2; -- 限制删除2条记录
* truncate 表名; -- 先删除表,在重新创建表。如果有字段自增,会重置。
注意:执行该语句后,表中记录清空。
11.查询的高级操作 <--返回目录
* 查询完整语法
select [select选项] 字段列表/* from 数据源 [where条件子句] [group by子句]
[having子句] [order by子句] [limit子句];
* select选项 all 或 distinct
- all:不写默认就是all
- distinct:去除重复的记录
12.字段别名 <--返回目录
select name [as] ‘姓名‘, age [as] ‘年龄‘ from tb_stu;
select * from (select * from tb_stu) as s; -- 子查询的表别名必须要有
13.查询--where子句 <--返回目录
update stu set age = floor(rand()*20+20);
select * from stu where id = 1 || id = 2;==>select * from stu where id in (1,2);
14.group by子句 <--返回目录
* 分组的意思:为了统计数据;按组统计:按分组字段进行数据统计
* SQL提供了一系列统计函数
count(*/字段名):统计分组后的记录数,每一组有多少记录
max(字段名):统计每组中该字段的最大值
min(字段名):统计每组中该字段的最小值
avg(字段名):统计每组中该字段的平均值
sum(字段名):统计每组中该字段的和
* count(*/字段名):里面可以放*,也可以放字段名;统计某个字段时,null不统计。
* 分组后会自动排序,根据分组字段排序,默认升序
* 例子:
-- 创建表
create table tb_user(
id int primary key auto_increment,
username varchar(20),
`password` varchar(20),
gender varchar(10),
state tinyint -- 0:未激活,1:已激活
)charset utf8;
-- 插入数据
insert into tb_user values(null,‘张三‘,‘zhangsan‘,‘男‘,0),(null,‘李四‘,‘lisi‘,‘女‘,1),
(null,‘王五‘,‘wangwu‘,‘女‘,0),(null,‘赵六‘,‘zhaoliu‘,‘男‘,1),(null,‘小明‘,‘xiaoming‘,‘女‘,0);
-- 分组查询,对分组后查询的结果进行排序
select gender, count(*) c from tb_user group by gender order by c;
-- 多字段分组查询:
select gender,state,count(*) from tb_user group by gender,state;
-- group_concat(字段名):对分组的结果中的某个字段进行字符串连接
select gender,state,count(*),group_concat(username) from tb_user group by gender,state;
结果:
gender state count(*) group_concat(username)
女 0 2 王五,小明
女 1 1 李四
男 0 1 张三
男 1 1 赵六
-- 回溯统计
select gender,state,count(*),group_concat(username) from tb_user group by gender,state with rollup;
结果:
gender state count(*) group_concat(username)
女 0 2 王五,小明
女 1 1 李四
女 (NULL) 3 王五,小明,李四
男 0 1 张三
男 1 1 赵六
男 (NULL) 2 张三,赵六
(NULL) (NULL) 5 王五,小明,李四,张三,赵六
15.having子句 <--返回目录
* having子句:对查询结果,再次进行条件判断
* 例子1:
select gender, count(*) as total
from tb_user
group by gender
having total>=2;
* 例子2:
select name as ‘姓名‘, number as ‘学号‘
from tb_stu
having ‘姓名‘ like ‘张%‘;
* 能用where的尽量用where,where直接对数据源的数据进行判断,效率更高;
having是对结果集(查询的结果,保存内存中)进行判断
16.order by子句 <--返回目录
* roder by:排序
select * from tb_stu order by age [asc/desc];
asc:默认,升序
desc:降序
* 多字段排序:
select * from tb_stu order by age asc ,gender desc; -- 如果age相同,女的排前面
17.limit子句 <--返回目录
* limit子句:是一种限制结果的语句,限制数量
* limit有两种使用方式:
1)方式1:limit 数据量; //限制数据量
select * from tb_stu limit 2; -- 限制查询记录数据量为2
2)方式2:limit 起始位置,数据量; //用来实现数据的分页
select * from tb_stu limit 0,2;
---