SQL语言

240 阅读11分钟

1.注释:

单行注释:注释内容(mysql特有)--
多行注释:* /注释/*

2.数据库类型:

  1. int:整数类型
  2. double:小数类型
  3. date:日期,yyyy-MM-dd
  4. datetime:日期,yyyy-MM-dd HH:mm ss
  5. timestamp:时间错类型 yyyy-MM-dd HH:mm ss
  6. varchar:字符串 varchar(20):姓名最大20个字符

3.SQL分类:

  1. (DDL)数据定义语言:

    定义数据库对象:数据库,表,列等。关键字:create,drop,alter

  2. (DDL)数据定义语言:

    修改数据:insert,delete,updata等

  3. (DQL)数据查询语言:

    查询数据:select,where

  4. (DCL)数据控制语言:

    定义数据的访问权限,及创建用户.关键字:GRANT,REVOKE

4.操作数据库:CRUD:

1.C(Create):创建:

  1. 创建自己的数据库:

    create database 数据库名;
    
  2. 创建自己的数据库(先判断):

    create database if not exists 数据库名;
    
  3. 创建自己的数据库,使用gbk的字符集:

    create database 数据名 character set gbk;
    
  4. 创建自己的数据库,判断是否存在,使用gbk的字符集:

    create database if not exists 数据库名 character set gbk;
    

2.R(show):查询:

  1. 查询所有数据库的名称:

    show databases;
    
  2. 查询某个数据库的字符集:

    show create database 数据库名称;
    

3.U(alter):修改:

  1. 修改数据库库的字符集:

    alter database 数据库名 character set 字符集名;
    

4.D(drop):删除

  1. 删除数据库:

    drop database 数据库名;
    
  2. 删除数据库,如果存在就删除:

    drop database if exists 数据库名;
    

5.使用数据库:

  1. 查询当期正在使用的数据库名:

    select database();
    
  2. 使用数据库:

    use 数据库名;
    

5.操作表:

1.C(Create):创建

  1. 创建一个表:

    create table 表名(
            列名1 数据类型1,
            列名2 数据类型2,
            列名3 数据类型3,
            ........
            列名n 数据类型n
    );
    
  2. 复制表:

    create table 表名 like 被复制的表名
    -- 注意:最后一列不加逗号
    

2.R(show):查询

  1. 查询某个数据库中所有的表名称:

    show tables;
    
  2. 查询表结构:

    desc 表名
    

3.U(alter):修改

  1. 修改表名:

    alter table 表名 rename to 新的表名;
    
  2. 查询表的字符集:

    show create database 表名;
    
  3. 修改表的字符集:

    alter table 表名 character set utf8;
    
  4. 添加一列:

    alter table 表名 add 列名 数据类型;
    
  5. 修改列名称,类型:

    alter table 表名 change 列名 新列名 新数据类型;
    alter table 表名 modify 列名 新数据类型;
    
  6. 删除列:

    alter table 表名 drop column 列名;
    

4.D(drop):删除

```
drop table 表名;
drop table if exists 表名;
```

6.图形化用户界面(SQLyog)

1. DML:增删改表中数据

  1. 添加数据:

    insert into 表名(列名1,列名2,...列名n) values(值1,值2,...值n);
    -- 注意:
    --     1.列表和值要--对应
    --     2.如果表名后,不定义列名,则默认给所有列添加值
                insert into 表名 values(值1,值2,...值n);
    --     3.除了数字类型,其他类型需要使用引号(单双)引起来           
    
  2. 删除数据:

    delete from 表名 where 条件;
    -- 注意:
    --     1.如果不加条件,则删除表中所有记录
    --     2.如果要删除所有记录
                delete from 表名;--删除表中所有元素
                truncate table 表名;--删除表,然后在创建一个一模一样的空表
    
  3. 修改数据:

    update 表名 set 列名1=1,列名2=2,...where 条件;
    -- 注意:
    --     1.如果不加任何条件,则会将表中所有记录全部删除
    

2.DQL:查询表中的记录

1.基础查询

  1. 查询表中某些记录

    select 列名,列名 from 表名;
    
  2. 查询表中所有记录

    select * from 表名;
    
  3. 查询表中不重复的记录

    select distinct 列名 from 表名;
    
  4. 查询并计算表中某些记录之和

    select 列名,列名,列名+列名 from 表名;
    
  5. 查询并计算表中某些记录之和(如果值为NULL,值替换为0)

    select 列名,列名,列名+ifnull(列名,0) from 表名;
    
  6. 查询并计算表中某些记录之和(如果值为NULL),改为0,起别名

    select 列名 as 列名,列名 as 列名,列名+ifnull(列名,0) as 列名 from 表名;
    

2.条件查询

  1. where子句后跟条件

  2. 运算符

    1. < <= >= = <> ----大于小于等于

    2. between...and ----之间

    3. like ----模糊查询

    4. 占位符:

      1. _:单个任意字符

      2. %:任意多个字符

        SELECT * FROM student WHERE NAME LIKE "王%";---第一个字为“王”的记录
        SELECT * FROM student WHERE NAME LIKE "_麻%";---第二个字为“麻”的记录
        SELECT * FROM student WHERE NAME LIKE "__";---名为两个字的记录
        SELECT * FROM student WHERE NAME LIKE "%马%";---名中含“马”的记录
        
    5. is null is not null ---判断是否为null

    6. and 或者 && ----和

    7. or 或者 ||

    8. not 或者 !

3.排序查询

  1. 排序方式:

    1. asc:升序(默认)
    2. desc:降序
  2. select * from 表名 order by 列名;---默认排序(从小到大)
    select * from 表名 order by 列名 排序方式;
    select * from 表名 order by 列名1 排序方式1,列名2 排序方式2;---如果列名1值相同,列名1相同记录按列名2,排序方式2排序
    

4.聚合函数

  1. 将一列数据作为整体,进行纵向计算

  2. 函数:

    1. count:计算个数
    2. max:计算最大值
    3. min:计算最小值
    4. sum:计算和
    5. avg:计算平均值
    select count(列名) from 表名;
    select count(ifnull(列名,0)) from 表名;---null替换为0
    select count(*) from 表名;
    
  3. 注意:

    聚合函数排除null值

5.分组查询

select 列名1,avg(math) from 表名 group by 列名1;
select 列名1,avg(math) from 表名 where 条件 group by 列名1;
select 列名1,avg(math) from 表名 where 条件 group by 列名1 having count(id)>2;
-- 注意:
--     where 与having:where在分组之前进行限定,having在分组之后进行限定
--     where后不能跟聚合函数,having可以跟聚合函数的判断

6.分页查询

-- 公式:开始的索引=(当前的页码-1)*每页显示的条数
select * from 表名 limit 开始的索引,条数; --第一页,三条记录
select * from 表名 limit 开始的索引,条数; --第二页,三条记录

7.约束(数据库完整性)

  1. 概念:

    对表中的数据进行限定,保证数据的完整性,有效性和正确性

  2. 分类:

    1. 主键约束:primary key(实体完整性)

      1. 注意:

        1. 含义:非空且唯一
        2. 一张表只能有一个字段为主键
        3. 主键就是表中记录的唯一标识
      2. 在创建表时,添加主键约束

        create table 表名(
            id int primary key,---给id添加主键约束
            name varchar(20)
        );
        
      3. 删除主键

        alter table 表名 drop primary key;
        
      4. 创建完表后,添加主键

        alter table 表名 modify 列名 数据类型 primary key;
        
      5. 自动增长

        1. 在创建表时

          create table 表名(
              id int primary key auto_increment,
              name varchar(20)
          );
          
        2. 删除自动增长

          alter table 表名 modify 列名 数据类型;
          
        3. 添加自动增长

          alter table 表名 modify 列名 数据类型 auto_increment;
          
    2. 非空约束: not null(用户定义的完整性)

      1. 创建表时添加约束

        create table 表名(
            id int,
            name varchar(20) not null ---为非空                    
        );
        
      2. 创建表完后,添加非空约束

        alter table 表名 modify 列名 数据类型 not null;
        
      3. 删除非空约束

        alter table 表名 modify 列名 数据类型;
        
    3. 唯一约束: unique(用户定义的完整性)

      1. 创建表时添加唯一约束

        create table 表名(
            id int,
            name varchar(20) unique --添加唯一
        );
        -- 注意:唯一约束限定的列可有有多个null
        
      2. 删除唯一约束

        alter table 表名 drop index 列名;
        
      3. 在创建表中,添加唯一约束

        alter table 表名 modify 列名 数据类型 unique;
        
    4. check:(用户定义的完整性)

      1. 检查列值是否满足一个条件表达式

      2. 使用:

        create table student(
            sex char(2) check (sex in('男','女'))
        );
        
    5. 外键约束:foreign key(参照完整性)

      1. 概述:

        让表与比表产生关系,从而保证数据的正确性。

      2. 使用:

        1. 部门表:

          create table department(
              id int primary key auto_increment,
              dep_name varchar(20),
              dep_locationion varchar(20)
          );
          
        2. 员工表:

          create table employee(
              id int primary key auto_increment,
              name varchar(20),
              age int,
              dep_id int, -- 外键对应主表的主键
              constraint emp_dept_fk foreign key (dep_id) references department(id)
          );
          
      3. 在创建表时,可以添加外键

        create table 表名1(
            -----
            外键列
            constraint 外键名 foreign key(外键列)references 表名2(主键2);
        );
        
      4. 删除键

        alter table 表名 drop foreign key 外键名;
        
      5. 创建之后,加外键

        alter table 表名 add constraint 外键名 foreign key(外键列名) references 表名2(主键2);
        
      6. 级联操作

        1. 概念:

          修改数据(外键和连接的主键)

        2. 添加外键,添加级联操作:

          alter table 表名 add constraint 外键名 foreign key(外键列名) references 表名2(主键2) on update cascade;
          alter table 表名 add constraint 外键名 foreign key(外键列名) references 表名2(主键2) on delete cascade;
          
        3. 分类:

          1. 级联更新:

            on update cascade
            
          2. 级联删除:

            on delete cascade
            

8.多表查询:

  1. 笛卡尔积:

    有两个集合A,B 取这两个集合的所有组成情况;要完成多表查询,需要消除无用的数据

  2. 分类:

    1. 内连接查询

      1. 隐式内连接:

        select1.列名2,表2.列名2 from1,表2 where1.'列名1'=2.'列名1'
        
      2. 显式内连接:

        select1.列名2,表2.列名2 from1 join2 on1.'列名1'=2.'列名1'
        
    2. 外连接查询

      1. 左外连接

        -- 查询的是左表所有数据以及交集部分
        select 字段列表 from1 left join2 on 条件;
        ​
        -- 查询所有学生的选课情况(包括没有选课的学生)
        SELECT sname,sc.cno FROM student LEFT JOIN sc ON sc.sno = student.sno;
        
      2. 右外连接

        -- 查询的是右表所有数据以及交集部分
        select 字段列表 from1 right join2 on 条件;
        

9.嵌套查询:

  1. 概念:

    查询中嵌套查询,称嵌套查询为子查询

  2. 带IN的子查询:

    -- IN 和 NOT IN
    select sno,sname from student where sno in (select sno from sc where cno=1);
    
  3. 带有比较运算符的子查询

    select sno,cno from sc x where grade >=(select avg(grade) from sc y where y.sno=x.sno);
    
  4. 带有ANY或All的子查询

    -- >ANY 大于子查询结果中的某个值
    -- >ALL 大于子查询结果中的所有值
    select sname,sage from student where sage<any(select sage from student where sdept='CS');
    select sname,sage from student where sage<all(select sage from student where sdept='CS');
    
  5. 带有EXISTS的谓语查询

    -- EXISTS的谓语查询不返回任何数据,只产生逻辑真值“true”,或逻辑假值“falseselect sname from student where exists(select * from sc where sno=student.sno and cno='1');
    

10.集合查询:

  1. 内容:

    1. 并操作:union
    2. 交操作:intersect
    3. 差操作:except
  2. 并操作:union

    select * from student where sdept='CS' union select * from student where sage<=19;
    
  3. 交操作:intersect

    select * from student where sdept='CS' intersect select * from student where sage<=19;
    
  4. 差操作:except

    select * from student where sdept='CS' except select * from student where sage<=19;
    

7.视图:

1.建立视图:

  1. 不带with check option语句:

    create view 视图名 as select 列名... from 表名 where 条件
    
  2. 带with check option语句

    -- with check option进行修改和插入操作时,乃保证该视图满足子查询条件
    create view 视图名 as select 列名... from 表名 where 条件 with check option
    

2.删除视图:

  1. 不带cascade:

    drop view 视图名 
    
  2. 带cascade:

    -- cascade删除视图1和由它所导出的所有视图
    drop view 视图名 cascade
    

3.查询视图:

4.更新视图:

  1. 概述:

    由于视图是不实际存储数据的虚表,因此对视图的更新最终要转换为对基本表的更新

  2. 插入insert

    insert into 视图名 values(值1,....);
    
  3. 删除delete

    delete from 视图名 where 条件
    
  4. 修改update

    update 视图名 set 视图列1=新值 where 视图列2=值;
    

5.视图的作用:

  1. 视图能简化用户的操作
  2. 视图使用户能以多种角度看待同一数据
  3. 视图对重构数据库提供了一定程度的逻辑独立性
  4. 视图能够对机密数据提供安全保护
  5. 适当利用视图可以清晰地表达查询

8.事务:

1.事务的基本介绍:

  1. 概念:

    如果一个包含多个步骤的业务操作,被事务管理,那么这些操作要么同时成功,要么同时失败

  2. 操作:

    1. 开启事务:start transaction;

    2. 回滚:rollback;---发现执行没有问题,提交事务

    3. 提交:commit;---发现出问题了,回滚事务

      ------开启事务----(多个操作)----提交事务----回滚事务

    4. mySQL数据库中事务默认自动提交:

      1. 事务提交的两种形式:

        1. 自动提交:

          1. mysql就是自动提交的
          2. 一条DML(增删改)语句会自动提交一次事务
        2. 手动提交:

          1. 需要先开启事务,在提交
      2. 修改事务默认提交方式:

        1. 查找事务的默认提交方式:select @@autocommit;--1 代表自动提交 0 代表手动提交
        2. 修改默认提交方式:set @@autocommit=0;

2.事务的四大特征:

  1. 原子性:是不可分割的最小操作单位,要么同时成功,要么同时失败
  2. 持久性:当事务提交或回滚后,数据库会持久化的保存数据
  3. 隔离性:多个事务之间,相互独立
  4. 一致性:事务操作前后,数据总量不变

3.事务的隔离级别:

  1. 概念:

    多个事务之间隔离的,相互独立的,但是如果多个事务操作同一批数据,则会引发一些问题,设置不同的隔离级别就可以解决这些问题

  2. 隔离级别:

    1. read uncommitted:读未提交

      产生问题:脏读,不可重复读,幻读

    2. read committed:读已提交

      产生问题:不可重复读,幻读

    3. repeatable read:可重复读

      产生的问题:幻读

    4. serializable:串行化

      可以解决所有的问题

    5. 注意:隔离级别从小到大安全性越来越大,但是效率越来越低

    6. 数据库查询隔离级别

      select @@tx_isolation;

    7. 数据库设置隔离级别:

      set global transaction isolation level 级别字符串

9.DCL(管理用户和授权):

1.管理用户:

  1. 添加用户:

    create user '用户名'@'主机名' identified by '密码';
    
  2. 删除用户:

    drop user '用户名'@'主机名';
    
  3. 修改用户密码:

    update user set password =password('新密码') where user ='用户名';
    
  4. 查询用户:

    -- 1.切换到mysql数据库
    -- 2.查询user表
    -- 3.通配符:%表示可以在任意主机使用用户登录数据库
    

2.授权:

  1. 查询权限:

    show grants for '用户名'@'主机名';
    
  2. 授予权限:

    grant 权限列表 on 数据库名 to '用户名'@'主机名';
    
  3. 撤销权限:

    revoke 权限列表 on 数据库名.表名 from '用户名'@'主机名';
    

10.断言:

  1. 概述:

    断言创建以后,任何对断言中所涉及关系的操作都会触发关系数据库管理系统对断言的检查

    任何使断言不为真值得操作都会被拒绝执行

  2. 创建断言的语句格式:

    create assertion 断言名 check 子句
    ​
    -- 限制每一个课程最多60名学生选课
    create assertion ASS_SC_CNUMI check(60>=all(select count(*) from sc group by sno));
    
  3. 删除断言的语句格式:

    drop assertion 断言名;
    

11.触发器:

1.概述:

  1. 触发器又叫做事件-条件-动作的规则

  2. 触发时机:after / before

  3. 触发器类型:

    1. 行级触发器(for each row):触发动作体执行一次
    2. 语句触发器(for each statement):触发动作体执行1000次
  4. 触发条件:when

2定义触发器:

//1.如果向section表插入记录,说明板块的主题数目要相应地增加,这可以通过触发器来完成。在section表上创建名为section_count地触发器。
CREATE TRIGGER section_count
    AFTER INSERT ON section
    FOR EACH ROW 
    UPDATE section SET sTopicCount=sTopicCount+1;
//2.在设计表时,buser表和reply表的uID字段值相同,当buser表中uID字段值更新时,reply表中的uID字段值也应该同时更新。创建一个update触发器update_userID实现这一功能
CREATE TRIGGER update_userID
    AFTER UPDATE ON buser
    FOR EACH ROW
    UPDATE reply SET uID=new.uID WHERE uID=old.uID;
//3.如果从buser表中删除一个用户的信息,那么这个用户在topic表中的信息也必须同时删除。在buser表上创建delete_user触发器,只要执行delete操作就删除topic表中相应的记录。
CREATE TRIGGER delete_user
    AFTER DELETE ON buser
    FOR EACH ROW
    DELETE FROM topic WHERE uID=old.uID;

3.激活触发器:

  1. 概述:

    触发器的执行是由触发事件激活,并由数据库服务器自动执行的

    一个数据表上可能定义了多个触发器

    一个表上有多个before(after)触发器,遵循"谁先创建谁先执行"的原则

  2. 执行顺序:

    1. 执行该表上的before触发器
    2. 激活触发器的sql语句
    3. 执行该表上的after触发器

4.删除触发器:

drop trigger 触发器名 on 表名

12.数据库设计:

1.多表之间的关系:

2.数据库设计的范式:

  1. 概念:

    设计数据库时,需要遵循后边的范式要求,不同的规范要求被称为不同的范式,各种范式呈递次规范,越高的范式数据库重复度越小

  2. 分类:

    1. .第一范式(1NF) :每一列都是不可分割的原子数据项

    2. 第二范式(2NF): 在1NF的基础上,非码属性必修完全依赖于码(在1NF基础上消除非主属性对主码的部分函数依赖)

      1. 函数依赖:

        A-->B,如果通过A属性(属性组)的值,可以确定唯一B属性的值。则称B依赖于A

        例如:学号-->姓名 (学号,课程名称)-->分数

      2. 完全函数依赖:

        A-->B,如果A是一个属性组,则B属性值得确定需要依赖于A属性组中所有的属性值

        例如:(学号,课程名称)-->分数

      3. 部分函数依赖:

        A-->B,如果A是一个属性组,则B属性值得确定需要依赖于A属性组中部分的属性值

        例如:(学号,课程名称)-->分数

      4. 传递函数依赖:

        A-->B,B-->C,如果通过A属性(属性组)的值,可以确定唯一B属性的值;如果通过B属性(属性组)的值,可以确定唯一C属性的值,则C依赖于A

        例如:学号-->姓名,姓名-->系主任

      5. 码:

        如果在一张表中,一个属性或者属性组,被其他所有属性所完全依赖,则称这个属性(属性值)为该表的码

        主属性:码属性组中的所有属性

        非主属性:除过码属性组的属性

    3. 第三范式(3NF) :在2NF基础上,任何非主属性不依赖于其他非主属性(在2NF基础上消除传递依赖)

13.数据库的备份和还原:

1.命令行:

2.图形化工具: