SQL Server’da var/yok alanları için hangi veri tipini tercih edersiniz?

ile Ömer Osmanoğlu · 25 Mart 2024

3 ay önce bir anket yayınlamıştım SQL Serverda tablonuzda 3-5 “evet/hayır”,”var/yok” olarak veri tutacağınız alanlara ihtiyacınız var. Bu alanlar için hangi veri tipini tercih edersiniz? diye…

Bağlantılarımda ve Yurt dışı 1 grupta yayınladım. Anket katılım az oldu ama sonuç değişmeyeceğine eminim. Herkes bit alan tipini tercih etti.

Anket Sonuçları

Yurt dışı SQL server grubu
Bağlantılar arasında

Tahmin ettiğim gibi BIT çıktı benim çok sık tinyint’de verileri tutup BIT operatörü ile süzme yaptığım yapının neredeyse kimse tarafından kullanılmadığını farkettim makalenin amacı bunun için

Anket resmi buydu.

Hız testi ve Örnekler için aşağıdaki gibi 1 tablo oluşturdum.

CREATE TABLE [dbo].[urunlerim](
	[urunAdi] [varchar](50) NULL,
	[ozellikler] [nvarchar](max) NULL,
	[parmakIzi] [bit] NULL,
	[suyaDayaniklilik] [bit] NULL,
	[hizliSarj] [bit] NULL,
	[ozelliklerInteger] [int] NULL,
	[ozelliklerVarchar] [varchar](500) NULL
)

Verileri çoğaltarak 500,000+ üzerinde kayıt oluşturdum.

Hepsi için filtreleme sorgusu yapıp çalıştırdım.

Resim verisindeki kodlar ve sonuçları:

JSON Filtre (Varchar alan tipi): CPU zamanı: 375 ms, Geçen süre: 2441 ms

SET STATISTICS TIME ON

SELECT * FROM urunlerim 
WHERE 
JSON_VALUE(Ozellikler, '$.suyaDayaniklilik') = 'yok';

SET STATISTICS IO OFF

Tinyint alan tipi. (Bit operatörü ile Filtre): CPU zamanı: 0 ms, Geçen süre: 2313 ms

SET STATISTICS TIME ON

SELECT *  FROM urunlerim 
WHERE 
(2&ozelliklerInteger)=0

SET STATISTICS IO OFF

Varchar Filtre: CPU zamanı: 31 ms, Geçen süre: 2477 ms

SET STATISTICS TIME ON

SELECT *  FROM urunlerim 
WHERE 
ozelliklerVarchar not like '%suyaDayaniklilik%'

SET STATISTICS IO OFF

Bit Alan ile Filtre: CPU zamanı: 2845 ms, Geçen süre: 6980 ms

SET STATISTICS TIME ON

SELECT *  FROM urunlerim 
WHERE 
suyaDayaniklilik=0

SET STATISTICS IO OFF

Sonuçların karşılaştırması toplu:

 JSON Filtre (Varchar alan tipi):
        CPU zamanı: 375 ms
        Geçen süre: 2441 ms

    Tinyint alan tipi. (Bit operatörü ile Filtre):
        CPU zamanı: 0 ms
        Geçen süre: 2313 ms

    Varchar Filtre:
        CPU zamanı: 31 ms
        Geçen süre: 2477 ms

    Bit Alan ile Filtre:
        CPU zamanı: 2845 ms
        Geçen süre: 6980 ms

Çok şaşırdınız değilmi? Aslında şaşılacak birşey yok. Çünkü BIT alan tipinde siz 1 tanede 8 tanede alan açsanız aslında 1Byte yani TINYINT ile aynı şekilde yer kaplar. Bit kaynak , Tinyint kaynak aslında bu kaynaklardan anlaşılacağı üzere sql server’da arka planda bit veritipini tinyint olarak tutuyor anlamına geliyor ve kullanımda arka planda bir convert yaptığı CPU yormasından anlayabiliyoruz.

Bit, Json, Varchar’ın kullanımı çok kolay olduğundan tercih ediliyor. Her yiğidin yoğurt yemesi farklı ama bana tinyint yetmediği durumlarda smallint vb. kullanmak çok daha kolay geliyor. Sadece arayüzde yeni alanları açıyorum ne veritabanında, ne de backend’de bir alan açmıyorum.

Daha önce bit operatörü kullanmadıysanız Tinyint alana neden 3,5 olarak kayıt ettin ve Suya Dayanıklı olmasını (2&ozelliklerInteger)=0 diye sorguladın diyenler olabilir.

Bunun için binary -> Decimal çevirme kullanıyorsunuz. Konu ile ilgili bir makale ve yandex disk’de bu makale için hazırladığım bir excel bulabilirsiniz. Bu excel’de kullan kısmına x yazarak tinyint’e yazacağınız değeri bulabilirsiniz.

Uygulamalarınızda checkbox olarak verileri listeyeceksiniz.

Value=1 Label=Parmak İzi
Value=2 Label=Suya Dayanıklılık
Value=4 Label=Hızlı Şarj 

şeklinde olacak ve backend’de sadece Value’ları toplayacaksınız. Yani Parmak İzi + Hızlı Şarj seçildi ise 1+4=5 gibi.

Sadece tinyint’demi var? Tabiki hayır mesela 8 özellik olarak kurguladınız daha sonra başka şeyler çıktı özellik sayısı 8+ oldu o zaman sadece alan tipini smallint yapmanız yeterli.

Aşağıdaki şekilde:

Anket’in üzerinden uzun süre geçtiği ve makaleyi geciktirdiğim için acele ile yanlış birşeyler yapmış olabilirim. Makaleyi yazarken ekran görüntülerini aldım ve testlerini yaptım o yüzden varsa bir yanlışlık af ola…

Bit operatörünü kullanalım…

#bit #operatör #sqlserver #json #xml #tinyint #özellikler

Not: Örnek verileri mükerer çoğalttım arkadaşlar bazılarında suyaDayaniklilik var, bazılarında yok olarak sorgulamışım var/yok kayıt sayısı birebir aynı. Sonuçlar değişmiyor o yüzden tekrar resim almadım.

Ekleme: 25.03.2024 Çift arama örneği:

SELECT *  FROM urunlerim 
WHERE 
--Suya Dayanıklılık (2 Değerli Özellik) = yok
(2&ozelliklerInteger)=0
AND
--Hızlı Şarj (4 değerli özellik) = var
(4&ozelliklerInteger)>0 

Bu adresden SQL test yapabilirsiniz: https://dbfiddle.uk/qmosRyBo

Bunlarıda okumak isteyebilirsiniz