zoukankan      html  css  js  c++  java
  • MySQL的约束、多表查询、子查询

    一、约束之主键约束

    约束:约束是添加在列上的,用来约束列的。

    1、主键约束(唯一标识):非空、唯一、被引用

    • 当表的某一列被指定为主键后,该类就不能为空,不能有重复值出现
    • 创建表时指定主键的两种方式:
    CREATE TABLE stu(
        sid  CHAR(6) PRIMARY KEY,
        sname  VARCHAR(20),
        age  INT,
        sex  VARCHEAR(10)
    );
    
    CREATE TABLE stu(
        sid  CHAR(6) ,
        sname  VARCHAR(20),
        age  INT,
        sex  VARCHEAR(10),
        PRIMARY KEY(sid)
    );

      指定sid列为主键列,即为sid列添加主键约束

    • 修改表时指定主键:

    ALTER TABLE stu ADD PRIMARY KEY(sid);

    • 删除主键:

    ALTER TABLE stu DROP PRIMARY KEY;

    2、主键自增长

    • 因为主键列的特性是:必须唯一,不能为空,所以我们通常会指定主键为整型,然后设置其自动增长,这样可以保证在插入数据时主键列的唯一和非空特性。
    • 创建表时指定主键自增长
    CREATE TABLE stu(
        sid  INT PRIMARY KEY AUTO_INCREMENT,
        sname  VARCHAR(20),
        age  INT,
        sex  VARCHEAR(10)
    );
    • 修改表时设置主键自增长:
    ALTER TABLE stu CHANGE sid sid INT AUTO_INCREMENT;
    • 修改表时删除主键自增长:
    ALTER TABLE stu CHANGE sid sid INT ;
    • 测试主键自增长:

    INSERT INTO stu VALUES(NULL,'zhangsan',23,'man');

    INSERT INTO stu(sname,age,sex) VALUES(NULL,'zhangsan',23,'man');

    3、非空约束

    因为某些列不能设置为null值,所以可以对添加非空约束。

    例如:

    CREATE TABLE stu (
       sid INT PRIMARY KEY AUTO_INCREMENT,
       sname  VARCHAR(20) NOT NULL,
       age   INT,
       sex  VARCHAR(10)
    );

    对sname列设置了非空约束。

    4、唯一约束

    车库某些列不能设置重复的值,所以可以对列添加唯一约束。

    例如:

    CREATE TABLE stu (
       sid INT PRIMARY KEY AUTO_INCREMENT,
       sname  VARCHAR(20) NOT NULL UNIQUE,
       age   INT,
       sex  VARCHAR(10)
    );

    二、概念模型

    1、对象模型:在Java中是domain ,例如:User、Student .

    2、关系模型:在数据库中表,1对多,1对1,多对多。

    三、外键约束

    • 外键必须是另一表的主键的值(外键要引用主键。)
    • 外键可以重复
    • 外键可以为空

    1、创建时添加外键约束

    CREATE TABLE dept (
        deptno INT PRIMARY KEY AUTO_INCREMENT,
        dname VARCHAR(50)
    );
    insert into dept values(10,'研发部');
    insert into dept values(20,'人力部');
    insert into dept values(30,'财务部');
    
    CREATE TABLE emp (
        empno INT PRIMARY KEY AUTO_INCREMENT,
        ename VARCHAR(50),
        deptno INT,
        CONSTRAINT fk_emp_dept FOREIGN KEY(dno) REFERENCES dept(deptno) 
    );
    
    CREATE TABLE dept (
        deptno INT PRIMARY KEY AUTO_INCREMENT,
        dname VARCHAR(50)
    );
    INSERT INTO dept VALUES(10,'研发部');
    INSERT INTO dept VALUES(20,'人力部');
    INSERT INTO dept VALUES(30,'财务部');
    
    INSERT INTO emp(empno,ename) VALUES(null,'zhangsan');
    INSERT INTO emp(empno,ename,deptno) VALUES(null,'lisi',10);

    INSERT INTO emp(empno,ename,deptno) VALUES(null,'zhangsan',80); /* Error Code: 1452. Cannot add or update a child row: a foreign key constraint fails (`mydb2`.`emp`, CONSTRAINT `fk_emp_dept` FOREIGN KEY (`deptno`) REFERENCES `dept` (`deptno`)) */

    2、修改表时添加外键约束:

    1 alter table t_student1 add constraint 外键名 foreign key(作为外键的列名) references t_class1(主键列名);
    2 ALTER TABLE emp ADD CONSTRAINT fk_emp_dept FOREIGN KEY(dno) REFERNCES dept(deptno);

    3、删除外键约束语法

    -- MySql 语法
    alter table t_student1 drop foreign key 外键名;

    四、数据库关系模型

    1、一对一关系

      在表中建立一对一关系比较特殊,需要让其中一张表的主键,即是主键又是外键。

    CREATE TABLE hasband (
        hid INT PRIMARY KEY AUTO_INCREMENT,
        hname VARCHAR(50)
    );
    
    CREATE TABLE wife (
        wid INT PRIMARY KEY AUTO_INCREMENT,
        wname VARCHAR(50),
        CONSTRAINT fk_wife_hasband FOREIGN KEY (wid)  REFERENCES hasband(hid) 
    );

    2、多对多关系

    在表中建立多对多关系需要使用中间表,即需要三张表,在中间表中使用两个外键,分别引用其他两张表的主键。

    CREATE TABLE student (
        sid INT PRIMARY KEY ,
        ......
    );
    
    CREATE TABLE teacher(
        tid INT PRIMARY KEY ,
        ......
    );
    
    CREATE TABLE stu_tea (
        sid INT,
        tid INT,
        ADD CONSTRAINT fk_stu_tea_sid FOREIGN KEY (sid)  REFERENCES student(sid) ,
        ADD CONSTRAINT fk_stu_tea_tid FOREIGN KEY (tid)  REFERENCES teacher(tid) 
    );

    在中间表中建立关系,如:

    INSERT INTO stu_tea VALUES(5,1);

    INSERT INTO stu_tea VALUES(2,2);

    INSERT INTO stu_tea VALUES(3,2);

    五、多表查询

    1、分类

    • 合并结果集
    • 连接查询
    • 子查询

    2、合并结果查询

    • 要求被合并表中,结果集列的类型和列数相同
    • UNION,去除重复行
    • UNION ALL,不去除重复行

    SELECT * FROM 表1名

    UNION ALL

    SELECT * FROM 表2名;

    3、连接查询

    ①分类

    • 内连接
    • 外连接
      • 左外连接
      • 右外连接
      • 全外连接(mysql不支持)
      • 自然连接(属于一种简化方式)

    ②内连接

    • 方言:SELECT * FROM 表1 别名1,表2 别名2 WHERE 别名1.xx=别名2.xx;

    SELECT * FROM emp,dept WHERE emp.deptno=dept.deptno;

    SELECT e.ename, e.sal, d.dname FROM emp e, dept d WHERE e.deptno=d.deptno;

         以条件筛选去除笛卡尔积中无用的信息。

    • 标准:SELECT * FROM 表1 别名1 INNER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;

    SELECT e.ename, e.sal , d.dname  FROM emp e INNER JOIN dept d ON  e.deptno=d.deptno;

    • 自然:SELECT * FROM 表1 别名1 NATURAL JOIN 表2 别名2 ;

    SELECT e.ename, e.sal , d.dname  FROM emp e NATURAL JOIN dept d;

    • 内连接查询出的所有记录都满足条件

    ③外连接

    • 左外:SELECT * FROM 表1 别名1 LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
      • 左表记录无论是否满足条件都会查询出来,而右表只有满足条件才能出来。左表中不满足条件的记录,右表部分都为null。

    SELECT e.ename, e.sal , IFNULL(d.dname,'无部门') AS dname  FROM emp e LEFT OUTER JOIN dept d ON  e.deptno=d.deptno;

    • 左外自然:SELECT * FROM 表1 别名1 NATURAL LEFT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
    • 右外:SELECT * FROM 表1 别名1 RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
      • 右表记录无论是否满足条件都会查询出来,而左表只有满足条件才能出来。右表中不满足条件的记录,左表部分都为null。
    • 右外自然:SELECT * FROM 表1 别名1 NATURAL RIGHT OUTER JOIN 表2 别名2 ON 别名1.xx=别名2.xx;
    • 全链接:可以使用UNION来完成全连接。

    SELECT e.ename, e.sal , d.dname 
    FROM emp e LEFT OUTER JOIN dept d 
    ON e.deptno=d.deptno
    UNION
    SELECT e.ename, e.sal , d.dname 
    FROM emp e RIGHT OUTER JOIN dept d 
    ON e.deptno=d.deptno;

    4、子查询

    查询中有查询(查看select关键字的个数)

    ①出现的位置

    • WHERE后作为条件存在
    • FROM后作为表存在(多行多列)

    ②条件

    • 单行单列:SELECT * FROM 表1 别名1 WHERE 列1 [=、>、<、>=、<=、!=] (SELECT 列 FROM 表2 别名2 WHERE 条件) ;

    SELECT * FROM emp WHERE sal=(SELECT MAX(sal) FROM emp);

    • 多行单列:SELECT * FROM 表1 别名1 WHERE 列1 [IN,ALL,ANY] (SELECT 列 FROM 表2 别名2 WHERE 条件);

    SELECT * FROM emp WHERE sal > ANY (SELECT sal FROM emp WHERE job='经理') ;

    • 单行多列:SELECT * FROM 表1 别名1 WHERE (列1,列2)IN (SELECT 列1,列2 FROM 表2 别名2 WHERE 条件);

    SELECT * FROM emp WHERE (job,deptno) IN (SELECT job,deptno from emp WHERE deptno=30) ;

    • 多行多列:SELECT * FROM 表1 别名1,(SELECT......)表2 别名2 WHERE 条件;
  • 相关阅读:
    单例模式的七种写法
    Android省电开发 浅析
    android省电开发之cpu降频
    什么是签名、为什么要给应用程序签名、如何给应用程序签名
    内存溢出和内存泄漏的区别、产生原因以及解决方案
    Android Studio 使用GitHub
    sharesdk 的使用
    当ViewPager嵌套在ScrollView/ListView里时,手势冲突如何处理?
    laravel安装笔记
    erlang的一些小技巧(不定期更新)
  • 原文地址:https://www.cnblogs.com/gdwkong/p/7487263.html
Copyright © 2011-2022 走看看