Konuyu Oyla:
  • Derecelendirme: 0/5 - 0 oy
  • 1
  • 2
  • 3
  • 4
  • 5
Oracle'da 1 Byte'lık Veri Türü
#21
(09-10-2019, Saat: 17:42)delphim Adlı Kullanıcıdan Alıntı: Bir konuda yanlış anlaşılmalar ya da hatalı varsayımlar mevcut. Length, Lengthb ya da parametresi VARCHAR olan başka fonksiyonlara 4444 gibi sayısal değerler geçtiğinizde size 4444 için değil '4444' için hesaplama yapar. Bu Oracle'ın sayısal verileri karakter olarak tutmasından değil otomatik tip değişimi yapmasından kaynaklanır.

Oracle sayısal alana kakakter, karakter alana sayısal değer atamaya izin verir. Gerekiyorsa ve mümkünse otomatik tip dönüşümünü yapar ve kodu çalıştırır. Tip dönüşümü mümkün değilse de ilgili hata mesajı ile çalışmayı sonlandırır.

Diğer konuya gelince Oracle'da çalışmıyorum. İşim gereği Oracle'da başka veritabanları da kullanıyorum. Tüm veritabanlarının benzer konulara farklı yaklaşımları, farklı ele alışları mevcut. Tüm programlama dillerinin benzer konulara farklı yaklaşımları, farklı ele alışları mevcut olduğu gibi. Bir veritabanına çok alışık olup da diğerinde olmayan yada farklı ele alınan şeyler için saçmalık demek en basitinden sığ bir yaklaşım. Hiçbirini (Oracle, DB2, MSSQL, ..., Delphi, Java, C/C++, C#, Go, ...) zorla kullanmıyoruz. Şimdi C/C++'da bolean veri türü yok ne saçma bir dil diyemyiz. Zorla kullanıyorsak da olanı olduğu şekilde kullanacağız, ya da kullanmayacağız.

Demek bizim yaklaşımımız "sığ" bir yaklaşım. Birincisi, bir veritabanına alışık olduğumuz için bir diğer veritabanını eleştirmiyoruz. Amacımız üzüm yemek, bağcı dövmek değil. Konu başında ifade edildiği gibi bir BYTE veri tutabilen bir tür arıyoruz sadece. Bütün programlama dilleri 1 BYTE yer kaplayan bir veri türüne sahipken; siz bizim Boolean veri türünden bahsettiğimizi sanmışsınız. C++'da Boolean veri türü yok diye bu dil saçmadır demeyiz; ancak C++ bir byte'ın yetebileceği bir değerler aralığı için bize "hayır sen 3 byte kullanacaksın" derse bu SAÇMA deriz.

Velhasıl, sözün özü; bir byte içinde tutulabilecek bir veri 3 byte içinde tutuluyor ise; burada bir başarıdan bahsedemeyiz. Geriye kalan 2 byte Oracle efendiye ait değil. O byte'lar benim diskimden, benim hafızamdan ve benim network band width'imden yiyecek. Kimsenin böyle bir tasarrufu olmamalı.

Kısacası; Oracle altında yatan başka bir neden yok ise; TINYINT, BYTE vs. adına ne derseniz deyin, 1 BYTE uzunluğa sığacak bir veri türünü bilerek ve isteyerek getirmedi ise; ben bu durumu aptalca bulurum. Bunu savunanları da akıllı adletmem. Oracle çok istiyorsa; sayısal verileri VARCHAR gibi tutacak NUMBER isimli bir alana sahip olabilir ve isteyen onu kullanabilir; ancak tüm programlama dillerinin sunduğu ve byte genişlikleri belli olan sabit veri türlerine de destek vermelidir. Byte(1), SmallInt(2), Word(2), Int(4), Int64(8) gibi. Bu bir opsiyon olmamalı, zaruri olmalıdır.

 İsteyen Oracle kullanır, isteyen kullanmaz. Orası ayrı bir tartışma konusudur. Ancak aptalca bir şeyi kim yaparsa yapsın aptalcadır. Bunu Oracle yapınca akıllıca bir şeye dönüşmez yani bu. Bu tarz fanatizm'den bir an evvel kurtulmanız gerektiğini düşünüyorum.

O sizin bitlerle byte'larla ilgilenmenize gerek kalmaz dediğiniz Oracle; 1 byte'lık veriyi minimum 1 maximum 3 byte'ta temsil ederken (ortalamasına 2 byte diyelim); tablonuzda 75.000.000 kayıt olduğunda(ki bizim tablolarımızda daha fazlası da var); fazladan 75.000.000 BYTE diskte fazladan yer işgal edecek; kafama esip aptalca bir şey olmasına rağmen sadece o alanı tüm kayıtlar bazında select etmek istesem; hafızamda 75.000.000 BYTE'ı fazladan işgal edecek; ve fazladan bir o kadar BYTE ağımda gereksiz yere gidip gelecek.

Şimdi bu mu aptalca değil !

Not: Ayrıca belirteyim; Delphi NUMBER veri türünü FireDAC kullanıyorsanız; TBCD yapısı ile map ediyor. Dolayısı ile her bir alanın hafızada kaplayacağı alan SizeOf(TBCD) kadar olacaktır. O da 34 Byte yapar. 75.000.000 Kayıt * 34 Byte = 2.550.000.000 Byte yapar. Kaybettiğimiz alan = 2.475.000.000 Byte. Altı üstü bir BYTE'lık yer istemiştik oysaki, geldiğimiz noktaya bak.

Her zaman bir BYTE sadece bir BYTE değildir !
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#22
Oracle NUMBER(p) storage size?

   
Cevapla
#23
(10-10-2019, Saat: 10:58)edo Adlı Kullanıcıdan Alıntı: Oracle NUMBER(p) storage size?

[url=https://stackoverflow.com/questions/24240087/oracle-numberp-storage-size/24240516#24240516][/url]

Yani? (Biz yabancı dil özürlü olanlar için ne diyor?)  Cool
Cevapla
#24
İngilizcem;
Dinleme-Anlama: Çok kötü
Yazma: Kötü
Okuma: Eh işte

Tuğrul bey serzenişte çok haklıydı, bilgisayar-işlemci nin
temel değerlerinin dünyanın en gelişmiş veritabanında 
olmaması diye bir şey olamaz, bu düşünceden yola çıkarak google da bir araştırma yaptım.

Yanlış anlamadıysam Oracle temel integer değerleri
tek bir NUMBER grubu altında toplamış, sizin girdiğiniz 
sayı değerine göre veritabanında yer ayırıyor aynen
varchar gibi.

Yine yanlış anlamadıysam siz NUMBER (3) gibi tanımlama yaptıysanız burada 3 digit lik sayı kullanacağınızı 
anlıyor ve en fazla 999 değer girmesine müsade ediyor
ama sayının büyüklüğüne göre de yer tahsisi yapıyor
bu 2 bytes da olabilir 4 veya 8 vs de olabilir sayının
büyüklüğüne göre.

Sonuç olarak sizin sayınızın büyüklüğü ne göre yer ayırıyor
aynen  varchar gibi, yani Oracle sayıları arka planda kendi
değerlendirerek veritabanında optimum yer ayırıyor.

Ben böyle anladım.
Cevapla
#25
En altta bir yaş ile ilgili bir örnek var. İşinizi görüyor mu?

https://way2tutorial.com/plsql/plsql-data-types.php
Ağlarsa kablosuz ağlar, gerisi yerel ağlar...
Cevapla
#26
Oracle'da numerik verilerin hepsi NUMBER tipinde tutuluyor. PL/SQL yazarken int olarak tanımlama yapsak bile bunu NUMBER olarak kabul ediyor. Alan işaretleme ve kısıtlamasını TinyInt gibi sağlamak için NUMBER(3) kullanabiliriz.

Mantissa'ya kayıt için belirleyici kriter içine eklenecek verinin büyüklüğü. Bunun için bkz: https://docs.oracle.com/cd/B28359_01/ser...#CNCPT1832
Cevapla
#27
Bonus bilgi:

PL/SQL içinde kullandığımız;

DEC, DECIMAL, NUMERIC, DOUBLE, PRECISION, FLOAT, INTEGER, INT, SMALLINT, BOOLEAN, REAL

tiplerinin karşılığı olarak NUMBER(p,s) veri tipi yer alıyor. Onda da ondalık hassasiyet ve ölçek kaplayacağı alanı etkiliyor.


Referans: https://www.mat.unical.it/~rullo/teachin...atypes.pdf
Cevapla
#28
Taktım kafayı Oracle'a

Hiç Oracle deneyimim olmadı, Oracle kurma şansım da yok ama şu adreste
http://www.sqlfiddle.com/#!4/17362/2 online olarak deneme şansınız var bende
denemelerimi burada yaptım.

Araştırmalarım sonucu;

1) Oracle da sayılar NUMBER grubu altında toplanmış
2) NUMBER(16) demekle veritabanında 16 byte lık yer ayrılacak anlamına gelmiyor
sadece sayının büyüklük sınırı belirleniyor
3) Oracle sayısal verileri paketleyerek saklıyor, dolayısı ile size boyut belirleme seçeneği vermiyor
4) Oracle sayıları paketleyerek sakladığı için veritabanındaki yer boyutunu kendi ayarlıyor
aynen VARCHAR gibi
5) Oracle sayıların başındaki ve sonundaki SIFIR'ları kullanmıyor - Paketliyor
Zaten sayıların başındaki sıfırların bir anlamı olmadığını biliyoruz ama Oracle sayıların
sonundaki sıfırları da paketliyor
6) Aşağıdaki örneklerde de görebileceğiniz gibi NUMBER(16) olarak veritabanında belirlediğiniz alan
içine 0 ( SIFIR ) değeri girerseniz 1 BYTE yer ayırıyor, oysa benzer işlemi FIREBIRD de yapsak ve
BIGINT olarak belirlesek bu alana ne sayı girersek girelim her zaman veritabanında 8 Byte ( 64 bit )
yer kaplayacak
7) Veritabanınızda 1 byle lık bir bilgi kullanmak istiyorsanız Oracle da bunu sayısal olarak belirtemiyorsunuz
NUMBER(3) olarak tanım yapmalısınız ve 1 byte ile 3 byte arasında yer kaplıyor çünkü içine gireceğiniz sayıya
göre Oracle yer ayırıyor
8) Milyonlarca kaydımız olan bir veritabanımız varsa ve burada SECENEK adında bir byte lık bir alan
kullanmak istersek ki amacımız sadece 1-255 arasında bir değer saklamak illa da NUMBER(3) ile kullanmak
zorundamıyım, başka yolu yokmu;

