===============================================================
元数据---------描述数据-----id name age sex class这样的
数据行---------实际数据-----002 张三 18 男 1503
对表结构或者数据库结构的操作 都是对元数据的操作--------DDL
对表内数据的修改-------------DML
默认值和自增什么时候生效
有几个字段,我只添加某几个字段,其余字段如果有默认值则会自动填充默认值
❗❗❗❗ char 类型需要 ' ' 引号引起来 ,int类型不需要(也可以用引号)
❗❗❗❗❗❗❗
truncate table 表名;清空表内的所有数据,会保留表结构;这时候再创建 自增的字段会从1开始
delete 删除数据 不会改变 表结构中的自增记录 这时候我在创建 自增字段 会从删除之前的那个值开始
drop table 表名 直接连表和表内数据全部删除 表结构都没有了
区别:
delete: DML操作, 是逻辑性质删除,逐行进行删除,速度慢.并没有从磁盘上真正删除。使用delete删除的时候,MySQL并没有把数据文件删除,而是将数据文件的标识位删除,没有整理文件,因此不会彻底释放空间。被删除的数据将会被保存在一个链接清单中,当有新数据写入的时候,MySQL会利用这些已删除的空间再写入。即,删除操作会带来一些数据碎片,正是这些碎片在占用硬盘空间。 磁盘空间不会立即释放。自增id还存在。产生大量碎片。
高水位线不会下降引起索引搜索性能问题,HWM
表的高度不变
truncate: DDL操作,对与表段中的数据页进行清空,速度快.
会立即释放空间。自增id会消失。物理层次删除。保留表结构。
drop:元数据和数据行物理层次删除。
插入数据:(行)
insert into 表名 (字段1,字段2,字段3) value('值1','值2','值3');
insert into 表名 value ('值1','值2','值3'),(’x','y','z');
insert into 表名 (字段2)value ('数据1'),(’数据2‘),(’数据3‘);(注意,其他未添加字段需要有默认值 或者 可以为空 或者 自增)
更新数据:(行中的某个值)
update 表名 set 字段名1='修改为的值' where 字段名1(也可以是其他)='原来值';
删除数据:(行)
delete from 表名 where 字段名=值;
DQL-------数据查询语句
(一)where
select xxx from 表名 [筛选条件];
执行顺序--------重点
1.from 表名:表1,表2。。。。
2.where 过滤条件:条件1,条件2
3.group by 列条件:
4.having 过滤条件:条件1,条件2
5.order by 条件列
6.limit 限制
多个条件 用 and 且
or 或者
where 字段名 in ("xxx","yyy) and 字段B>=XXX;
in ( ) ----------------在()内匹配任意值 (类似于或者的作用)
limit 5 只显示查找到的前五行
limit 5,6 显示第五行开始的6行
where 字段名 like 'zhang%' ----------模糊查找
❗❗❗注意,%不能放在前面 因为那样就不走索引了
(二)group by 配合聚合函数使用----------------分组
例如 统计来自同一个城市的人数
聚合函数:
max() :求最大值
min() :求最小值
avg() :求平均值
sum() :求总和
count() :统计个数
group_concat() : 列转行
顺序:
取数据---根据分组排序去重(group by)--- 配合函数(聚合)---生成需要数据
统计世界上每个国家的总人口数.
mysql>SELECT countrycode ,SUM(population) FROM city GROUP BY countrycode;
统计中国各个省的总人口数量(练习)
mysql>SELECT district,SUM(Population) FROM city WHERE countrycode='chn' GROUP BY district;
❗❗❗❗COUNT和sum的区别
count 数----------------求总数 一个一个数 比如数中国的城市有多少个 changsha shanghai
sum 算 ------------------求总和 相加 比如求几个城市的人数和 2222+3455+6454
group by 核心使用:
1。根据需求找出分组条件。
2。根据需求找出合适的聚合函数
【扩展】列转行的使用场景
例如 要查询 中国每个省里有多少个城市 以及城市名字
mysql> select district,name,count(name) from city where counytrycode='chn' group by district; ERROR 1054 (42S22): Unknown column 'counytrycode' in 'where clause'
发现报错
district(省) | name(城市) | count(name) 城市数 |
湖北 | 武汉 | xxx |
恩施 | ||
荆州 | ||
宜昌 | ||
襄阳 |
因为我们查询的 理想结果 应该是这样的
但是这样是无法显示的(原因:mysql不支持一列对应多行显示(5.7之后,5.7之前会默认选择id第一的那个数据) 此时用group_concat()改成横行显示。
需要用到列转行 -----------group_concat(要转行的列)
select district,group_concat(name),count(name) from city where countrycode='chn' group by district\G
将城市那一列 转成行显示
group by 图解 按省份分组 然后 聚合函数
having:类似where字句。做后过滤。
使用场景:需要在group by + 聚合函数后,再做过滤使用。 例子: 统计中国每个省的总人口数,只打印总人口数小于100w SELECT district,SUM(Population) FROM city WHERE countrycode='chn' GROUP BY district HAVING SUM(Population) < 1000000 ;
(为甚不直接将这个条件写在 where中?
因为 先执行 where 再执行 group by 然后 sum 再having
在where那一步 是拿不到 sum()的值 自然也无法用他来判断)
联表查询---------------内连接
语法:
select a.xx,a.yy,b.tt from 表1 as a join 表2 as b on a.pp=b.oo [where ..]
as -----------给表取别名 简化语句
on ------------两张表的关联条件 例如 两张表里都有国家名 那么国家名就可以作为关联条件
但是可能 两张表里的国家名 对应字段名不一样 例如 city-------countrycode country----code
❗❗❗❗注意:两张表的关联字段的数据类型必须一样 例如:char(3)和char(6)就不行
join-----------用来说明 要使用的两张表 (般来说,JOIN的顺序不重要,除非你要自己定制driving tabl)
联表查询可以不用担心 列转行
因为 一对多时 会自动 每一行都匹配那个只有一个的 如下图中的 surfacearea
也就是 笛卡尔积 显示
========================================================================
【扩展】
当两个表没有任何关联然后还需要查询拼接数据时,需找中间表。
例子:
在school库里面
查询zhang3,学习的课程名称有哪些?
SELECT st.sname , GROUP_CONCAT(co.cname) #显示学生名字和选择课程,因为课程多个,mysql不支持一次性单对多显示,需将多行改成列转行显示。
FROM student AS st #别名学生表
JOIN sc #学生表与成绩表有关联所以join
ON st.sno=sc.sno #学生表与成绩表关联项。
JOIN course AS co #学科表又与成绩表有关联所以join
ON sc.cno=co.cno #学科表与成绩表关联项
WHERE st.sname='zhang3' #筛选学生名字。
(没有关联的两张表可以传递关联,即a=b,b=c的关系)
from A join B on xx=yy join C on gg=kk [where ]
注意 join顺序 a~b b~c
中间位置的 必须是 中间表
=========================================================================
联合查询---------外连接
left join/right join
left join 左表所有数据和两表交集数据 一定要有on语法
left join 本质上指的是,join操作所筛选的数据+左边表全部数据的返回。
right join 本质相同,join操作筛选数据+右边表所有数据进行返回。
select 如果指定了左表要显示的 字段 那么会显示 左表要显示字段的全部数据 然后一条一条的去匹配右表要显示的内容 匹配到的会显示匹配结果 匹配不到的 以null 填充
注意 left join on and (这里用 and 而不是 where 如果用where那么left join 会失效 变成内连接)
外连接作用: 强制驱动表
会拿左表数据与关联表数据逐行匹配,最终得到匹配数据。 在left join 里面左表为驱动表。 建议: 将结果集小 的表设置为驱动表,会降低next loop的次数对于内连接无法控制。完全由优化器做主。人为干预则将内连接改成外连接。 会强制左表作为驱动表。
#内连接是先拼接后过滤,而外连接是优先过滤再拼接筛选。(不一定)
示例:
执行
SELECT article.aid,**article.title,**user.username** FROM article LEFT JOIN user ON article.uid = user.uid
可以看出来,与 INNER JOIN 明显的区别是,左表记录被全部取出,即使右表无对应匹配记录。
aid 4 对应的 uid 4 在user表中没有匹配的
但是他还是 会输出 只是对应的值显示 null
内连接---------内键
外连接---------外键
----------主键
联合查询-------------union all -------联合多条查询语句
SELECT * FROM city
WHERE countrycode IN ('CHN' ,'USA');
SELECT * FROM city WHERE countrycode='CHN'
UNION ALL
SELECT * FROM city WHERE countrycode='USA';
统计同一表下使用。
说明:一般情况下,我们会将 IN 或者 OR 语句 改写成 UNION ALL,来提高性能
UNION 将结果集自动去重复
UNION ALL 只取结果集不去重复
distinct (xxx) 应用: 去重复 SELECT countrycode FROM city ; SELECT DISTINCT(countrycode) FROM city ;
show processlist---------------查看数据库中活跃的线程
后面的info 就是该线程对应的命令
kill id号;--------------------可以将数据库中的对应线程杀死;
show
show grants for xxx---------------------查看xxx用户的 权限(只能看数据库用户的 不能看root的)
show index from 表名------------------查看某表的索引
show status; ---------------------查看数据库的状态
show status like '%%'; -----------模糊查询状态
show binary logs ------------------查询二进制日志
show binlog event in ---------------二进制文件;查询二进制日志事件
show create database world ----------- #查看建库语句
show create table world.city---------------#查看建表语句
show charset;----------------------------#查看字符集
show collation-----------------------------#查看校对规则
SHOW VARIABLES ----------------------#查看所有配置信息
show engines ----------------------------#查看支持的所有的存储引擎
show master status -------- #查看数据库的日志位置信息,开启主从使用,开启binlog日志用
show slave status -------------#查询从库状态。开启主从用
视图:
作用:保存了所有表的字典信息。
每次数据库启动会自动在内存中生成,以视图存储数据库元数据信息。
视图:sql语句的执行方法,不保存数据本身。
创建视图:
create view v_select as 某sql语句指的是select语句。
使用,select * from v_select;
DESC information_schema.TABLES #存储,数据库表的元数据属性。
TABLE_SCHEMA ---->库名
TABLE_NAME ---->表名
ENGINE ---->引擎
TABLE_ROWS ---->表的行数
AVG_ROW_LENGTH ---->表中行的平均行(字节)
INDEX_LENGTH ---->索引的占用空间大小(字节)
资产统计:------------以下是DBA常用工具性sql
查询整个数据库中所有库和所对应的表信息
SELECT table_schema,GROUP_CONCAT(table_name)
FROM information_schema.tables
GROUP BY table_schema;
统计所有库下的表个数
SELECT table_schema,COUNT(table_name)
FROM information_schema.TABLES
GROUP BY table_schema;
统计world数据库下每张表的磁盘空间占用
SELECT table_name,CONCAT((TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB")
AS size_KB
FROM information_schema.tables WHERE TABLE_SCHEMA='world';
统计所有数据库的总的磁盘空间占用
SELECT
TABLE_SCHEMA,
CONCAT(SUM(TABLE_ROWS*AVG_ROW_LENGTH+INDEX_LENGTH)/1024," KB") AS Total_KB
FROM information_schema.tables
GROUP BY table_schema;