chapter04_关系数据库标准语言SQL_1_SQL

  • SQL的功能

    (1) 数据定义:定义表、视图、索引

    (2) 数据操纵:增删改查

    (3) 数据控制:访问权限、事务

  • 三级模式和SQL的对应关系

    概念模式 – 基本表

    外模式 – 视图

    内模式 – 存储文件

  • UNIQUE

    (1) 表示列值必须唯一

    示例

      CREATE TEMPORARY TABLE `temp` (
          `num1` int(11) DEFAULT NULL UNIQUE,
          `num2` int(11) DEFAULT NULL UNIQUE,
          `num3` int(11) DEFAULT NULL,
      );
    

    (2) 如果需要命名 UNIQUE 约束,以及为多个列定义 UNIQUE 约束,使用下面的 SQL 语法

    示例

      CREATE TABLE `temp` (
          `num1` int(11) DEFAULT NULL,
          `num2` int(11) DEFAULT NULL,
          `num3` int(11) DEFAULT NULL,
          CONSTRAINT unique_id UNIQUE(num1, num2)
      );
    

    注:可以类比联想创建外键约束时的语法

      CREATE TABLE `temp` (
          `num1` int(11) DEFAULT NULL,
          `num2` int(11) DEFAULT NULL,
          `num3` int(11) DEFAULT NULL,
          CONSTRAINT fk_temp_num1 FOREIGN KEY (num1)
      );
    

    (3) 如果表已经创建

      ALTER TABLE temp
      ADD (CONSTRAINT uc_ID 可省略) UNIQUE (num1, num2);
    

    (4) 撤销UNIQUE约束

      ALTER TABLE temp
      DROP INDEX uc_PersonID(没命名的话就是num1这种)
    
  • UNIQUE和PRIMARY KEY的区别和联系

    (1) UNIQUE和PRIMARY KEY都可以建在一个或多个属性上

    (2) 一个表只能建一个PRIMARY KEY,但是可以建多个UNIQUE

    (3) 功能上看, PRIMARY KRY = UNIQUE(值不能重复) + NOT NULL

  • 主键可以是一组属性

    示例

      CREATE TABLE Persons (
          Id_P int NOT NULL,
          LastName varchar(255) NOT NULL,
          FirstName varchar(255),
          Address varchar(255),
          City varchar(255),
          CONSTRAINT pk_PersonID PRIMARY KEY (Id_P, LastName)
      );
    

    前面的CONSTRAINT pk_PersonID 是给这个主键约束命名为 pk_PersonID

  • 删除表和视图的时候都可以后面添加 CASCADE/RESTRICT

    DROP TABLE temp CASCADE 代表temp上建立的索引和表上定义的视图一并删除;

    DROP TABLE temp RESTRICT 代表表上没有定义视图或参照约束表时删除该表,否则报错

  • 索引 index

    (1) 在不读取整个表的情况下,索引使数据库应用程序可以更快地查找数据

    (2) 用户无法看到索引,它们只能被用来加速搜索/查询

    (3) 更新一个包含索引的表需要比更新一个没有索引的表__更多的时间__,这是由于索引本身__也需要更新__;

    因此,合适的做法是仅仅在常常被搜索的列(以及表)上面创建索引

    (4) 一个表上可以建立一个或多个索引

    (5) 在创建表时添加索引

      CREATE TABLE temp (
          num1 int, 
          num2 int,
          INDEX num1_index (num1), 
          INDEX num2_index (num2)
      );
    

    (6) 创建表完成以后添加索引

      CREATE INDEX num_index ON temp (num1, num2);
    

    (7) UNIQUE在表上创建一个唯一的索引。唯一的索引意味着两个行不能拥有相同的索引值

      CREATE UNIQUE INDEX num_index ON temp (num1, num2);
    

    (8) CLUSTER表示要创建__聚集索引__。一个基本表上仅能建立一个聚集索引

      CREATE CLUSTER INDEX num_index ON temp (num);
    
  • 聚合函数

    作用在多条记录上,例如SUM, COUNT, MAX, AVG等

  • HAVING 和 WHERE

    (1) HAVING是对聚合后的结果进行条件的过滤,而WHERE是在聚合前就对记录进行过滤

    (2) HAVING常常和GROUP BY连用,用于分组查询;此时是不能用WHERE的,因为此时还没有记录,不能用聚合函数

    (3) 能用WHERE的时候要尽量用WHERE,因为用where先过滤记录,这样因为结果集减小,将对聚合的效率大大提高,最后再根据逻辑看是否用having进行过滤

  • SELECT

    (1) 完整写法

    SELECT (DISTINCT) <列名, 常量, 算术表达式>
    FROM <表名, 视图名>
    (WHERE <条件表达式>)
    (GROUP BY <列名>)
    (HAVING <条件表达式>)
    (ORDER BY <列名>) (ASC/DESC);

    (2) SELECT 后面可以是__列名__,也可以是__字符串常量__或__算术表达式__

    (3) 分组查询 GROUP BY 中,除了要分组的列名以外,不能再出现其他的列名

  • 子查询

    (1) 带有EXISTS的子查询返回的是TRUE/FALSE,若返回TRUE则保留当前记录,因此带有EXISTS的子查询中常常使用 SELECT *

      SELECT name FROM student AS s1 
      WHERE EXISTS (SELECT * FROM student AS s2 WHERE s1.dept = s2.dept AND s2.name = 'Lily');
    

    (2) EXISTS常用的是它的否定形式

  • UNION, MINUS, INTERSECT分别代表结果的并集、差集、交集,但是有的数据库不一定支持这三个关键字,此时可以用子查询代替

    示例

      SELECT name FROM student CROSS JOIN sc WHERE sc.no = 'C1' AND student.sno = sc.sno
      INTERSECT
      SELECT name FROM student CROSS JOIN sc WHERE sc.no = 'C2' AND student.sno = sc.sno;
    

    等价于

      SELECT name FROM student WHERE 
      sno IN (SELECT sno FROM sc WHERE cno = 'C1') 
      AND sno IN (SELECT sno FROM sc WHERE cno = 'C1');
    
  • INSERT可以和SELECT结合在一条语句中使用

    示例

      INSERT INTO cs_avg (no, grade)
      SELECT sno, AVG(grade) FROM sc WHERE sno IN (SELECT sno FROM student WHERE dept = 'computer science');
    
  • INSERT, DELETE, UPDATE 相比 SELECT 最大的区别是 INSERT, DELETE, UPDATE只涉及单个表, 而SELECT还涉及子查询和表的联接

    所以, 使用INSERT, DELETE, UPDATE要保证数据库的一致性,多张表要么都操作,要么都不操作(事务,ACID的C:consistency)

  • 视图

    (1) 系统仅将视图的定义保存在数据字典中,在对视图操作时才生成数据(相当于子查询);视图相当于__窗口__。

    (2) 创建视图的完整语句

      CREATE VIEW <视图名> (<列名1, 列名2, ...>)
      AS
      SELECT (DISTINCT) <列名, 常量, 算术表达式>
      FROM <表名, 视图名> 
      (WHERE <条件表达式>)
      (GROUP BY <列名>)
      (HAVING <条件表达式>)
      (ORDER BY <列名>) (ASC/DESC)
      (WITH CHECK OPTION);
    

    (3) 创建视图时必须使用列名的情况

    1° 目标列中包含聚合函数

    2° 多个表定义的视图,多个表有相同列名

    3° 需要定义与基本表列名不相同的视图的列名

    (4) WITH CHECK OPTION选项的作用:

    DELETE, INSERT, UPDATE时检查是否满足条件,不满足时拒绝执行操作(MySQL不支持CHECK约束,通过建立视图的方式可以“曲线救国”)

    (5) 对视图的更新最终会转换成对基本表的更新,所以有些更新可以执行,有些更新不能执行:

    不能更新的限制:

    1° 由多个基本表导出的视图

    2° 视图定义使用了GROUP BY 或聚集函数

    3° 列中含有常量或表达式

    4° 定义中含有DISTINCT

  • (1) 对表的操作

    SELECT, INSERT, UPDATE, DELETE, ALTER TABLE, CREATE INDEX

    (2) 在视图和列上的操作

    SELECT, INSERT, UPDATE, DELETE

    (3) 对权限的操作

    GRANT, REVOKE

  • GRANT

    GRANT 语句执行后,DBMS把授权的结果__存入数据字典__,用户提出操作请求时进行检查

  • 嵌入式SQL与主程序

    (1) 嵌入式SQL与主程序的通信

    SQL中设置一个通信区SQLCA,SQLCA是一个数据结构,包含描述当前工作状态的信息,应用程序可以通过这些信息了解数据库执行的情况

    (2) 游标

    SQL是面向集合的,一次可以生成多条记录;而应用程序一次只能处理一行;

    游标是一个数据缓冲区,用来存放SQL语句的执行结果;

    游标包含两个部分:结果集 + 指针;通过移动指针每次将结果集中的一行给应用程序

猜你喜欢

转载自blog.csdn.net/captxb/article/details/88051007