Veritabanında bit maskesi kullanmanın avantajları ve dezavantajları


22

Çok uzun zaman önce meslektaşımla konuştum ve kesinlikle bit maskeleri kullanmaya karşı çıktı çünkü veritabanında depolanan tüm değerleri anlamak zordu. Kanımca, örneğin mevcut kullanıcının rollerini belirlemek için bunları kullanmak her zaman kötü bir fikir değildir. Aksi halde, ayrı bir tabloda saklamanız gerekir, bu da bir JOIN daha ekleyecektir. Yanılıyorsam bana söyler misin? Bit maskeleri kullanmanın başka yan etkileri, avantajları / dezavantajları?


2
Veritabanının dahili olarak maskeler oluşturması ve bitleri size ayrı sütunlar halinde sunması daha mantıklı olabilir. Gereksinimleriniz değişebilir.
Simon Richter

1
Birleşmeleri kullanmazsanız, ilişkisel veritabanınızı tasarlandığı gibi kullanmazsınız.
Pieter B,

Yanıtlar:


38

Kullanıcı rolü atamaları depolamak için bit maskeleri kullanan bir uygulamayla çalışıyorum. Bu popodaki bir acı. Bu beni yanlı yaparsa, suçlandığı gibi suçlu.

Zaten ilişkisel bir veritabanı kullanıyorsanız, çoğu ilişkisel teoriyi ve tüm normalleştirme kurallarını ihlal eden bir anti-kalıptır. Kendi veri depolama alanınızı kurduğunuzda, bu kadar kötü bir fikir olmayabilir.

Çok fazla tablonun katıldığı bir şey var, ancak ilişkisel veritabanları bununla başa çıkmak için oluşturuluyor. Performansın sorun çıkarması durumunda birçoğunun ek özellikleri vardır: endeksler, indekslenmiş görünümler, vb. Baktığınız değerler çok sık değişmese bile, Bitmask için bir avantajdır, endekslemenin yönetilmesi gerekliliği veritabanında oldukça kolay.

Her ne kadar veritabanı veri toplamak için iyi bir iş çıkarsa da, karmaşık formüller veya Skaler Fonksiyonlar gibi şeyleri veri setlerine sokmaya başladığınızda halsizleşebilirler. Uygulamanızda bit yönünde yapabilirsiniz, ancak yaptığınız tek şey alakalı veriler elde etmekse (bir kullanıcının rollerine bakarken), veri depolamanızın en iyi şekilde yaptıklarından yararlanamazsınız.

Buna karşı son argümanım diğer geliştiriciler için basitlik olurdu. Kullanıcılarınız, rolleriniz ve ödevleriniz var. Çok yaygın bir ilişki seti (çünkü birden fazla ilişki var), bu kadar yaygındır, yönetimi kolay olmalıdır. Sadece CRUD meselesi.


8
İlişkisel bir veritabanı, bir bit maskesi için en kötü yerle ilgilidir. Depolama maliyetleri artık o kadar da kötü değil, birkaç katılım ve ekstra bir masa sizi kırmalı. Bu kesinlikle her şeyin nedenini zorlaştırıyor. İzinleri veritabanında bitler (1/0) olarak kendi tablolarında saklayın ve bunları ancak bayraklarla kodlayın. Oldukça uygun ve uygulanabilir görünüyor. Geliştiriciler basit bayraklar alır ve dbas normalleştirilmiş tablolara sahiptir. Herkes mutlu.
Mike McMahon

3
Kabul ediyorum, veritabanındaki kullanıcı rolleri ve ayrıcalıklar için bit maskeleri kullanan bir uygulamayı desteklemek için kullandım. O bir kabustu. 32 bitlik bir int kullanarak, bitleri tükettik, bu yüzden biri daha fazla bit maskesi eklemek için harika bir fikre sahipti , ve sonra üst üste bindirmelerle, bir sütundaki 4 bit, bu diğer sütunda bit 8 anlamına geliyordu ve senkronizasyondan çıktılar. Hoşçakal, hoşçakal. İndeksler zordu çünkü indeksler, ayrı bitleri değil, ayrı sütun değerlerini saklar, bu yüzden where some_bit_mask & 12 > 0satır satır tarama yapmadan satır arayamazsınız.
Brandon,

Günün sonunda, çoktan çoğa user_role_mapveya user_priv_mapmasa yeterli olurdu.
Brandon

@MikeMcMahon, lütfen masa tasarımında daha derine dalabilir misiniz ve bahsettiğiniz sonucu elde etmek için kodda nasıl haritalandırmalıyım?
Alex Ovechkin

2
@ usr - Asla asla deme. Elbette bit maskeleri kullanabilirsiniz, ancak bunları ilişkisel veritabanı kullanan bir uygulamada kullanmazdım. Eski verilerle ya da hıza büyük bir ihtiyaçla uğraşırken muhtemelen bazı son durumlar vardır.
JeffO