Ben bir çıkış yolu aşağıda örnekledim, yapılabiliyor.

İlk önce aşağıdaki örneklmeyi yaptım;

create table t42 (n number(16));

select n, vsize(n), dump(n)
from t42
order by n;


N                                   VSIZE(N)  DUMP(N)
0                                   1              Typ=2 Len=1: 128
1                                    2              Typ=2 Len=2: 193,2
9                                   2              Typ=2 Len=2: 193,10
99                                  2              Typ=2 Len=2: 193,100
255                               3              Typ=2 Len=3: 194,3,56
999                               3              Typ=2 Len=3: 194,10,100
9999                             3              Typ=2 Len=3: 194,100,100
9000000000000000     2              Typ=2 Len=2: 200,91
9000000000000009     9              Typ=2 Len=9: 200,91,1,1,1,1,1,1,10
9999999900000000    5               Typ=2 Len=5: 200,100,100,100,100
9999999999999900    8               Typ=2 Len=8: 200,100,100,100,100,100,100,100

N Alanımızı NUMBER(16) olarak tanımladık ama içine değişik sayılar girdik.

1) Bu alana SIFIR girdiğimizde 1 Byte yer ayırıyor, bu kadar büyük sayı için biz diğer
veri tabanlarında 8 Byte gibi bir yer ayırmamız gerekirdi
2) SIFIR dan sonra 1 sayısını girdiğimiz anda 2 Byte yer ayırıyor
3) 1 Bytle lık 255 sayısı için de 3 Byte yer ayırıyor
4) Son dört sırada çok büyük sayılar girdim, ilk sıradakine dikkat edin başında 9 rakamı var
sonrasında 15 tane SIFIR, Oracle bu kadar büyük bir sayıyı 2 byte içine paketledi
5) Eğer sayının sonunda bir 9 koyarsak sayının büyüklüğüne göre kendisi yer ayırıyor

Sonuç olarak Oracle bazı sayılarda fazladan yer kullanırken bazı sayılarda da çok büyük yer tasarrufu
yapıyor - paketleme özelliğinden dolayı

Peki bizim bir veritabanımız var ve içinde de bir tablomuzda şöyle bir yapı var

ADI varchar(50)
SOYADI varchar(50)
SECENEK byte

Buradaki SECENEK 1 ile 255 arasında kullanacağımız bir alan olsun, mesela Meslek kodlarını sakladığımızı
kabul edelim

Bunu Oracle da;
ADI varchar(50)
SOYADI varchar(50)
SECENEK NUMBER(3)

şeklinde kullanmanız gerekiyor ve SECENEK alanının içine gireceğiniz sayı değerine göre de veri tabanında
yer ayırıyor

Peki biz illa da 1 byte olarak kullanmak istersek, o zaman şöyle yöntemle sonuca ulaşılabiliyor

1) SECENEK alanı tanımında VARCHAR(1) tanımlasını kullanacağız
2) Oracle ın CHR ve ASCII fonksiyonlarından faydalanacağız

ADI varchar(50)
SOYADI varchar(50)
SECENEK VARCHAR(1)

Şimdi bunun örneklemesine bakalım, yine aynı adresteki online siteden deneme yaptım.

