[20160704]NULL与主外键问题.txt

[20160704]NULL与主外键问题.txt

--主外键的问题主要出现在阻塞等情况,有许多极端dba认为应该取消这个约束.当然从使用的角度出发有总比没有好.只是不要过度滥用.
--我这里遇到一个问题,开发指出主外键"失效",我仔细检查发现建立的主表索引是唯一,而非主键,这样可以插入NULL,导致所谓的"失效".
--我开始意味是因为oracle索引不记录NULL而导致的(主键仅仅一个字段).实际上我的测试还是有点意外:

1.环境:

SCOTT@book> @ &r/ver1
PORT_STRING                    VERSION        BANNER
------------------------------ -------------- --------------------------------------------------------------------------------
x86_64/Linux 2.4.xx            11.2.0.4.0     Oracle Database 11g Enterprise Edition Release 11.2.0.4.0 - 64bit Production

--drop table cheap purge;
--drop table pheap purge;

create table pheap (
  id number(10) ,
  v varchar2(10)
);

create unique index pk_pheap on scott.pheap (id,v);
alter table pheap add constraint uk_pheap unique (id,v);

create table cheap (
  id number(10) primary key,
  p_id number(10) ,
  v varchar2(10)
);

alter table cheap add constraint fk_cheap foreign key (p_id,v) references pheap (id,v);
--//注意如果前面没有alter table pheap add constraint uk_pheap unique (id,v);
--//SCOTT@book> alter table cheap add constraint fk_cheap foreign key (p_id,v) references pheap (id,v);
--//alter table cheap add constraint fk_cheap foreign key (p_id,v) references pheap (id,v)
--//                                                                                 *
--//ERROR at line 1:
--//ORA-02270: no matching unique or primary key for this column-list

SCOTT@book> @ &r/desc pheap;
Name  Null?    Type
----- -------- ----------------------------
ID             NUMBER(10)
V              VARCHAR2(10)

SCOTT@book> @ &r/desc cheap;
Name   Null?    Type
------ -------- ----------------------------
ID     NOT NULL NUMBER(10)
P_ID            NUMBER(10)
V               VARCHAR2(10)
--都是NULL.

insert into pheap values (1, '1');
insert into pheap values (2, '2');
insert into cheap values (1, 1, '1');
commit;

create index cheappid on cheap (p_id,v);

2.测试:
SCOTT@book> select * from pheap;
        ID V
---------- ----------
         1 1
         2 2

SCOTT@book> select * from cheap;
        ID       P_ID V
---------- ---------- ----------
         1          1 1

SCOTT@book> insert into cheap values (2, 2, NULL);
1 row created.

--//可以发现我插入insert into cheap values (2, 2, NULL);在phead并不存在(2,NULL)的记录.

SCOTT@book> insert into cheap values (3, 3, NULL);
1 row created.

--//一样ok.
SCOTT@book> insert into cheap values (4, null, 'a');
1 row created.

SCOTT@book> commit ;
Commit complete.

SCOTT@book> select * from pheap;
ID V
--- ----------
  1 1
  2 2

SCOTT@book> select * from cheap;
ID       P_ID V
--- ---------- ----------
  1          1 1
  2          2
  3          3
  4            a

--如果插入:
SCOTT@book> insert into cheap values (4, 5, '5');
insert into cheap values (4, 5, '5')
*
ERROR at line 1:
ORA-00001: unique constraint (SCOTT.SYS_C0012621) violated

SCOTT@book> delete from pheap where id=2;
1 row deleted.

SCOTT@book> commit ;
Commit complete.

SCOTT@book> insert into pheap values (2, NULL);
1 row created.

SCOTT@book> commit ;
Commit complete.

SCOTT@book> delete from pheap where id=2;
1 row deleted.

--完全不会影响cheap的记录.

SCOTT@book> rollback;
Rollback complete.

SCOTT@book> delete from pheap where id=1;
delete from pheap where id=1
*
ERROR at line 1:
ORA-02292: integrity constraint (SCOTT.FK_CHEAP) violated - child record found

--当然我的测试非常特殊,主表没有建立主键索引.从另外一个侧面索引数据库设计非常重要.

时间: 2024-09-20 10:55:27

[20160704]NULL与主外键问题.txt的相关文章

[20121020]主外键约束以及NULL问题.txt

[20121020]主外键约束以及NULL问题.txt 主外键约束可以一定程度保证数据完整性,但是如果外键输入的是NULL,情况会如何呢? SQL> select * from v$version ; BANNER -------------------------------------------------------------------------------- Oracle Database 11g Enterprise Edition Release 11.2.0.1.0 - 6

[20151231]主外键与空表.txt

[20151231]主外键与空表.txt --主外键的测试例子很多,今天做一个特别的,外部键表为空,也会出现阻塞吗?测试看看. 1.建立环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ------------------------------ -------------- -------------------------------------------------------

[20160616]IOT与主外键.txt

[20160616]IOT与主外键.txt https://ilmarkerm.eu/blog/2016/06/interesting-difference-in-foreign-key-locking-behavior-between-heap-and-index-organized-tables --许多人都知道主外键引起的阻塞或者死锁,如果主表是IOT呢? IOT实际上一种特殊的索引结构,测试看看. 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING    

[20160719]主外键与延迟约束2.txt

[20160719]主外键与延迟约束2.txt --前几天遇到的问题,因为开发没有在2个存在主外键上的表上建立约束,导致主表记录删除了,而外表数据还在. --主要开发有需求要删除主表的记录,由于条件写错,导致以上情况出现.实际上oracle支持延迟约束,只有提交的时候才会检查. --自己通过例子说明: 1.环境: SCOTT@book> @ &r/ver1 PORT_STRING                    VERSION        BANNER ---------------

[20160716]主外键与延迟约束.txt

[20160716]主外键与延迟约束.txt --前几天遇到的问题,因为开发没有在2个存在主外键上的表上建立约束,导致主表记录删除了,而外表数据还在. --主要开发有需求要删除主表的记录,由于条件写错,导致以上情况出现.实际上oracle支持延迟约束,只有提交的时候才会检查. --自己通过例子说明: 1.环境: SCOTT@test01p> @ ver1 PORT_STRING           VERSION    BANNER                                

[20151231]主外键与空表(12c).txt

[20151231]主外键与空表(12c).txt --主外键的测试例子很多,今天做一个特别的,外部键表为空,也会出现阻塞吗?测试看看. 1.建立环境: SCOTT@test01p> @ver1 PORT_STRING                    VERSION        BANNER                                                                               CON_ID --------------

[20140210]主外键和阻塞.txt

[20140210]主外键和阻塞.txt 许多人都知道如果几个表之间存在主外键关系的情况下,许多情况下会出现阻塞情况. 具体的例子还很多,当然如果我觉得最常见如果你不修改主外键值,外键的索引多数情况下可以不建. 而且有些外键的索引建立有点多余的. 今天我看了一篇blog,链接如下: http://blog.yavor.info/?p=564&lang=en 给出的例子很奇特,就是这个问题在11g下会出现阻塞,而10g下不会.12c下我也做了测试,也不会, 自己重复测试做一个记录: 1.12c的情

主外键关联删除(on delete set null和on delete cascade)

主外键关联,当删除的是父表数据,参照这些要删除的数据,Oracle有三种处理方式: 1.禁止删除,也是Oracle默认方法. 2.将参照要删除数据的子表对应数据置空. 3.将参照要删除数据的子表对应数据删除. 对于1,比较容易理解,不解释. 对于2,需要使用on delete set null建立外键约束.实验: create table dept_test(deptno number(10) not null, deptname varchar2(30) not null, constrain

sql-SQL:一个留言板小系统。主外键关系的确定问题

问题描述 SQL:一个留言板小系统.主外键关系的确定问题 CREATE TABLE gbook--用户留言表 ( [id] int identity(1,1) not null, [title] nvarchar(50) collate Chinese_PRC_CI_AS null,--用户留言的标题. [name] nvarchar(50) collate Chinese_PRC_CI_AS null,--用户名称 [time] datetime null,--用户留言的时间. [conten