24

İlgili artıları ve eksileri zaten adlandırdınız:

  • Bit alanları yerden tasarruf sağlar.
  • Verileri kaydın kendisinde saklarlar, böylece onları bulmak için JOIN'lere ihtiyacınız yoktur. (Ancak kayıttaki bireysel bayrak alanları aynı olacaktır.)
  • Ham SQL çıktısıyla verimli bir şekilde çalışmak istiyorsanız, bunlar çok okunaklı.

Ne yapılacağına karar vermek daha fazla bilgi gerektirir:

  • Kullanım alanı için disk alanı ne kadar az?
  • Aslında kullanıcı rollerini o kadar sık ​​okuyor musunuz, onlara KATILMA zamanı bir darboğaz mı?
  • Are sen buna dayanarak SQL çıkışı ve marka kararları okuyacağım - ya da sadece sistemin makine kodu okunamayacak gerçeği gibi, bir okunamayan veri tabanı kayıt önemsizdir?

Yapmanız gereken şey, risk faktörlerini toplamak ve ardından artıların eksilere ağır basıp basmadığını görmek için onları ağırlıklandırmak .


Cevabınız için teşekkür ederim, düşüncelerinize tamamen katılıyorum, fakat genel olarak bu anti-kalıp mı değil mi? Projelerinizde maske kullanıyor musunuz?
Alex Ovechkin

12
@Alex Sizin durumunuzda ne yapacağınıza karar verebilecek “en iyi uygulama” diye bir şey yoktur. Uzayda çok kısaysanız, bit alanlarını kullanmak en iyi yöntemdir. SQL çıktısını CEO’ya raporlarda kullanmak istiyorsanız, konuşma adlarını kullanmak en iyi yöntemdir. Ancak bu koşulları bilen tek kişi sizsiniz , bu nedenle topluluk size her zaman geçerli olan bir reçete veremez .
Kilian Foth

Boşluk argümanını "hile" olarak kabul etmek. Bir bit maskesi kullanıp kullanmama sorusu, bunun üzerinde ve üstünde herhangi bir fayda sağlayıp sağlamadığının üzerinde durmakta veya düşmektedir.
Robbie Dee,

Ayrıca HER ZAMAN veritabanındaki bilgileri işlemeniz mi gerekiyor yoksa kullanmadan önce bir uygulamaya okunuyor mu?
Ian

1
"SQL çıktısını okuyacak ve buna dayalı kararlar alacaksınız - ya da okunamaz bir veri tabanı kaydı, tıpkı sisteminizin makine kodunun okunamadığı gerçeği gibi mi?" Sanırım tüm geliştiriciler için konuşamıyorum, ancak geliştirirken, bir şeyi anlamak veya kontrol etmek için DB'den veri seçmeye başlamak benim için çok yaygın. Bu yüzden genellikle bunun cevabının “Evet, biri olacak” olduğunu iddia ederdim .
jpmc26

18

Eğer gerçekten, ediyorsanız gerçekten , gerçekten disk alanı için sarılı, o zaman belki kullanıcı izinleri bitmapleri düşünün. Performans kaygınızsa, onları tamamen unutun, çünkü onları ayırmak aslında daha yavaş olacaktır. Bir bitmap alanını anlamlı bir şekilde indeksleyemezsiniz , bu da neredeyse her zaman bir performans katili olan veritabanı tablosu taramalarına neden olur.

Amazon veya Netflix olmadıkça , kullanıcı izinlerine dahil olan veri miktarı , sahip olduğunuz her şeye kıyasla ihmal edilebilir düzeyde olacaktır.

Herhangi bir ciddi DBMS, bu "ekstra birleşim" i göz kırpmadan bile halledebilir.


7
+1: İyi ilişkisel veritabanları, yaptıkları işte gerçekten, gerçekten, gerçekten iyi olan insanlar tarafından geliştirilir. Bit alanlarını kullanarak alabileceğiniz en son performansı bitirme ihtiyacı duyan hiç kimsenin soruyu sorması gerekmez. Verileri modelleyin, sonra çalışmayan parçaları bulun.
Blrfl

Birleşmeye sahip olmak uygulama kodunu daha karmaşık hale getirecek, bu yüzden roller işlendiği yer için çok şey var.
Ian,

4
@ Birliğe sahip olmak bitmasked izinlerini nasıl deşifre edeceğinizi bilmekten daha karmaşık görünmüyor.
Brad

@Brad, C # 'da bir bayrak kümesi olan bir enum'u düşünün, değeri veritabanında “olduğu gibi” saklanır, C # cold daha kolay olamaz. Eğer bir birleştirme kullanılırsa, C # kodunun "1'den çok" bir ilişkiyle başa çıkması gerekir.
Ian

