MySQL day03 SQL基础

SQL基础

  • 数据类型
    • 数值类型
    • 字符类型
    • 时间类型
    • 二进制类型
  • 属性
    • 列属性
      • 约束
    • 表属性
  • DDL 数据定义语言
    • 库定义
      • 1.创建数据库
      • 2.删除(生产中禁止使用)
      • 3.修改
      • 4.查询
    • 表定义
      • 1.创建
      • 2.删除(生产中禁用命令)
      • 3.修改
      • 4.表属性查询(DQL)
  • DCL 数据控制语言
  • DML 数据操作语言
    • 1.insert
    • 2.update
    • 3.delete
  • DQL 数据查询语言(select)
    • 1.group by + 常用聚合函数
    • 2.having
    • 3.order by + limit
    • 4.distinct:去重复
    • 5.联合查询- union all
    • 6.join 多表连接查询
      • 1.别名
      • 2.多表SQL练习
    • 7.information_schema.tables视图
  • show 命令
  • 补充

数据类型

数值类型

MySQL day03 SQL基础_第1张图片

tinyint  : -128~127
int       :-2^31~2^31-1
说明:手机号是无法存储到int的。一般是使用char类型来存储收集号

字符类型

MySQL day03 SQL基础_第2张图片

char(11) :
定长 的字符串类型,在存储字符串时,最大字符长度11个,立即分配11个字符长度的存储空间,如果存不满,空格填充。
varchar(11):
变长的字符串类型看,最大字符长度11个。在存储字符串时,自动判断字符长度,按需分配存储空间。
enum('bj','tj','sh'):
枚举类型,比较适合于将来此列的值是固定范围内的特点,可以使用enum,可以很大程度的优化我们的索引结构。

时间类型

MySQL day03 SQL基础_第3张图片

DATETIME 
范围为从 1000-01-01 00:00:00.000000 至 9999-12-31 23:59:59.999999。
TIMESTAMP 
1970-01-01 00:00:00.000000 至 2038-01-19 03:14:07.999999。
timestamp会受到时区的影响

二进制类型

MySQL day03 SQL基础_第4张图片

属性

列属性

约束

约束(一般建表时添加):
**primary key** :主键约束
设置为主键的列,此列的值必须非空且唯一,主键在一个表中只能有一个,但是可以有多个列一起构成。
**not null**      :非空约束
列值不能为空,也是表设计的规范,尽可能将所有的列设置为非空。可以设置默认值为0
**unique key** :唯一键
列值不能重复
**unsigned** :无符号
针对数字列,非负数。

其他属性:
**key** :索引
可以在某列上建立索引,来优化查询,一般是根据需要后添加
**default**           :默认值
列中,没有录入值时,会自动使用default的值填充
**auto_increment**:自增长
针对数字列,顺序的自动填充数据(默认是从1开始,将来可以设定起始点和偏移量)
**comment ** : 注释

表属性

存储引擎:
InnoDB(默认的)
字符集和排序规则:
utf8       
utf8mb4

DDL 数据定义语言

库定义

1.创建数据库

create database school;
create schema sch;
show charset;
show collation;
CREATE DATABASE test CHARSET utf8;
create database xyz charset utf8mb4 collate utf8mb4_bin;

建库规范:
1.库名不能有大写字母   
2.建库要加字符集         
3.库名不能有数字开头
4. 库名要和业务相关

建库标准语句

mysql> create database db charset utf8mb4;
mysql> show create database xuexiao;

2.删除(生产中禁止使用)

mysql> drop database oldboy;

3.修改

SHOW CREATE DATABASE school;
ALTER DATABASE school  CHARSET utf8;
注意:修改字符集,修改后的字符集一定是原字符集的严格超集

4.查询

show databases;
show create database oldboy;

表定义

1.创建

create table stu(
列1  属性(数据类型、约束、其他属性) ,
列2  属性,
列3  属性
)


USE school;
CREATE TABLE stu(
id      INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname   VARCHAR(255) NOT NULL COMMENT '姓名',
sage    TINYINT UNSIGNED NOT NULL DEFAULT 0 COMMENT '年龄',
sgender ENUM('m','f','n') NOT NULL DEFAULT 'n' COMMENT '性别' ,
sfz     CHAR(18) NOT NULL UNIQUE  COMMENT '身份证',
intime  TIMESTAMP NOT NULL DEFAULT NOW() COMMENT '入学时间'
) ENGINE=INNODB CHARSET=utf8 COMMENT '学生表';


1. 表名小写
2. 不能是数字开头
3. 注意字符集和存储引擎
4. 表名和业务有关
5. 选择合适的数据类型
6. 每个列都要有注释
7. 每个列设置为非空,无法保证非空,用0来填充。

2.删除(生产中禁用命令)

drop table t1;

3.修改

