[Linux]Day30-20180606【SQL】

回顾
1、范式
1NF
一个字段一个值
列的值不能重复
2NF
非主字段必须完全依赖主键
违反范式:复合主键
3NF
非主键不能存在依赖关系
2、ACID
A:原子性
C:一致性
I:隔离性
D:持续性
3、多实例


RDBMS常见组件
数据库

索引
视图
存储过程
存储函数
触发器
事件调度


SQL语言介绍
应用于RDBMS,最早由oracle商用
微软:T-SQL
oracle:PL/SQL


SQL语言规范
不区分大小写,但建议用大写
长语句建议分行书写
语句要以 ; 结尾
关键字不能简写
标准注释
/* 多行注释 */
-- 单行注释,
MySQL支持 # 注释


数据库对象
对象的分类
数据库

索引
视图
用户
存储过程
命名
必须以字母开头
只允许使用字母、数字、下划线
不要使用MySQL保留字
同一个数据库(Schema)不允许同名
实例instance
一套数据库应用软件
多个实例之间相互隔离


SQL语句分类
DDL:数据定义语言(数据对象)
CREATE 增
DROP 删
ALTER 改
DML:数据操作语言(数据库)
INSERT 增
DELETE 删
UPDATE 改
DCL:数据控制语言
GRANT 授权
撤销授权
DQL:数据查询语言
SELECT 查询


SQL语句构成
关键字keyword组成子句clause
多条子句共同组成一条语句


SQL帮助文档
https://dev.mysql.com/doc/refman/5.5/en/


数据库操作
创建数据库
指定数据库名(“如果不存在”避免报错)
CREATE DATABASE [IF NOT EXISTS]
SCHEMA [IF NOT EXISTS]
指定字符集
CHARACTRE SET
指定排序规则
COLLATE
删除数据库
DROP DATABASE
查看帮助
help
查看数据库
SHOW DATABASES;
注意!DATABASES是复数形式!!

```sql
-- 查看数据库
show databases;
-- 创建数据库
CREATE DATABASE db1;
-- 删除数据库
DROP DATABASE db1;
-- 查看系统支持的字符集
show CHARACTRE SET;
-- 查看排序规则
show COLLATE;
-- 查看子句的用法帮助
help CREATE DATABASE;
```



二维关系
设计表需要遵守规范
修饰


表操作
查看表
SHOW TABLES
查看所有引擎
SHOW ENGINES
查看表结构
DESC db_name.tb_name
删除表
DROP TABLE [IF EXISTS] tb_name
查看表创建命令
SHOW CREATE TABLE tbl_name
查看表状态
SHOW TABLE STATUS LIKE 'tbl_name'
查看指定数据库中所有表状态
SHOW TABLE STATUS FROM db_name
创建表
CREATE TABLE [IF NOT EXISTS]
create_definition
创建表的定义语句,字段用逗号隔开

```sql
-- 查看表
show TABLES;
-- 创建表
/*
tinyint unsigned :正整数,存储数据的宽度可变
not null :非空
primary key :指定为主键
char(10) :存放姓名,数据宽度占用10个字节
char(11) :存放手机号码,数据宽度占用11个字节
char(1) :存放性别属性,数据宽度占用1个字节
*/
CREATE TABLE students ( id tinyint unsigned not null primary key , name char(10) not null , phone char(11) , sex char(1) );
-- 查看表基本信息
show tables status like 'students'\G
-- 查看表结构
desc students;
-- 查看指定数据库中所有表的状态
show table status from students;
```


数据类型
三大原则
使用最小数据类型
简单数据类型的操作可以节省CPU周期
不要出现NULL值,可以添加默认值(NULL值不利于MySQL优化)
整型
TINYINT
0~255
unsigned:正数,要紧跟在数据类型后面,否则会报错
SMALLINT
INT
后面跟的length:显示的位数
字符型
CHAR
每个字符宽度一致
追求性能,查询速度快
VARCHAR
字符宽度可变
节约磁盘存储空间
日期时间类型
timestamp
自动更新的时间戳