create table t42 (secenek varchar(1));

insert into t42 values ( chr( 0 )  );
insert into t42 values ( chr( 1 )  );
insert into t42 values ( chr( 65 )  );
insert into t42 values ( chr( 90 )  );
insert into t42 values ( chr( 255 )  );

select ascii(secenek), vsize(secenek), dump(secenek)
from t42
order by secenek;

ASCII(SECENEK)     VSIZE(SECENEK)     DUMP(SECENEK)
0                             1                            Typ=1 Len=1: 0
1                             1                            Typ=1 Len=1: 1
65                           1                            Typ=1 Len=1: 65
90                           1                            Typ=1 Len=1: 90
255                         1                            Typ=1 Len=1: 255

Bu yöntemle veritabanımız içinde 1 byte lık alan kullanabiliyoruz ama tabiki bu alanın içine konan karakterler sizi rahatsız etmiyorsa !
Cevapla
#29
(12-10-2019, Saat: 11:39)yozdemir Adlı Kullanıcıdan Alıntı: Taktım kafayı Oracle'a

Hiç Oracle deneyimim olmadı, Oracle kurma şansım da yok ama şu adreste
http://www.sqlfiddle.com/#!4/17362/2 online olarak deneme şansınız var bende
denemelerimi burada yaptım.

Araştırmalarım sonucu;