1.在stu表中添加qq列

DESC stu;
ALTER TABLE stu ADD qq VARCHAR(20) NOT NULL UNIQUE COMMENT 'qq号';

2.在sname后加微信列

ALTER TABLE stu ADD wechat VARCHAR(64) NOT NULL UNIQUE  COMMENT '微信号' AFTER sname ;

3.修改数据类型

ALTER TABLE stu modify qq char(11) NOT NULL UNIQUE COMMENT 'qq号';

4.删除qq号列

ALTER TABLE stu drop qq

4.表属性查询(DQL)

use school
show tables;
desc stu;
show create table stu;
CREATE TABLE ceshi LIKE stu;

DCL 数据控制语言

grant 
revoke

DML 数据操作语言

1.insert

--- 最标准的insert语句
INSERT INTO stu(id,sname,sage,sg,sfz,intime) 
VALUES
(1,'zs',18,'m','123456',NOW());
SELECT * FROM stu;
--- 省事的写法
INSERT INTO stu 
VALUES
(2,'ls',18,'m','1234567',NOW());
--- 针对性的录入数据
INSERT INTO stu(sname,sfz)
VALUES ('w5','34445788');
--- 同时录入多行数据
INSERT INTO stu(sname,sfz)
VALUES 
('w55','3444578d8'),
('m6','1212313'),
('aa','123213123123');
SELECT * FROM stu;

2.update

DESC stu;
SELECT * FROM stu;
UPDATE stu SET sname='zhao4' WHERE id=2;
注意:update语句必须要加where。

3.delete

DELETE FROM stu  WHERE id=3;

全表删除:

DELETE FROM stu
truncate table stu;
区别:
delete: DML操作, 是逻辑性质删除,逐行进行删除,速度慢.
truncate: DDL操作,对与表段中的数据页进行清空,速度快.

伪删除:用update来替代delete,最终保证业务中查不到(select)即可

1.添加状态列
ALTER TABLE stu ADD state TINYINT NOT NULL DEFAULT 1 ;
SELECT * FROM stu;
2. UPDATE 替代 DELETE
UPDATE stu SET state=0 WHERE id=6;
3. 业务语句查询
SELECT * FROM stu WHERE state=1;

DQL 数据查询语言(select)

-- select @@xxx 查看系统参数
SELECT @@port;
SELECT @@basedir;
SELECT @@datadir;
SELECT @@socket;
SELECT @@server_id;
SELECT NOW();
SELECT DATABASE();
SELECT USER();
SELECT CONCAT("hello world");
SELECT CONCAT(USER,"@",HOST) FROM mysql.user;
SELECT GROUP_CONCAT(USER,"@",HOST) FROM mysql.user;
https://dev.mysql.com/doc/refman/5.7/en/func-op-summary-ref.html?tdsourcetag=s_pcqq_aiomsg

1.group by + 常用聚合函数

根据 by后面的条件进行分组,方便统计,by后面跟一个列或多个列

常用聚合函数

**max()**      :最大值
**min()**      :最小值
**avg()**      :平均值
**sum()**      :总和
**count()**    :个数
group_concat() : 列转行
例子1:统计世界上每个国家的总人口数.
USE world
SELECT countrycode ,SUM(population)    FROM  city  GROUP BY countrycode;

例子2: 统计中国各个省的总人口数量(练习)
SELECT district,SUM(Population) FROM city  WHERE countrycode='chn' GROUP BY district;

例子3:统计世界上每个国家的城市数量(练习)
SELECT countrycode,COUNT(id)  FROM city GROUP BY countrycode;

2.having

例子4:统计中国每个省的总人口数,只打印总人口数小于100
SELECT district,SUM(Population)
FROM city
WHERE countrycode='chn'
GROUP BY district
HAVING SUM(Population) < 1000000 ;

3.order by + limit

应用案例


1.查看中国所有的城市,并按人口数进行排序(从大到小)
SELECT * FROM city WHERE countrycode='CHN' ORDER BY population DESC;

2.统计中国各个省的总人口数量,按照总人口从大到小排序
SELECT district AS 省 ,SUM(Population) AS 总人口
FROM city
WHERE countrycode='chn'
GROUP BY district
ORDER BY 总人口 DESC ;

3.统计中国,每个省的总人口,找出总人口大于500w的,并按总人口从大到小排序,只显示前三名
SELECT  district, SUM(population)  FROM  city 
WHERE countrycode='CHN'
GROUP BY district 
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 3 ;

LIMIT N ,M --->跳过N,显示一共M行
LIMIT 5,5

SELECT  district, SUM(population)  FROM  city 
WHERE countrycode='CHN'
GROUP BY district 
HAVING SUM(population)>5000000
ORDER BY SUM(population) DESC
LIMIT 5,5;

4.distinct:去重复

