| 導購 | 订阅 | 在线投稿
分享
 
 
 

Oracle与MySQL删除字段时对索引和约束的处理

2008-08-05 07:04:56  編輯來源:互聯網  简体版  手機版  評論  字體: ||
 
 
  不知道有多少人清楚的知道,在Oracle中,如果一个复合索引,假定索引(a,b,c)三个字段,删除了(包括unused)其中一个字段,Oracle会怎么处理这个索引。同样,如果是约束,Oracle又怎么处理?

  用Oracle为例子,我又拿mysql做了一个对比,看看mysql是怎么处理这个问题的。我这里不讨论谁好谁差,只是希望大家知道其中的差别与细节而已。

  我们先看Oracle的例子,我们创建一个表,然后在上面创建一个约束,创建一个索引:

  SQL10G>createtabletest(aint,bint,cint);

  Tablecreated.

  SQL10G>altertabletestaddconstraintpk_testprimarykey(a,b);

  Tablealtered.

  SQL10G>createindexind_testontest(b,c);

  Indexcreated.

  然后,我们检查刚才创建的约束与索引

  SQL10G>selectt.constraint_name,c.constraint_type,t.column_name,t.position,c.status,c.validated

  2fromuser_cons_columnst,user_constraintsc

  3wherec.constraint_name=t.constraint_name

  4andc.constraint_type!='C'

  5andt.table_name='TEST'

  6orderbyconstraint_name,position;

  CONSTRAINT_NAMECCOLUMN_NAMEPOSITIONSTATUSVALIDATED

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

  PK_TESTPA1ENABLEDVALIDATED

  PK_TESTPB2ENABLEDVALIDATED

  SQL10G>selectt.index_name,t.column_name,t.column_position,i.status

  2fromuser_ind_columnst,user_indexesi

  3wheret.index_name=i.index_name

  4andt.table_name='TEST'

  5*orderbyindex_name,column_position

  INDEX_NAMECOLUMN_NAMECOLUMN_POSITIONSTATUS

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

  IND_TESTB1VALID

  IND_TESTC2VALID

  现在,我们先删除索引上的字段,其实并没有物理删除,只是设置为unused:

  SQL10G>ALTERTABLEtestSETUNUSED(c);

  Tablealtered.

  SQL10G>selectt.index_name,t.column_name,t.column_position,i.status

  2fromuser_ind_columnst,user_indexesi

  3wheret.index_name=i.index_name

  4andt.table_name='TEST'

  5orderbyindex_name,column_position;

  norowsselected

  发现了什么,索引也删除了。那我们再删除约束上的字段呢?

  SQL10G>ALTERTABLEtestSETUNUSED(b);

  ALTERTABLEtestSETUNUSED(b)

  *

  ERRORatline1:

  ORA-12991:columnisreferencedinamulti-columnconstraint

  SQL10G>ALTERTABLEtestSETUNUSED(b)CASCADECONSTRAINTS;

  Tablealtered.

  SQL10G>selectt.constraint_name,c.constraint_type,t.column_name,t.position,c.status,c.validated

  2fromuser_cons_columnst,user_constraintsc

  3wherec.constraint_name=t.constraint_name

  4andc.constraint_type!='C'

  5andt.table_name='TEST'

  6orderbyconstraint_name,position;

  norowsselected

  我们可以看到,正常的删除会报一个错误,如果我们指定了cascade,将会把对应的约束也删除。

  我们看完了Oracle的处理过程,再看看mysql是这么处理删除索引上字段这个事情的

  mysql>createtabletest(aint,bint,cint);

  QueryOK,0rowsaffected(0.72sec)

  mysql>altertabletestaddprimarykey(a,b);

  QueryOK,0rowsaffected(0.27sec)

  Records:0Duplicates:0Warnings:0

  mysql>createindexind_testontest(b,c);

  QueryOK,0rowsaffected(0.32sec)

  Records:0Duplicates:0Warnings:0

  我们执行同样的操作,先删除复合索引中的一个字段,然后删除约束中的一个字段。

  mysql>altertabletestdropc;

  QueryOK,0rowsaffected(0.58sec)

  Records:0Duplicates:0Warnings:0

  mysql>showindexfromtest;

  +-------+------------+----------+-----------+

  |Table|Non_unique|Key_name|Seq_in_index|Column_name|Collation|

  +-------+------------+----------+-----------+

  |test|0|PRIMARY|1|a|A|

  |test|0|PRIMARY|2|b|A|

  |test|1|ind_test|1|b|A|

  +-------+------------+----------+-----------+

  3rowsinset(0.06sec)

  mysql>altertabletestdropb;

  QueryOK,0rowsaffected(0.28sec)

  Records:0Duplicates:0Warnings:0

  mysql>showindexfromtest;

  +-------+------------+----------+-----------+

  |Table|Non_unique|Key_name|Seq_in_index|Column_name|Collation|

  +-------+------------+----------+-----------+

  |test|0|PRIMARY|1|a|A|

  +-------+------------+----------+-----------+

  1rowinset(0.03sec)

  可以看到,mysql的处理方式是有差别的,mysql仅仅是把字段从索引中拿掉,而不是删除该索引。

  本文的意思,就是想提醒大家,平常在做columns删除的时候,包括unused,一定要小心,是否有复合索引包含了该字段,否则,一不小心把索引删除了,可能将引发大的错误。
 
 
 
