Oracle'dan PostgreSQL'e geçiş

Not: Bu yazı taslak aşamasındadır.
Oracle 9i'den Oracle 10g'ye yeni geçtik. Bir yıl kadar sonra ise PostgreSQL 8'e geçtik. Geçiş esnasında, veritabanı üzerinde ve kodlarım üzerinde yapmak zorunda kaldığım değişikliklerin birçoğunu not aldım. Bu yazıda bu notları paylaşacağım. Veritabanı Unicode'du ve PostgreSQL'de veritabanını oluştururken de Unicode olarak oluşturdum. Veritabanım karmaşık değildi:


  • 200'den fazla tablo

  • 50 kadar arttırıcı (sequence)

  • Birkaç fonksiyon

  • Birkaç şema (schema)


Bu kadar çok tablo içermesine rağmen hiç görüntü (view) içermemesinden de anlaşılabilir; yeteri kadar profesyonelce tasarlanmış bir veritabanı değildi. Oracle 8i'den kalma bir veritabanıdır çünkü. Oracle VTS (Veritabanı Sununucusu), yapı üzerinde büyük değişiklikler yapılması noktasında bizi çok sıklıkla hüsrana uğratmıştı. Bu nedenle, çalışmaya devam ettiği müddetçe, genel tasarımı/yapıyı hep muhafaza etme taraftarı olduk. Hatta diyebilirim ki, veritabanı yapısı bizim için tam bir tabu olmuştu. Fakat PostgreSQL'e geçtikten sonra, açıkkaynak yazılımların genel etkisi olsa gerek, özgüven geldi. Artık çok ciddi değişiklikler yapmakta şüphe duymuyorum.

Veritabanı, saklı yordam (stored procedure) içermediği için, geçiş çok kolay oldu. Öyle ki, özel bir veritabanı-geçiş yazılımı kullanmama gerek kalmadı. Bir yazılım aracılığıyla tüm veritabanının SQL dökümünü çıkardım. Yüzlerce:

CREATE TABLE ...
CREATE SCHEMA ...
INSERT INTO ...

deyimi hayal edin. 2 gün içerisinde, bu deyimlerin tamamını PostgreSQL'e uygun şekilde değiştirdim. Değişikliklerin çoğunu, Dreamveawer'ın "Find and Replace" penceresini kullanarak gerçekleştirdim. İşte, değişiklik notlarımın bir kısmı, bu esnadaki değişiklikleri içeriyor.

1) NVARCHAR2 ve VARCHAR2 gördüğüm her yere VARCHAR yazdım.
2) LONG gördüğüm her yere TEXT yazdım.
3) DATE gördüğüm her yere TIMESTAMP yazdım.
4) NUMBER veritürü ile ilgili olarak ise

NUMBER(1..4) --> SMALLINT
NUMBER(5..9) --> INTEGER
NUMBER(10..18) --> BIGINT
NUMBER(20) --> BIGINT

değişikliklerini yaptım.

CREATE TABLE SAY (DEGER NUMBER)

şeklindeki salt kullanımları ise NUMERIC olarak değiştirdim.

NUMBER(T,O) --> NUMERIC(T,O)

değişikliğini yaptım. Veritürleri ile ilgili olarak, hatırladığım kadarıyla yalnızca bu değişiklikleri yapmak yeterli oldu. Şimdi sırada, diğer SQL ifadelerine geldi...

GRANT

PostgreSQL’de, grant komutunun

alter, index

seçenekleri yoktur. Dreamweaver’da, kurallı ifadelerin de yardımıyla,

grant.*alter.*\; grant.*index.*\;

ifadelerini arattırıp, bul-değiştir yapmak suretiyle, GRANT ifadelerini PostgreSQL’e uyumlu hale getirdim.


Tablo-cache

CREATE TABLE ifadesinde CACHE seçeneği olmadığından,

CREATE TABLE ... (...) CACHE;

benzeri tüm ifadeleri

CREATE TABLE ... (...);

olarak değiştirdim.


İlişki-disable

alter table REHBER add constraint BIRIM_REHBER_FK foreign key (ESAS_BIRIM_ID) references ESKI_BOLUM (BOLUM_KODU) disable;

"disable" seçeneği olmadığı için, kaldırıldı.




Şema isimlerinde küçük harf

