27 Şubat 2012 Pazartesi

Tabloların taşınılması işlemleri



 Senaryo gereği iki tane birbiri ile ilişkili(master-child yapıda) tablolardan birisini başka bir tablespace’ ni değiştirdiğimizde tabloyla ilişkili nesnelerin (index-constraint) durumlarını inceleyelim.

Öncelikle veritabanımıza bazı yeni kullanıcı, tablespace oluşturmak için Sqlplus’ a sysdba olarak bağlanalım.


sqlplus / as sysdba
Connected.

Create a tablespace(bir test tablespace oluşturalım)
create tablespace test_tbs datafile
'/u01/app/oracle/oradata/XDB/datafile/test01.dbf' size 10M  autoextend on next 1M;
 
Tablespace created

İkinci bir tablespace oluşturuyorum.

create tablespace test_tbs2 datafile
'/u01/app/oracle/oradata/XDB/datafile/test02.dbf' size 10M  autoextend on next 1M;

Tablespace created.

Create a user(bir  test kullanıcısı oluşturalım)

create user test_usr identified by password;
 
User created.

Daha sonra test_usr kullanıcısına gerekli haklar verelim.

grant resource,connect to test_usr;

Grant succeeded.

Bu kullanıcıya Default tablespace ve geçici tablespace  olarak belirleyelim. Bundaki amaç bu kullanıcının oluşturacağı tablolar ve diğer nesneler default olarak bu tablespace içinde yer alması içindir.

alter user test_usr default tablespace test_tbs temporary tablespace temp;

User altered.

conn test_usr/password
Connected.

Tablo oluştur.
create table
test_table( t_id number, t_name varchar(30), hire_date date );

Table created.

Bildiğimiz gibi oracle diğer veritabanlarında olduğu gibi otomatik artan bir veritipine sahip değildir. Bu amaçla oracle nesnesi olarak sequence oluşturulup tablo kayıtları için kullanılabilir. Böylelikle de sequence nesnesinin de nasıl oluşturulup , tablo üzerinde nasıl kullanacağımızı da pekiştirmiş oluruz.

idmatic isminde bir Sequence oluştur.

create sequence id_matic
                        minvalue 1 
                        maxvalue 100
                        increment by 1
                        start with 1
                        nocycle 
sequence created.

insert into test_table  values(id_matic.nextval,'John',sysdate-30);

1 row created.

insert into test_table values(id_matic.nextval,'Jim',sysdate-60);

1 row created

insert into test_table values(id_matic.nextval,'Austin',sysdate-90);

1 row created.


select * from test_table;
      T_ID T_NAME                         HIRE_DATE
---------- ------------------------------ ----------
         2 John                           20/01/2012
         3 Jim                            21/12/2011
         4 Austin                         21/11/2011

Diğer child tabloyu oluşturuyoruz.

create table test_child_table(id number,month varchar(20),salary number);

Table created

Diğer parent tablo (test_table) ile ilişkiyi sağlamak için bu tabloya bir foreign key tanımlıyorum.

alter table test_child_table add constraint fk_id_test_ch_tbl foreign key(id)
references test_table(t_id);

Table altered

Daha sonrada indeks testi için bu child tablo üzerinde bir indeks oluşturuyorum. Btree indeksler de oluşturabilirsiniz. Ben Bitmap indeks tercih ettim.
create bitmap index idx_id_child_tbl on test_child_table (id);

Index created.

Yeni kayıt girelim
 insert into test_child_table values(2,'JAN',2000); 

1 row created

Kullanıcı tablolarını bir sorgulayalım. Bakalım ne yapmışız.

select table_name,tablespace_name from user_tables;
TABLE_NAME                     TABLESPACE_NAME
------------------------------ ------------------------------
TEST_TABLE                            TEST_TBS
TEST_CHILD_TABLE               TEST_TBS

Test_usr kullanıcısına it user objeleri aşağıda görülmektedir.


select object_name,OBJECT_TYPE from all_objects where owner='TEST_USR';


OBJECT_NAME                    OBJECT_TYPE
------------------------------ -------------------
ID_MATIC                       SEQUENCE
TEST_TABLE                     TABLE
PK_T_ID_TEST_TBL               INDEX
TEST_CHILD_TABLE               TABLE

Daha sonra test_child_table tablosunu test_tbs2 tablespace’ ine taşıyoruz.


alter table test_child_table move tablespace test_tbs2; 
Table altered.


Tekrar kontrol ettiğimizde kullanıcı tablolarını test_child_table tablosunu farklı bir tablespace taşıdığımızı kontrol ettik. Problem yok.

select table_name,tablespace_name from user_tables;
TABLE_NAME                           TABLESPACE_NAME
------------------------------ ------------------------------
TEST_TABLE                          TEST_TBS
TEST_CHILD_TABLE                          TEST_TBS2

Bakalım şimdi bu tablo üzerindeki nesneler özellikle indeksler ne durumda diye.
Taşındıktan sonra test_child_table tablosu üzerindeki indeksler unusable(kullanılamaz) hale gelecektir.;

 select index_name,status from user_indexes where table_name='TEST_CHILD_TABLE';

INDEX_NAME                     STATUS
------------------------------ --------
IDX_ID_CHILD_TBL               UNUSABLE

Gördüğümüz gibi tablo taşındıktan sonra mevcut indeksin tablo kayıtları için tuttuğu rowid ‘ler de değiştiği için indeks te artık yeni rowidler mevcut olmadığından unusable duruma düşecektir. Neyseki  rebuild edilebilir özelliği olduğundan yeni tablespace üzerinde rebuild edip yeni row id leri  listesine alacaktır.
Daha sonra bu indeksi yeni  yerinde rebuild yapma ihtiyacımız olacaktır.


 alter index IDX_ID_CHILD_TBL rebuild tablespace test_tbs2 ;

Index altered.

select index_name,status from user_indexes where table_name='TEST_CHILD_TABLE';



INDEX_NAME                     STATUS
------------------------------ --------
IDX_ID_CHILD_TBL               VALID

Şimdi bakalım. Bildiğimiz gibi test_child_table tablosu test_table tablosuna bağımlı bir child tablodur. Yeni yerinde test_child_table tablosuna yeni kayıtlar ekleyelim.

 insert into test_child_table values(3,'FEB',4000);

1 row created.

select * from test_child_table;

        ID MONTH                    SALARY
---------- -------------------- ----------
         2 FEB                        4000
         3 FEB                        4000
Ana tablomuzdak kayıtları inceleyelim.

select * from test_table;


      T_ID T_NAME                         HIRE_DATE
---------- ------------------------------ ----------
         2 John                           20/01/2012
         3 Jim                            21/12/2011
         4 Austin                         21/11/2011

insert into test_child_table values(1,'FEB',4000);

insert into test_child_table values(1,'FEB',4000)

ERROR at line 1:
butunluk kısıtlaması (TEST_USR.FK_ID_TEST_CH_TBL) bozuldu – ust anahtar
bulunamadi


Tabloyu taşıdık. Ama Ana tabloya bağımlı olan bir foreign key kısıtlaması halen çalışmakta.
Farklı bir makale ile görüşmek üzere.

2 yorum: