
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ı


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