Bu soru-Cevap başlığında ilginç olan şey aslında 3 soru olduğudur. Herkes farklı bir cevap vermiş, neredeyse hiç kimse birincisini cevaplamamış:
- Neden değil vahşi bazı veritabanları normalize?
- Normalize edilmiş bir veritabanı neden / ne zaman denormalize edilmelidir ?
- Hangi durumlarda ilk etapta normalleşmek zararlı mı yoksa gereksiz mi?
Uyarı okuyucular, bunların çok farklı sorular olduğunu ve çok fazla ayrıntıdan kaçınırken her birine ayrı ayrı cevap vermeye çalışacağım. "Çok fazla" derken, bunun normalizasyon lehine veya aleyhine çeşitli argümanların esası hakkında geniş kapsamlı bir tartışma yürütmenin uygun bir bağlam olduğunu sanmıyorum; Ben sadece bu argümanların ne olduğunu açıklayacağım, belki bir kaç uyarıyı listeleyeceğim ve ortaya çıkarlarsa felsefeyi daha spesifik sorular için saklayacağım.
Ayrıca, bu cevabın içinde “normalleşmenin” “BCNF, 3NF veya en az 2NF” anlamına geldiğini kabul ediyorum , çünkü tasarımcıların genel olarak elde etmeyi hedeflediği normalleştirme düzeyi. 4NF veya 5NF tasarımlarını görmek daha nadirdir; Kesinlikle imkansız hedefler olmasalar da, kendilerini etki alanı hakkında oldukça fazla bilgi gerektiren sadece temsiliyetlerinden ziyade ilişkilerin anlambilimiyle ilgileniyorlar .
Yani, ileri ve yukarı:
1. Neden vahşi ortamdaki bazı veritabanları normalleştirilmiyor?
Bunun cevabı olabilir "onlar olmamalı çünkü" olabilir, ama yarasa bu varsayım doğru yapmaları oldukça çok kötü ile dedektiflik işi. Her ne olursa olsun, olması gerektiği varsayımına göre hareket etmiş olsaydık, toplum olarak fazla ilerleme kaydedemeyiz.
Veritabanlarının ilk etapta normalleşmemesinin gerçek nedenleri daha karmaşıktır. İşte karşılaştığım ilk 5:
Bunu tasarlayan geliştiriciler nasıl normalleşeceğini bilmiyor ya da anlamadı . Bunun güçlü kanıtı, her şey için varchar sütunlarının kullanılması ya da anlamsız tablo ve sütun isimlerinin spagetti karmaşasına sahip olması gibi eşlik eden diğer kötü tasarım seçenekleri şeklinde gelir . Ve sizi temin ederim ki, TDWTF makalelerindeki her şey kadar kötü olan "gerçek" veritabanlarını gördüm.
Bunu tasarlayan geliştiriciler ilke olarak umursamadı veya normalleşmeye karşı aktifti . Not, burada bağlamsal analize dayalı normalleşmek için kasıtlı olmayan bir kararın verildiği durumlardan bahsetmiyorum, daha ziyade normalleşmenin az çok anlaşıldığı ancak ihmal edildiği veya alışkanlıktan çıkarıldığı ekipler veya şirketler hakkında konuşmuyorum. Yine, şaşırtıcı derecede yaygın.
Yazılım bir Brownfield projesi olarak yapıldı / yapıldı . Pek çok uzman, normalleşmemek için teknik nedenlerden ziyade bu meşru meşru işi görmezden geliyor . Bazen aslında sıfırdan yeni bir veritabanı tasarlayamazsınız, mevcut bir eski şemaya cıvata takmanız gerekir ve bu noktada normalleşmeye çalışmak çok fazla acı içerecektir. 3NF, 1971 yılına kadar icat edilmedi ve bazı sistemler - özellikle de finansal / muhasebe sistemleri - kökleri bundan daha da uzaklaştı!
Veri tabanı başlangıçta normalize edildi , ancak uzun bir süre boyunca küçük değişikliklerin birikmesi ve / veya geniş çapta dağınık bir ekip, aslen herhangi bir normal formun ne olduğuna dair ustaca çoğaltma formları ve diğer ihlaller getirdi. Başka bir deyişle, normalizasyonun kaybı tesadüfi idi ve yeniden yapılanmaya çok az zaman harcandı.
İş analizi veya veri tabanı tasarımı üzerinde hiçbir zaman harcamamak ve sadece “halletmek” için bilinçli bir iş kararı verildi. Bu genellikle yanlış bir ekonomidir ve nihayetinde teknik borcun montaj şekli haline gelir , ancak bazen en azından o zaman bilinen bilgilere dayanan rasyonel bir karardır - örneğin, veri tabanı bir prototip olarak tasarlanıp sonuçlandırılmış olabilir iş ortamındaki zaman kısıtlamaları veya değişiklikler nedeniyle üretim kullanımına teşvik ediliyor.
2. Normalize edilmiş bir veri tabanı neden / ne zaman denormalize edilmelidir?
Bir veritabanı, bu tartışma sık sık gündeme gelmektedir olduğu başlamak normalize. Ya performans zayıf ya da sorgularda çok sayıda tekrarlama var (katılım) ve takım, doğru ya da yanlış olarak, mevcut tasarıma mümkün olduğunca ileri gittiklerini hissediyor. Normalleştirmenin çoğu zaman performansı arttırdığını not etmek önemlidir ve normalizasyonun size karşı çalıştığı görülüyorsa, çoğu denormalize edilmiş bir modele geçmek yerine, daha az invaziv ve riskli olan fazla birleşmeleri ortadan kaldırmak için birkaç seçenek vardır :
En yaygın sorunlu alanları içine alan dizinlenmiş görünümler oluşturun. Modern DBMS'ler onları eklenebilir veya güncellenebilir hale getirebilir (örneğin, SQL Server INSTEAD OF
tetikleyicileri). Bu, alttaki tablolarda / dizinlerde DML ifadelerine çok düşük bir maliyetle gelir, ancak genellikle denemeniz gereken ilk seçenektir, çünkü berbat etmek neredeyse imkansızdır ve bakımının neredeyse hiçbir maliyeti yoktur. Tabii ki, her sorgu dizine alınmış bir görünüme dönüştürülemez - toplu sorgular en zahmetlidir. Bu bizi bir sonraki maddeye yönlendirir ...
Tetikleyiciler tarafından otomatik olarak güncellenen denormalize toplam tablolar oluşturun. Bu tablolar normalize edilmiş tablolara ek olarak bulunur ve bir tür CQRS modeli oluşturur. Bugünlerde daha popüler olan bir diğer CQRS modeli, verilerin eskimiş olamayacağı çok nadir durumlarda uygun olmasa da, zaman uyumsuzluğunun faydasını sağlayan sorgu modellerini güncellemek için pub / sub kullanmaktır.
Bazen, dizinlenmiş görünümler mümkün olmayabilir, işlem oranları ve veri hacimleri kabul edilebilir performansla tetikleyicileri kabul etmek için çok yüksektir ve sorgular her zaman gerçek zamanlı veriyi geri vermelidir. Bu durumlar nadirdir - Yüksek Frekanslı Ticaret veya kolluk kuvvetleri / istihbarat veritabanları gibi şeylere uygulanabileceklerini tahmin ediyorum - ama olabilirler . Bu gibi durumlarda, orijinal tabloları normalleştirmek dışında bir seçeneğiniz yok.
3. Hangi durumlarda ilk etapta normalleşmek zararlı ya da gereksiz mi?
Aslında burada birkaç iyi örnek var:
Veri tabanı sadece raporlama / analiz için kullanılıyorsa . Tipik olarak bu, bir olduğu anlamına gelir ek periyodik ETL veya mesaj yoluyla analiz veritabanına eşitlenir OLTP için kullanılan, normalize veritabanı olmak üzere.
Normalleştirilmiş bir modeli uygularken gelen verilerin gereksiz yere karmaşık bir analizini gerektirir. Buna bir örnek, birkaç harici sistemden veya veritabanından toplanan telefon numaralarını kaydetmesi gereken bir sistem olabilir. Sen olabilir farklı yerel bahsetmiyorum, çağrı kodu ve alan kodu denormalize, ancak farklı olası biçimleri geçersiz telefon numaraları, özel numaralar (1-800-GET-STUFF) tümü için hesaba gerek. Genellikle değerinden daha fazla sorun olur ve alan kodu için belirli bir işletme gereksiniminiz yoksa, telefon numaraları genellikle yalnızca tek bir alana taşınır .
İlişkisel veritabanı öncelikli olarak, ilişkisel olmayan ek bir veritabanı için işlem desteği sağlamak üzere olduğunda. Örneğin, ilişkisel veritabanını bir mesaj kuyruğu olarak kullanıyor olabilirsiniz ya da birincil veriler Redis veya MongoDB'de saklanırken veya bir işlemin durumunun izini sürmek ya da her neyse. Başka bir deyişle, veriler "kontrol verileri" dir. Normalde aslında işletme verileri olmayan verileri normalleştirmenin bir anlamı yoktur .
Fiziksel bir veritabanını paylaşan Servis Odaklı Mimari. Bu biraz garip bir durum, ancak gerçek bir SOA'da, hizmetlerin birbirlerinin verilerini doğrudan sorgulamasına izin verilmediğinden , bazen verilerin fiziksel olarak çoğaltılması gerekir. Onlar ise gerçekleşmesi aynı fiziksel veritabanını paylaşan edilecek veriler olacaktır görünür normalize olmamak - ama genel olarak her servis tarafından sahip olunan verilerin olduğu diğer hafifletici faktörlerden biri yerde olmadığı sürece hala normalize. Örneğin, bir Faturalandırma hizmeti Fatura varlığına sahip olabilir, ancak Muhasebe hizmetinin o yılın gelirine dahil edilmesi için Fatura Tarihi ve Tutarını alması ve saklaması gerekir.
Listelemediğimden daha fazla neden olduğundan eminim; Benim elde ettiğim şey, özünde, oldukça spesifik olmaları ve pratik olarak ortaya çıktığında oldukça açık olmaları. OLAP veritabanlarının yıldız şemaları kullanması gerekiyor , SOA'ların bazı kopyaları olması gerekiyordu , vb. Olması gerekiyordu . Eğer normalleştirme ile çalışmayan iyi bilinen bir mimari modelle çalışıyorsanız normalleşmiyorsunuz; Genel olarak konuşursak, mimari model veri modeline göre önceliklidir.
Ve son soruyu cevaplamak için:
İyi mimarlar ve uzmanların denormalize bir tasarım seçtiği, deneyimli olmayan geliştiriciler ise bunun aksini seçtiği doğru mu? Tasarımınıza normalizasyon göz önünde bulundurularak başlatılmasındaki argümanlar nelerdir?
Hayır, bu tam ve eksiksiz BS Aynı zamanda uzmanların da her zaman normalize edilmiş bir tasarım seçtiği BS . Uzmanlar sadece bir mantrayı takip etmiyorlar. Araştırma yapar, analiz eder, tartışır, açıklığa kavuşturur ve tekrar ederler ve sonra kendi durumları için en anlamlı olan yaklaşımı seçerler.
3NF veya BCNF veritabanı genellikle analiz için iyi bir başlangıç noktasıdır , çünkü dünyanın dört bir yanındaki on binlerce projede denenmiş ve kanıtlanmıştır, ancak yine de, C de vardır. yeni proje. Gerçek dünyadaki durumlar, modelde bazı değişiklikler veya tamamen farklı bir modelin kullanılmasını gerektirebilir. Eğer oluncaya kadar bilmiyorum içinde bu durum.