两表关联查询-创建约束,外键对比

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了两表关联查询-创建约束,外键对比相关的知识,希望对你有一定的参考价值。

--开启执行计划:

set autotrace on

SP2-0618: Cannot find the Session Identifier. Check PLUSTRACE role is enabled

找不到会话标识符,启用检查
SP2-0611: Error enabling STATISTICS report

错误:统计报告

grant plustrace to scott
*
ERROR at line 1:
ORA-01919: role ‘PLUSTRACE‘ does not exist                ---角色不存在


SQL> select * from dba_roles where role=‘PLUSTRACE‘; ---查询角色

no rows selected

SQL> @?/sqlplus/admin/plustrce.sql                              -----执行脚本
SQL> drop role plustrace;
drop role plustrace
*
ERROR at line 1:
ORA-01919: role ‘PLUSTRACE‘ does not exist


SQL> create role plustrace;

Role created.

SQL> grant select on v_$sesstat to plustrace;

Grant succeeded.

SQL> grant select on v_$statname to plustrace;

Grant succeeded.

SQL> grant select on v_$mystat to plustrace;

Grant succeeded.

SQL> grant plustrace to dba with admin option;

Grant succeeded.

SQL> set echo off

-----------------------------

grant plustrace to scott;

SQL> select USERNAME,GRANTED_ROLE from user_role_privs;

USERNAME GRANTED_ROLE
------------------------------ ------------------------------
SCOTT CONNECT
SCOTT PLUSTRACE
SCOTT RESOURCE

----这是最后的:类似的查询;

select empno,ename,sal from scott.emp e,scott.dept d where e.deptno=d.deptno; 

--生成测试:

SQL> create table emp1 as select * from emp;

SQL> create table dept2 as select * from dept;

**********测试查询一(两个表,没有索引,没有约束)*********************************

SQL> set autotrace traceonly;
SQL> select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |
----------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 826 | 6 (0)| 00:00:01 |
|* 1 | HASH JOIN | | 14 | 826 | 6 (0)| 00:00:01 |
| 2 | TABLE ACCESS FULL| DEPT2 | 4 | 52 | 3 (0)| 00:00:01 |
| 3 | TABLE ACCESS FULL| EMP1 | 14 | 644 | 3 (0)| 00:00:01 |

1 - access("E"."DEPTNO"="D"."DEPTNO")

Note
-----
 dynamic sampling used for this statement (level=2)

          7  consistent gets

exec dbms_stats.gather_table_stats(ownname=>‘SCOTT‘,tabname=>‘EMP1‘);

*****************************************测试查询二(dept2表中建立了主键约束(建立了索引))*******************************************

--创建外键约束:

alter table emp1 add constraint emp_forkey foreign key(deptno) references dept2(deptno)
*
ERROR at line 1:
ORA-02270: no matching unique or primary key for this column-list

                --没有匹配的这个列表唯一或主键

子表创建与父表的:外键约束,必须要明确父表关联列,有主键或者唯一约束;

SQL> alter table dept2 add constraint p_k primary key(deptno);

SQL> select owner,constraint_name from user_constraints ;

OWNER CONSTRAINT_NAME
-------------------- --------------------
SCOTT P_K

SQL> select INDEX_NAME,TABLE_NAME from user_indexes;

INDEX_NAME TABLE_NAME
------------------------------ ------------------------------
P_K DEPT2

--建立主键约束后,父表dept2,的列deptno列自动生成索引;

SQL> set autotrac traceonly
SQL> select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| Id | Operation | Name | Rows | Bytes | Cost (%CPU)| Time |        *成本从6减为3
---------------------------------------------------------------------------
| 0 | SELECT STATEMENT | | 14 | 420 | 3 (0)| 00:00:01 |
| 1 | NESTED LOOPS | | 14 | 420 | 3 (0)| 00:00:01 |             *********从哈希转为嵌套循环
| 2 | TABLE ACCESS FULL| EMP1 | 14 | 238 | 3 (0)| 00:00:01 |  
|* 3 | INDEX UNIQUE SCAN| P_K | 1 | 13 | 0 (0)| 00:00:01 |  *********全表扫描,转为索引范围


3 - access("E"."DEPTNO"="D"."DEPTNO")

Note
 dynamic sampling used for this statement (level=2)

          7  consistent gets

 

***************************************测试三(emp1与dept2建立主外键约束)**************************************

SQL> set autotrace off

SQL> alter table emp1 add constraint f_y foreign key(deptno) references dept2(deptno);

SQL> select owner,constraint_name from user_constraints;

OWNER CONSTRAINT_NAME
-------------------- --------------------
SCOTT P_K
SCOTT F_Y

SQL> select index_name,table_name from user_indexes where table_name=‘EMP1‘;

no rows selected

select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

| 0 | SELECT STATEMENT | | 14 | 238 | 3 (0)| 00:00:01 |   ---因为测试数据量少,成本没有变化
|* 1 | TABLE ACCESS FULL| EMP1 | 14 | 238 | 3 (0)| 00:00:01 |  --对DEPT2表根本没有查询;
----------

   1 - filter("E"."DEPTNO" IS NOT NULL)         ---直接根据dept2,deptno列非空(主键,非空且唯一);

14 rows selected.

 

*******测试五、测试四的基础上插入一条数据*******

insert into emp1(empno,ename,deptno) values(8000,‘YANG‘,null);

select empno,ename,sal from emp1 e,dept2 d where e.deptno=d.deptno;

--因为查询是等值连接,所以,执行计划不受影响;

但是会存在脏数据:对于外键约束来说,子表中的数据必须在父表中有匹配值,本次测试中,插入了Null,值没有报错;

insert into emp1(empno,ename,deptno) values(8100,‘YG‘,11);

ERROR at line 1:
ORA-02291: integrity constraint (SCOTT.F_Y) violated - parent key not found  外键还是好的;

小结:主外键约束,要保证数据干净,子表中,关联列加上not null 约束靠谱;

alter table emp1 modify deptno not null
*
ERROR at line 1:
ORA-02296: cannot enable (SCOTT.) - null values found

SQL> delete emp1 where deptno is null;

SQL> alter table emp1 modify deptno not null;

 

以上是关于两表关联查询-创建约束,外键对比的主要内容,如果未能解决你的问题,请参考以下文章

sql mysql多表如何关联查询

sql 关联查询外键为空的情况

两表关联查询SQL语句的,要怎么写?

MySQL — 关联

mysql 的完整性约束 与单表查询

Java实现对mongoDB的两表关联查询