创建表的第一种语法
```sql
--
/*auto_increment:编号自动递增*/
create table emp
( id int unsigned auto_increment primary key ,
name varchar(30) not null ,
sex char(1) default 'm' ,
address varchar(100) )
engine=innodb
default charset=utf8;
--
show table status like 'emp'\G
--
show create table emp\G
--
show create table user\G
```

创建表的第二种语法
```sql
--
select user,host,password from mysql.user;
-- 只有表结构,不拷贝数据
create table user2 user,host,password from mysql.user where 1 = 0;
--
desc user2;
--
select * from user where 1 = 0;
```

创建表的第三种语法
```sql
-- 仿照别的表结构创建新表(不会拷贝数据)
create table user3 like mysql.user;
--
desc user3;
--
select * from user where 1 = 0;
```

问题:如何在不修改表结构的情况下,让查询结果中的表头显示为中文?


级联删除CASCADE
删除主键表附带删除与之关联的外键表
枚举ENUM
多个字符中只选一个,(单选)
多选SET
多个字符中选取多个
主键PRIMARY KEY

唯一键UNIQUE KEY
多个
允许为空

```sql
--
create table t1
( name char(30) ,
city char(30) ,
sex char(1) ,
primary key(name,city) );
```

DML语句
INSERT
UPDATE
DELETE


(一)INSERT插入记录


```sql
--
insert students
values(1, '10086' , 'm' );
--
select * from students;
```

```sql
-- 插入单条记录
insert students(name,id)
values ('wang' , 70);
--
select * from students;
```

```sql
-- 插入多条记录
insert students(id,name,sex)
values (2 , 'liu' , 'm'),(3 , 'lin' , 'f');
--
select * from students;
```

(二)UPDATE修改记录
一定要加WHERE条件!!!


```sql
--
update emp
name='admin',address='beijing'
where id=1;
```

```sql
-- 只修改前两行记录
update emp
name='admin',address='beijing'
where name='root'
LIMIT 2;
```

(三)DELECT删除记录
一定要加WHERE条件!!!
生产中用“伪删除”来代替删除


三种等效的写法
```bash
# 使用安全模式
mysql --safe-updates
#
musql -U
#
mysql --i-am-a-dummy
```


vim /etc/my.cnf.d/mysql-clients.cnf
```
[mysql]
safe-updates
```


SELECT查询
不严谨的语句写法可能会造成服务器宕机

SELECT
as 字段显示使用别名
like 模糊搜索

```sql
--
select 'number',user,password from user;
```

```sql
-- 精确匹配,等号后面的字符串不能写错
select * from user where host='localhost';
```

```sql
-- 并且
select * from user
where host='localhost'
and user='root';
-- 或者
select * from user
where host='localhost'
or user='root';
```

```sql
--
select * from students
where sex is null;
--
select * from students
where sex is not null;
```

```sql
--
select * from students
where id >= 2
and id <= 5;
--
select * from students
where id
between 2 and 5;
```
注意:
between A and B 存在顺序,
A是小值,B是大值

```sql
--
select id
as 编号 , name as 姓名
from students as st;
```

```sql
--
select * from students where name like 'w%'
```
百分号:相当于通配符的星号,匹配任意个字符
下划线:相当于通配符的问号,匹配单个字符


```sql
-- 在phone列后面插入score列
alter students add score tinyint after phone;
```


```sql
--
select from students group by sex;
```

```sql
--
select sex , max(score) as 最好成绩
from students
group by sex;
--
select sex , avg(score) as 平均成绩
from students
group by sex;
```
1、用来分组的字段名本身
2、要汇总统计的字段

```sql
--
alter table students
add class tinyint default 1;
```

```sql
--
select class,sex,avg(score)
from students
group by class,sex;
```

```sql
-- 分组后过滤
select class,sex,avg(score)
from students
group by class,sex
having avg(score) > 80;
```

正向排序
```sql
--
select * from students
order by score asc;
```

逆向排序
```sql
--
select * from students
order by score desc;
```

针对NULL特别优化
```sql
-- 把NULL排在最后面
select * from students
order by -score desc;
-- 把NULL排在最前面
select * from students
order by -score asc;
```

限制条件
```sql
--
select * from students order by score limit 3;
```