Ayrıca, bir tabloda birden fazla boolean sütuna sahipseniz, çoğu veritabanının bunları mümkün olduğunca az alana nasıl ezeceğini ve sizin için bit bükmeyi önemser.
Blrfl

8

Depolamanın pahalı olduğu zamanlarda, bit maskeleri olan nimet, yer tasarrufu sağlamalarıydı. Büyük veri günlerinde, bir zamanlar olduğu mesele bu değil.

Aldığınız örneği ele alarak - bir bit maskesi olarak saklanan rollere sahip olmak, ilk normal formu ihlal edeceğinden, bir veritabanı tasarımı açısından bir kod kokusu olabilir . Bu anlamda, bunlar bir anti-kalıptır.

Bütün bunlar söyleniyor, biri ya da diğeri olmak zorunda değil. Verileri bir bit maskesi olarak depolayabilir ve ardından kullanıcı rollerini anında çekebilecek bir görünüme sahip olabilirsiniz. Ayrıca, kullanıcıların aynı rollere sahip olduğunu bir bakışta kontrol etme avantajına da sahip olacaksınız.


2

Bit maskelerini kullanmanın tek avantajı, bit alanlarının anlamlarının statik olmamasıdır. İlişkisel tablolar, yalnızca her alanın kayıtta ne olduğunu önceden biliyorsanız, CREATE TABLEsonuçta DDL deyimindeki alanları tanımlamanız gerekir .

Eğer her bit alanı anlamı zamanında yapılandırılabilir ya da başka şekilde vaktinden bilinen değil, o zaman belki biraz alanı olarak boole saklamak anlamlı. O zaman bile, keyfi alanları bir tablo tanımlamak mümkündür: field_1, field_2vb Bu size daha temiz ilişkisel tasarımı verir, her ne kadar hala ideal değil. Bunun bir bit alanına tercih edilip edilmediği, büyük ölçüde bir fikir meselesidir, çünkü hiçbir çözüm ideal değildir.

Bitlerin geliştirme sırasında neyi temsil ettiğini biliyorsanız, o zaman her bit için alanlar oluşturun ve onlara anlamlı adlar verin .

Sadece iç platform etkisine dikkat edin . Keyfi ama iyi yazılmış alanları tanımlamayı başaramazsanız, bu bir şeydir, ancak bundan çok daha uzağa giderseniz, ilişkisel bir veritabanının içinde ilişkisel bir veritabanını yeniden keşfedersiniz.


2

Bit maskeleri konusunda kararsızım. Dedektörlerinin çoğunun ikili ve onaltılık anlamıyor. Netlik için iyi anımsatıcılar kullanın.

Yukarıda belirtilmeyen bir avantaj, potansiyel olarak zaman alan yeni bir sütun eklenmeden bit maskelerine yeni anlamlar eklemektir. Db tasarımcılarımız (benden önce gelen) onları şimdi günde 5 milyon yeni kayıt alan bir masaya koyuyorlar. Yeni bir davranışı temsil etmek için yeni bir sütun eklemek uzun zaman alacaktır, oysa yeni bir bit tanımlamak (64'ün 33'ünü tükettik) tablo oluşturma işlemini gerektirmez.

Hayır, bit maskeleri indekslenemez ancak 33 indeks oluşturmak saçma olur ve sürünmeyi yavaşlatır. Tablo aramaları tarihler kullanır ve "sahipler" dizinlerini kaydeder, bu nedenle bu bit maskesindeki dizinler mümkünse asla kullanılmaz.


Bu ilginç bir durum. Sanırım, masada "yedek" sütunları tanımlayarak ve ardından bunları gerektiği gibi kullanıma sokarak, daha temiz ve açık bir şekilde başarabildiğinizi düşünüyorum. Daha sonra seçerseniz, en azından bu sütunları seçerek indeksleyebilirsiniz.
Steve

1

Amaç sadece biraz disk alanı kazanmaksa, bunun kötü bir fikir olduğunu düşünüyorum:

  • Bugün GB’nin maliyetine bakın,
  • Raporları ve soruları yazanların ve alanın içinde ne olduğunu ve belirli bir parçanın nasıl ele alınacağını, maliyet / fayda karşılaştırmasının yanlış tarafta bitebileceğini bulmak zorunda kalanların maliyetiyle karşılaştırın.
  • SQL veritabanıyla çalışıyorsanız, birçok sorguda gerekli olan ek bit erişim işlemleri de gerekenden daha fazla hesaplama süresi tüketebilir

Ancak, bit alanlarının kullanımını engelleyebilecek bazı durumlar vardır:

  • Eğer bitleriniz, daima bir bütün olarak birlikte kullandığınız karmaşık bir bayrak setini temsil ediyorsa,
  • Bu setlere bazı kalıp eşleştirme algoritmaları uygulamanız gerekirse, daha da fazlası,
  • ve özellikle bu veriler en sık kullanılan seçim kriterleri arasında değilse.
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.