1) Oracle da sayılar NUMBER grubu altında toplanmış
2) NUMBER(16) demekle veritabanında 16 byte lık yer ayrılacak anlamına gelmiyor
sadece sayının büyüklük sınırı belirleniyor
3) Oracle sayısal verileri paketleyerek saklıyor, dolayısı ile size boyut belirleme seçeneği vermiyor
4) Oracle sayıları paketleyerek sakladığı için veritabanındaki yer boyutunu kendi ayarlıyor
aynen VARCHAR gibi
5) Oracle sayıların başındaki ve sonundaki SIFIR'ları kullanmıyor - Paketliyor
Zaten sayıların başındaki sıfırların bir anlamı olmadığını biliyoruz ama Oracle sayıların
sonundaki sıfırları da paketliyor
6) Aşağıdaki örneklerde de görebileceğiniz gibi NUMBER(16) olarak veritabanında belirlediğiniz alan
içine 0 ( SIFIR ) değeri girerseniz 1 BYTE yer ayırıyor, oysa benzer işlemi FIREBIRD de yapsak ve
BIGINT olarak belirlesek bu alana ne sayı girersek girelim her zaman veritabanında 8 Byte ( 64 bit )
yer kaplayacak
7) Veritabanınızda 1 byle lık bir bilgi kullanmak istiyorsanız Oracle da bunu sayısal olarak belirtemiyorsunuz
NUMBER(3) olarak tanım yapmalısınız ve 1 byte ile 3 byte arasında yer kaplıyor çünkü içine gireceğiniz sayıya
göre Oracle yer ayırıyor
8) Milyonlarca kaydımız olan bir veritabanımız varsa ve burada SECENEK adında bir byte lık bir alan
kullanmak istersek ki amacımız sadece 1-255 arasında bir değer saklamak illa da NUMBER(3) ile kullanmak
zorundamıyım, başka yolu yokmu;

Ben bir çıkış yolu aşağıda örnekledim, yapılabiliyor.

İlk önce aşağıdaki örneklmeyi yaptım;

create table t42 (n number(16));

select n, vsize(n), dump(n)
from t42
order by n;


N                                   VSIZE(N)  DUMP(N)
0                                   1              Typ=2 Len=1: 128
1                                    2              Typ=2 Len=2: 193,2
9                                   2              Typ=2 Len=2: 193,10
99                                  2              Typ=2 Len=2: 193,100
255                               3              Typ=2 Len=3: 194,3,56
999                               3              Typ=2 Len=3: 194,10,100
9999                             3              Typ=2 Len=3: 194,100,100
9000000000000000     2              Typ=2 Len=2: 200,91
9000000000000009     9              Typ=2 Len=9: 200,91,1,1,1,1,1,1,10
9999999900000000    5               Typ=2 Len=5: 200,100,100,100,100
9999999999999900    8               Typ=2 Len=8: 200,100,100,100,100,100,100,100

N Alanımızı NUMBER(16) olarak tanımladık ama içine değişik sayılar girdik.

1) Bu alana SIFIR girdiğimizde 1 Byte yer ayırıyor, bu kadar büyük sayı için biz diğer
veri tabanlarında 8 Byte gibi bir yer ayırmamız gerekirdi
2) SIFIR dan sonra 1 sayısını girdiğimiz anda 2 Byte yer ayırıyor
3) 1 Bytle lık 255 sayısı için de 3 Byte yer ayırıyor
4) Son dört sırada çok büyük sayılar girdim, ilk sıradakine dikkat edin başında 9 rakamı var
sonrasında 15 tane SIFIR, Oracle bu kadar büyük bir sayıyı 2 byte içine paketledi
5) Eğer sayının sonunda bir 9 koyarsak sayının büyüklüğüne göre kendisi yer ayırıyor

Sonuç olarak Oracle bazı sayılarda fazladan yer kullanırken bazı sayılarda da çok büyük yer tasarrufu
yapıyor - paketleme özelliğinden dolayı

Peki bizim bir veritabanımız var ve içinde de bir tablomuzda şöyle bir yapı var

ADI varchar(50)
SOYADI varchar(50)
SECENEK byte

Buradaki SECENEK 1 ile 255 arasında kullanacağımız bir alan olsun, mesela Meslek kodlarını sakladığımızı
kabul edelim

Bunu Oracle da;
ADI varchar(50)
SOYADI varchar(50)
SECENEK NUMBER(3)

şeklinde kullanmanız gerekiyor ve SECENEK alanının içine gireceğiniz sayı değerine göre de veri tabanında
yer ayırıyor

Peki biz illa da 1 byte olarak kullanmak istersek, o zaman şöyle yöntemle sonuca ulaşılabiliyor