Rollerin isimleri küçük harfle verildi. Büyük harflerle yazınca, "şema bulunamadı" hatası oluşuyor. Belki bunun çözümü vardır ama, o arada incelemeye vaktim olmadı. (Bununla ilgili olarak söylemek istediğiniz birşey varsa yorum yazabilirsiniz)

ALTER TABLE, CREATE TABLE önceliği

Var olmayan bir tablodaki bir alana ilişki oluşturulamayacağından ve var olmayan bir Birincil Anahtar (Primary Key) üzerinden kısıt kurulamayacağından dolayı,

ALTER TABLE ADD CONSTRAINT
INSERT INTO

komutlarının birçoğu hata verecektir. Bu nedenle, bu komutların çalıştırılma sırası aşağıdaki gibi olmalıdır:

CREATE TABLE ... (... ADD PRIMARY KEY ...);
INSERT INTO ...;
ALTER TABLE ADD CONTRAINT ...;

böylece, hangi tabloyu önce oluşturduğunuz önemsiz hale gelir.

SYSDATE-NOW()

SYSDATE gördüğüm yere NOW() yazdım.

Uygulama Sunucusu kodlarımda yaptığım değişiklikler

  • ORDER BY'larda Türkçe sorunu çıkmasın diye ALTER SESSION benzeri komutlar kullanırdık. Bunları kaldırdık.

  • SQL ifadelerindeki (+) ifadeleri, JOIN ifadeleri ile değiştirildi. (Oracle'ı bilenler, veritabanımızın ne kadar eski olduğunu daha iyi anlamışlardır)

  • CONCAT CONCAT(CONCAT(PERSONEL.ADI,' '),PERSONEL.SOYADI)benzeri ifadelerPERSONEL.ADI || ' ' || PERSONEL.SOYADIile değiştirildi.

  • Uygulama Sunucusu olarak ColdFusion kullanıyoruz. Geri dönen veritürlerini ColdFusion (veya JDBC sürücüsü) bazen doğru algılayamayıncaCAST CAST(SUBSTR(METIN, 17001, 2000) AS VARCHAR2(2000)) AS METIN_PARCA_10benzeri ifadeler kullanmak zorunda kalmıştık. PostgreSQL'de (veya JDBC sürücüsünde)bu noktada herhangi bir sorun mevcut olmadığından CAST ifadelerini çoğu yerden kaldırdık:SUBSTR(METIN, 17001, 2000) AS METIN_PARCA_10

  • Her alt SELECT ifadesinebir isim verilmesi gerekti. Mesela:select * from (select * from)komutu Oracle'da çalışırken PostgreSQL'de hata veriyordu. Biz deselect * from (select * from) calisanlarbenzeri şekilde değiştirmek zorunda kaldık. Bence mantıklı olan da bu.

  • Ve işte geldik arttırıcı (sequence) meselesine. Her iki VTS'de de arttırıcı nesne var. Fakat, değerini almak için komutlar farklı. Oracle'da: select KISI_ID_SEQ.nextval from dualPostgreSQL'de:select nextVal(' KISI_ID_SEQ ') Arttırıcılar hakkında daha fazla bilgi

  • NVL() fonksiyonunun eşleniği COALESCE() fonksiyonudur. Gerekli değişiklikler yapıldı.

  • ColdFusion kodlarımızdaki SQL-binding kısımlarında değişiklikler yapıldı:cfsqltype="cf_sql_clob" --> cfsqltype="cf_sql_text"
    cf_sql_longvarchar --> cf_sql_textcfsqltype="cf_sql_text"
    cfsqltype="cf_sql_nvarchar" --> cfsqltype="cf_sql_varchar

  • TRUNC(x) --> DATE_TRUNC('day', x)

  • ColdFusion kodlarındaki CFQUERY etiketleri arasındaki tüm/* ... */açıklama satırları-- ...ile değiştirildi veya gereksiz açıklama satırları kaldırıldı. Nedendir bilmiyorum; C++ tarzı açıklama satırları hataya neden oldular. İncelemeye pek vaktim olmadı (bu konuda görüşü olan?)


Neden PostgreSQL'e geçtim?
...

Anahtar kelimeler

oracle postgresql geçiş
oracle postgresql migration
oracle postgresql conversion

0 yorum:

Diğer Yazılar