不知道有多少人清楚的知道,在Oracle中,如果一个复合索引,假定索引(a,b,c)三个字段,删除了(包括unused)其中一个字段,Oracle会怎么处理这个索引。同样,如果是约束,Oracle又怎么处理? 用Oracle为例子,我又拿mysql做了一个对比,看看mysql是怎么处理这个问题的。我这里不讨论谁好谁差,只是希望大家知道其中的差别与细节而已。 我们先看Oracle的例子,我们创建一个表,然后在上面创建一个约束,创建一个索引: SQL10G>createtabletest(aint,bint,cint); Tablecreated. SQL10G>altertabletestaddconstraintpk_testprimarykey(a,b); Tablealtered. SQL10G>createindexind_testontest(b,c); Indexcreated. 然后,我们检查刚才创建的约束与索引   SQL10G>selectt.constraint_name,c.constraint_type,t.column_name,t.position,c.status,c.validated 2fromuser_cons_columnst,user_constraintsc 3wherec.constraint_name=t.constraint_name 4andc.constraint_type!='C' 5andt.table_name='TEST' 6orderbyconstraint_name,position; CONSTRAINT_NAMECCOLUMN_NAMEPOSITIONSTATUSVALIDATED ------------------------------------------------------------ PK_TESTPA1ENABLEDVALIDATED PK_TESTPB2ENABLEDVALIDATED SQL10G>selectt.index_name,t.column_name,t.column_position,i.status 2fromuser_ind_columnst,user_indexesi 3wheret.index_name=i.index_name 4andt.table_name='TEST' 5*orderbyindex_name,column_position INDEX_NAMECOLUMN_NAMECOLUMN_POSITIONSTATUS ------------------------------------------------- IND_TESTB1VALID IND_TESTC2VALID 现在,我们先删除索引上的字段,其实并没有物理删除,只是设置为unused: SQL10G>ALTERTABLEtestSETUNUSED(c); Tablealtered. SQL10G>selectt.index_name,t.column_name,t.column_position,i.status 2fromuser_ind_columnst,user_indexesi 3wheret.index_name=i.index_name 4andt.table_name='TEST' 5orderbyindex_name,column_position; norowsselected 发现了什么,索引也删除了。那我们再删除约束上的字段呢? SQL10G>ALTERTABLEtestSETUNUSED(b); ALTERTABLEtestSETUNUSED(b) * ERRORatline1: ORA-12991:columnisreferencedinamulti-columnconstraint SQL10G>ALTERTABLEtestSETUNUSED(b)CASCADECONSTRAINTS; Tablealtered.   SQL10G>selectt.constraint_name,c.constraint_type,t.column_name,t.position,c.status,c.validated 2fromuser_cons_columnst,user_constraintsc 3wherec.constraint_name=t.constraint_name 4andc.constraint_type!='C' 5andt.table_name='TEST' 6orderbyconstraint_name,position; norowsselected 我们可以看到,正常的删除会报一个错误,如果我们指定了cascade,将会把对应的约束也删除。 我们看完了Oracle的处理过程,再看看mysql是这么处理删除索引上字段这个事情的 mysql>createtabletest(aint,bint,cint); QueryOK,0rowsaffected(0.72sec) mysql>altertabletestaddprimarykey(a,b); QueryOK,0rowsaffected(0.27sec) Records:0Duplicates:0Warnings:0 mysql>createindexind_testontest(b,c); QueryOK,0rowsaffected(0.32sec) Records:0Duplicates:0Warnings:0 我们执行同样的操作,先删除复合索引中的一个字段,然后删除约束中的一个字段。 mysql>altertabletestdropc; QueryOK,0rowsaffected(0.58sec) Records:0Duplicates:0Warnings:0 mysql>showindexfromtest; +-------+------------+----------+-----------+ |Table|Non_unique|Key_name|Seq_in_index|Column_name|Collation| +-------+------------+----------+-----------+ |test|0|PRIMARY|1|a|A| |test|0|PRIMARY|2|b|A| |test|1|ind_test|1|b|A| +-------+------------+----------+-----------+ 3rowsinset(0.06sec) mysql>altertabletestdropb; QueryOK,0rowsaffected(0.28sec) Records:0Duplicates:0Warnings:0 mysql>showindexfromtest; +-------+------------+----------+-----------+ |Table|Non_unique|Key_name|Seq_in_index|Column_name|Collation| +-------+------------+----------+-----------+ |test|0|PRIMARY|1|a|A| +-------+------------+----------+-----------+ 1rowinset(0.03sec) 可以看到,mysql的处理方式是有差别的,mysql仅仅是把字段从索引中拿掉,而不是删除该索引。 本文的意思,就是想提醒大家,平常在做columns删除的时候,包括unused,一定要小心,是否有复合索引包含了该字段,否则,一不小心把索引删除了,可能将引发大的错误。
󰈣󰈤
日版宠物情人插曲《Winding Road》歌词

日版宠物情人2017的插曲,很带节奏感,日语的,女生唱的。 最后听见是在第8集的时候女主手割伤了,然后男主用嘴帮她吸了一下,插曲就出来了。 歌手:Def...

兄弟共妻,我成了他们夜里的美食

老钟家的两个儿子很特别,就是跟其他的人不太一样,魔一般的执着。兄弟俩都到了要结婚的年龄了,不管自家老爹怎么磨破嘴皮子,兄弟俩说不娶就不娶,老父母为兄弟两操碎了心...

 
 
>>返回首頁<<
 
 
 
 
 熱帖排行
 
 
王朝网络微信公众号
微信扫码关注本站公众号 wangchaonetcn
 
  免责声明:本文仅代表作者个人观点,与王朝网络无关。王朝网络登载此文出于传递更多信息之目的,并不意味著赞同其观点或证实其描述,其原创性以及文中陈述文字和内容未经本站证实,对本文以及其中全部或者部分内容、文字的真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有