1) SECENEK alanı tanımında VARCHAR(1) tanımlasını kullanacağız
2) Oracle ın CHR ve ASCII fonksiyonlarından faydalanacağız

ADI varchar(50)
SOYADI varchar(50)
SECENEK VARCHAR(1)

Şimdi bunun örneklemesine bakalım, yine aynı adresteki online siteden deneme yaptım.

create table t42 (secenek varchar(1));

insert into t42 values ( chr( 0 )  );
insert into t42 values ( chr( 1 )  );
insert into t42 values ( chr( 65 )  );
insert into t42 values ( chr( 90 )  );
insert into t42 values ( chr( 255 )  );

select ascii(secenek), vsize(secenek), dump(secenek)
from t42
order by secenek;

ASCII(SECENEK)     VSIZE(SECENEK)     DUMP(SECENEK)
0                             1                            Typ=1 Len=1: 0
1                             1                            Typ=1 Len=1: 1
65                           1                            Typ=1 Len=1: 65
90                           1                            Typ=1 Len=1: 90
255                         1                            Typ=1 Len=1: 255

Bu yöntemle veritabanımız içinde 1 byte lık alan kullanabiliyoruz ama tabiki bu alanın içine konan karakterler sizi rahatsız etmiyorsa !

Emekleriniz, araştırmanız ve bu araştırma neticelerini paylaştığınız için teşekkür ederim.

Lâkin, yine döndük dolaştık en başa geldik. Görünen o ki, Oracle'da 1 Byte uzunluğunda sayısal değerler tutabileceğimiz bir veri türü bulunmuyor. Number veri türünün ve ortaya koydukları algoritmanın efektif olma ihtimali yüksek, ancak tüm programlama dillerinde olan veri türlerinin desteklenmiyor olması kısacası AYIP.
Hiç yakıştıramadım ben Oracle'a.

Bu konuya yorumları ile zenginlik katan her arkadaşıma teşekkür ederim. Belki yine benim gibi Oracle'da BYTE veri türü arayan birisi olacak ve bu konudan ziyadesi ile istifade edebilecek.
Mal sahibi, mülk sahibi
Hani bunun ilk sahibi ?
Mal da yalan mülk de yalan
Var biraz da sen oyalan...
WWW
Cevapla
#30
Asıl ben sizlere Teşekkür ederim.
Sizin bizlere verdiğiniz bilgilerin yanında benimki göl de bir damla.

Yeri gelmişken bir düzeltme yapayım.

5) Eğer sayının sonunda bir 9 koyarsak sayının büyüklüğüne göre kendisi yer ayırıyor

Bu cümlem yanlış olmuş, sanki sona konan 9 rakamının bir özelliği varmış gibi anlam çıkıyor.

Burada anlatmak istediğim sıfırlardan sonra bir rakam eklediğinizde  ki bu 1 den 9 a kadar bir sayı olabilir en büyük 9 olduğu için ben 9 ekledim, bu durumda oracle sıfırları paketlemiyor sayıyı büyük bir sayı olarak kendisi paketleyip değişken bir boyutta yer ayırıyor.
Cevapla


Konu ile Alakalı Benzer Konular
Konular Yazar Yorumlar Okunma Son Yorum
  Oracle Bugün Doğum Günü olanlar gonulali 13 3.280 12-03-2022, Saat: 12:20
Son Yorum: engerex
Photo Sqlite Database Veri Sorunu apachi2006 2 1.343 25-07-2021, Saat: 00:33
Son Yorum: apachi2006
  Delphi Access Veri Aktarma bedirdeg 10 4.210 17-12-2020, Saat: 11:01
Son Yorum: bedirdeg
  FireDac kullanarak Oracle Server'a bağlanma Abdullah ILGAZ 1 2.008 16-03-2020, Saat: 09:07
Son Yorum: SimaWB
  PostgreSQL Veri Tabanı Erişimi için katı Güvenlik 3ddark 4 3.355 25-10-2019, Saat: 13:32
Son Yorum: dilanorkan



Konuyu Okuyanlar: 1 Ziyaretçi