SELECT countrycode FROM city ;
SELECT DISTINCT(countrycode) FROM city  ;

5.联合查询- 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 不去重复

6.join 多表连接查询

案例准备

use school
student :学生表
sno:    学号
sname:学生姓名
sage: 学生年龄
ssex: 学生性别

teacher :教师表
tno:     教师编号
tname:教师名字

course :课程表
cno:  课程编号
cname:课程名字
tno:  教师编号

score  :成绩表
sno:  学号
cno:  课程编号
score:成绩

-- 项目构建
drop database school;
CREATE DATABASE school CHARSET utf8;
USE school

CREATE TABLE student(
sno INT NOT NULL PRIMARY KEY AUTO_INCREMENT COMMENT '学号',
sname VARCHAR(20) NOT NULL COMMENT '姓名',
sage TINYINT UNSIGNED  NOT NULL COMMENT '年龄',
ssex  ENUM('f','m') NOT NULL DEFAULT 'm' COMMENT '性别'
)ENGINE=INNODB CHARSET=utf8;

CREATE TABLE course(
cno INT NOT NULL PRIMARY KEY COMMENT '课程编号',
cname VARCHAR(20) NOT NULL COMMENT '课程名字',
tno INT NOT NULL  COMMENT '教师编号'
)ENGINE=INNODB CHARSET utf8;

CREATE TABLE sc (
sno INT NOT NULL COMMENT '学号',
cno INT NOT NULL COMMENT '课程编号',
score INT  NOT NULL DEFAULT 0 COMMENT '成绩'
)ENGINE=INNODB CHARSET=utf8;

CREATE TABLE teacher(
tno INT NOT NULL PRIMARY KEY COMMENT '教师编号',
tname VARCHAR(20) NOT NULL COMMENT '教师名字'
)ENGINE=INNODB CHARSET utf8;

INSERT INTO student(sno,sname,sage,ssex)
VALUES (1,'zhang3',18,'m');

INSERT INTO student(sno,sname,sage,ssex)
VALUES
(2,'zhang4',18,'m'),
(3,'li4',18,'m'),
(4,'wang5',19,'f');

INSERT INTO student
VALUES
(5,'zh4',18,'m'),
(6,'zhao4',18,'m'),
(7,'ma6',19,'f');

INSERT INTO student(sname,sage,ssex)
VALUES
('oldboy',20,'m'),
('oldgirl',20,'f'),
('oldp',25,'m');


INSERT INTO teacher(tno,tname) VALUES
(101,'oldboy'),
(102,'hesw'),
(103,'oldguo');

DESC course;
INSERT INTO course(cno,cname,tno)
VALUES
(1001,'linux',101),
(1002,'python',102),
(1003,'mysql',103);

DESC sc;
INSERT INTO sc(sno,cno,score)
VALUES
(1,1001,80),
(1,1002,59),
(2,1002,90),
(2,1003,100),
(3,1001,99),
(3,1003,40),
(4,1001,79),
(4,1002,61),
(4,1003,99),
(5,1003,40),
(6,1001,89),
(6,1003,77),
(7,1001,67),
(7,1003,82),
(8,1001,70),
(9,1003,80),
(10,1003,96);

SELECT * FROM student;
SELECT * FROM teacher;
SELECT * FROM course;
SELECT * FROM sc;

语法
MySQL day03 SQL基础_第5张图片

查询张三的家庭住址

SELECT A.name,B.address FROM
A JOIN  B
ON A.id=B.id
WHERE A.name='zhangsan'

例子:

1.查询一下世界上人口数量小于100人的城市名和国家名
SELECT b.name ,a.name ,a.population
FROM  city  AS a
JOIN  country AS b
ON    b.code=a.countrycode
WHERE  a.Population<100

2.查询城市shenyang,城市人口,所在国家名(name)及国土面积(SurfaceArea)
SELECT a.name,a.population,b.name ,b.SurfaceArea
FROM city  AS a JOIN country AS b
ON a.countrycode=b.code
WHERE a.name='shenyang';

1.别名

列别名,表别名
SELECT 
a.Name AS an ,
b.name AS bn ,
b.SurfaceArea AS bs,
a.Population AS bp
FROM city AS a  JOIN country AS b
ON a.CountryCode=b.Code
WHERE a.name ='shenyang';

2.多表SQL练习

每位老师所教课程的平均分,并按平均分排序

SELECT te.tname,AVG(sc.score)
FROM teacher AS te
JOIN course AS co
ON te.tno=co.tno
JOIN sc
ON co.cno=sc.cno
GROUP BY te.tname
ORDER BY AVG(sc.score) DESC ;

7.information_schema.tables视图

每次数据库启动,会自动在内存中生成I_S,以视图的方式存储数据库一部分元数据信息视图。I_S.tables 保存了所有表的数据字典信息