使用sql脚本的第一种方法
```bash
mysql < hellodb.sql
```
使用sql脚本的第二种方法
```sql
source hellodb.sql
```


多表查询

内连接:两张表取交集
```sql
-- 旧写法
select
s.name as student_name , t.name as teacher_name
from
students as s , teacher as t
where
s.teacherid=t.tid;
-- 新写法
select
s.name as student_name , t.name as teacher_name
from
students as s
inner join
teachers as t
on
s.teacherid=t.tid;
```

左外连接
```sql
-- students表在左边(取全部),teachers表在右边(只取交集)
select
s.name as student_name , t.name as teacher_name
from
students as s
left outer join
teachers as t
on
s.teacherid=t.tid;
```

右外连接
```sql
-- students表在左边(只取交集),teachers表在右边(取全部)
select
s.name as student_name , t.name as teacher_name
from
students as s
right outer join
teachers as t
on
s.teacherid=t.tid;
```


```sql
-- students表在左边,teachers表在右边
-- 取出students表中不包含两表交集的部分
select
s.name as student_name , t.name as teacher_name
from
students as s
left outer join
teachers as t
on
s.teacherid=t.tid and t.name=null;
```


完全外连接??
```sql
--
select stuid , name
from students
union
select tid,name
from teachers;
```


完全外连接
```sql
--
select
s.name as student_name , t.name as teacher_name
from
students as s
left outer join
teachers as t
on
s.teacherid=t.tid
union
select
s.name as student_name , t.name as teacher_name
from
students as s
right outer join
teachers as t
on
s.teacherid=t.tid
where
s.teacherid is null
or
t.tid is null;
```


自连接
```sql
--
select
s1.name as emp , s2.name as leader
from
students as s1
inner join
students as s2
on
s1.teacherid=s2.stuid;
```

子查询


SELECT执行流程
找表
过滤条件
分组
挑列
挑行


练习题一
```sql
--
select

from
students
where
age > 25
group by
gender;
```


练习题二
```sql
--
select name from students
where
age > (select avg(age) from students);
```

视图:相当于Shell中的别名
相当于假的表
用“查看表状态”可以看到
COMMENT : VIEW
可以隐藏磁盘上数据的逻辑结构
视图本身不存储数据,可以通过视图间接修改表

```sql
-- 创建视图
create view view_students
as select stuid , name from students;
--
select * from view_students;
```

物化视图
相当于实体表,会占用磁盘空间,
但是:MySQL不支持此技术

删除视图 DROP VIEW_NAME 不会删除表数据,类似于Shell中删除别名操作


函数
函数不能独立运行,必须嵌入SQL语句才能运行

自定义函数UDF

```sql
delimiter //

delimiter;
```

存储过程
系统数据库mysql用来存储设置信息:函数、变量
mysql.proc存放存储过程

调用存储过程
CALL PROCEDURE_NAME(ARGS)

触发器


MySQL用户与权限管理
用户帐号的符号格式(写法)
'USERNAME'@'HOST'
匿名用户


创建用户
(1)指定用户名
(2)指定主机
(3)默认权限:USAGE,只能连接数据库,不能做其他的操作(增删改查)


```sql
-- 创建用户
/*控制用户只能在192.168.30.6上登录*/
create user 'wang'@'192.168.30.6' identified by 'centos'
-- 刷新权限策略
flush privileges;
--
select user , host , password from user.mysql;
-- 删除匿名用户
drop user ''@'localhost';
```


```bash
# 添加数据库的root口令
mysqladmin password 'centos'
# 使用新口令登录数据库
mysql -uroot -pcentos
```


破解数据库的root口令
1、停止服务
2、修改配置文件:/etc/my.cnf
在文件头添加一行:skip-grant-tables
3、启动服务
4、mysql客户端免密码登录
5、改user.mysql表
update user.mysql set password=password('centos') where user='root' and host='localhost';
6、退出登录
7、再次修改配置文件:/etc/my.cnf
删除刚刚添加的这一行:skip-grant-tables
8、重启服务
9、使用新密码登录mysql客户端

猜你喜欢

转载自www.cnblogs.com/GymUManAlvin/p/9147993.html