视图:基于 SQL 语句的结果集的可视化的表,是一个虚拟表,其内容由查询定义。
可理解为是 别名

select语句的执行方法,不保存数据本身
I_S中的视图,保存的就是查询元数据的方法
MySQL day03 SQL基础_第6张图片
MySQL教程之concat以及group_concat的用法
https://baijiahao.baidu.com/s?id=1595349117525189591&wfr=spider&for=pc

DESC information_schema.TABLES ——》 查看某张表的列情况
TABLE_SCHEMA ---->库名
TABLE_NAME ---->表名
ENGINE ---->引擎
TABLE_ROWS ---->表的行数
AVG_ROW_LENGTH ---->表中行的平均行(字节)
INDEX_LENGTH ---->索引的占用空间大小(字节)

如果没有i_s,那么2. 就会要进入到库,统计表个数,表名。
假如有100个库,一个个去弄就很麻烦。 因此利用i_s会方便很多

1.查询整个数据库中所有库和所对应的表信息
SELECT table_schema,GROUP_CONCAT(table_name)
FROM  information_schema.tables
GROUP BY table_schema;
这个group_contact 不能多行显示,直接一列显示多值

2.统计所有库下的表个数
SELECT table_schema,COUNT(table_name)
FROM information_schema.TABLES
GROUP BY table_schema;

3.统计每个库的占用空间总大小
一张表大小=AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH  
select table_schema,sum(AVG_ROW_LENGTH*TABLE_ROWS+INDEX_LENGTH ) from information_schema.tables group by table_shema;

4.查询业务数据库(系统表除外),所有非InnoDB表
select table_schema,table_name from information_schema.tables where engine !='InnoDB' and table_schema not in ('sys','performance_schema','information_schema','mysql');

44.查询业务数据库(系统表除外),所有非InnoDB表。将非InnoDB表转换为InnoDB,然后把结果集导入到sql文件(前提是要允许安全目录)
把批量的命令拼接出来,不同库的不同表

前提:vim /etc/my.cnf
[mysqld]
secure-file-priv=/tmp

select concat("alter table 	",table_schema,".",table_name," engine=innodb;") from information_schema.tables 
where engine !='InnoDB' 
and table_schema not in ('sys','performance_schema','information_schema','mysql')
into outfile 'tmp/alter.sql';
#mysql -uroot -p123456 

单表写法:
mysql> alter table world.myt1 engine=innodb;

________________________________________________________

6.查询所有innodb引擎的表及所在的库
SELECT table_schema,table_name,ENGINE FROM information_schema.`TABLES`
WHERE ENGINE='innodb';

7.统计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';

8.统计所有数据库的总的磁盘空间占用
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;
mysql -uroot -p123 -e "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;"

9.生成整个数据库下的所有表的单独备份语句
模板语句:
mysqldump -uroot -p123 world city >/tmp/world_city.sql
SELECT CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )
FROM information_schema.tables
WHERE table_schema NOT IN('information_schema','performance_schema','sys')
INTO OUTFILE '/tmp/bak.sh' ;

CONCAT("mysqldump -uroot -p123 ",table_schema," ",table_name," >/tmp/",table_schema,"_",table_name,".sql" )


10.107张表,都需要执行以下2条语句
ALTER TABLE world.city DISCARD TABLESPACE;
ALTER TABLE world.city IMPORT TABLESPACE;
SELECT CONCAT("alter table ",table_schema,".",table_name," discard tablespace")
FROM information_schema.tables
WHERE table_schema='world'
INTO OUTFILE '/tmp/dis.sql';

show 命令

show  databases;                          #查看所有数据库
show tables;                                          #查看当前库的所有表
SHOW TABLES FROM                        #查看某个指定库下的表
show create database world                #查看建库语句
show create table world.city                #查看建表语句
show  grants for  root@'localhost'       #查看用户的权限信息
show  charset;                                   #查看字符集
show collation                                      #查看校对规则
show processlist;                                  #查看数据库连接情况
show index from                                 #表的索引情况
show status                                         #数据库状态查看
SHOW STATUS LIKE '%lock%';         #模糊查询数据库某些状态
SHOW VARIABLES                             #查看所有配置信息
SHOW variables LIKE '%lock%';          #查看部分配置信息
show engines                                       #查看支持的所有的存储引擎
show engine innodb status\G               #查看InnoDB引擎相关的状态信息
show binary logs                                    #列举所有的二进制日志
show master status                                 #查看数据库的日志位置信息
show binlog evnets in                             #查看二进制日志事件
show slave status \G                             #查看从库状态
SHOW RELAYLOG EVENTS               #查看从库relaylog事件信息
desc  (show colums from city)               #查看表的列定义信息

补充

help 内置命令
mysql> help
\G 格式化输出

你可能感兴趣的:(#,数据库,数据库,mysql)