Bu bir DB şemasını yapılandırmanın saçma bir yolu mu yoksa tamamen bir şey mi eksik?


61

İlişkisel veritabanları ile oldukça fazla çalışma yaptım ve iyi şema tasarımının temel kavramlarını oldukça iyi anladığımı düşünüyorum. Geçenlerde, DB'nin yüksek ücretli bir danışman tarafından tasarlandığı bir projeyi devralmakla görevlendirildim. Bağırsaklarım içgüdüsel olursa lütfen bana bildirin - "WTF ??!?" - garantili mi, yoksa bu adam benim dünyamda kullandığı kadar dahi mi?

Söz konusu DB çalışanlardan gelen istekleri girmek için kullanılan bir içi uygulama. Sadece küçük bir bölümüne baktığımızda, kullanıcılar hakkında ve yapılan istek hakkında bilgileriniz olur. Bunu şöyle tasarlardım:

Kullanıcı tablosu:

UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department

İstek tablosu

RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table

Basit değil mi?

Danışman bu şekilde tasarladı (örnek verilerle):

UsersTable

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

DepartmentsTable

DepartmentID   Name
1              Sales
2              HR
3              IT

UserDepartmentTable

UserDepartmentID   UserID   Department
1                  234      2
2                  516      2
3                  123      1

RequestTable

RequestID   UserID   <...>
1           516      blah
2           516      blah
3           234      blah

Veritabanının tamamı, kendi tablosunda kapsanan her veri parçası ve her şeyi birbirine bağlayan sayısal kimliklerle bu şekilde oluşturulmuştur. Görünüşe göre danışman OLAP hakkında bir şeyler okudu ve 'tamsayı arama hızını' istedi

Ayrıca tüm bu tabloları çapraz referanslamak için çok sayıda saklı yordama sahiptir.

Bu geçerli tasarım, küçük ve orta ölçekli bir SQL DB için mi?

Yorumlarınız / cevaplarınız için teşekkürler ...


12
Oh, eğer bu WTF demeni sağlıyorsa, o zaman muhtemelen 200+ sütun içeren masaları görmemiş ve 1000'den fazla çizgiden uzun saklanmış prosedürleri görmemişsindir.
İş

42
Utandıktan sonra silmeme için +1. Bunu bıraktığın için teşekkürler, başkaları öğrenebilsin.
Wayne Koorts,

2
@Job - Aslında, ben yapmadım - Ben ticaret tarafından bir DBA değilim (şu anda oldukça açık! Lol), bu yüzden benim SQL WTF eşik oldukça düşük. Yine de, danışmanın tasarımındaki noktayı tamamen özlüyorum, kendi yeteneklerimi WTF'liyor. Hiç aptal hissettiğin bir gün oldu mu?
Jim

9
@Jim: Tebrikler, aptal bir günü aydınlanmış bir güne dönüştürdün .
Wayne Koorts 29:11

3
Bu yüksek ücretli danışmanlara lanet olsun!
davidsleeps,

Yanıtlar:


73

Bana çok mantıklı geliyor. Bu sadece çok normalize oldu, aksi takdirde sahip olamayacağınız esnekliği sağlar. De-normalize edilmiş veriler popodaki bir acıdır.


Cevabınız mükemmel mantıklı ve benim soru ve şemaya bakarak belki de o bana kafam karıştıran sadece sayısız tablo olduğunu. Soruma verilen örneği büyük ölçüde basitleştirdim, ancak konseptin nasıl sağlam olduğunu görüyorum - sadece işleri benden çok daha fazla ayırıyor. Sigh, sanırım DBA değilim, iyi bir şey! :)
Jim

On dakikalık kurala göre tasarım yapmayı öğrenin: "Şu anda doğru olan şey muhtemelen 10 dakika içinde olmaz." Tasarımlarınızın değişimle başa çıkabildiğinden emin olun.
Blrfl

1
Bu şema aslında, bir çalışan yerleştirildiğinde, departmanlarının var olması avantajına sahiptir.
Simon Richter

@SimonRichter: Doğru değil. Çalışan, herhangi bir Departman olmadan ve bunun tersi olmadan da yaratılabilir.
Daniel Dinnyes

@SimonRichter Bu tasarımın yararı, öncelikle, Bölümün ayrı bir varlık olmasıdır ve ikincisi, OP'lerin örneğinin aksine, Bölüm ve Çalışan arasında çoktan çoğa bir ilişki olduğudur. bire bir "(birebir söyleyemedi, ayrı bir departman varlığı olmadığı için ilişki olarak adlandırılıyordu).
Daniel Dinnyes

48

Bir WTF'nin garanti olduğunu ya da adamın herhangi bir delice dahi tasarım yaptığını sanmıyorum - oldukça standart bir veritabanı normalleşmesi.

Departman tablosunun nedeni bölümleri ayrı bir masaya koymazsanız, "Satış", "satış", "Satışçılar", "Yelkenler" ve "Satış" bölümlerindeki kullanıcılarla uğraşmanız gerekecek olmasıdır. bunu önlemek için bir şeyler yapmazsan. Ekstra masaya sahip olmak, bunu yapmanın en iyi yolunun (bir parçası) olması.

Bir UserDepartment masası olması gerekip gerekmediği daha zor bir çağrıdır, ki bu elbette ne kararın hem çıkış hem de delilik anlamına gelmez. Bir yandan tüm masa tasarımınızın ve mantığınızın kullanıcı başına bir bölüm üstlendiği bir acıydı, sonra değişiyor, diğer yandan yıllarca ve yıllar boyunca sebepsiz yere ekstra bir katılım yapmak gerçek bir olasılık ve aynı zamanda bir acı.

Şahsen, UserDepartment tablonun büyük olasılıkla overkill olduğuna katılıyorum. Dahil olsa bile, olasılıklar zamanla insanların departman başına yalnızca bir kullanıcı olduğunu varsayan sorular yazmasıdır, bu nedenle her iki dünyanın en kötüsüyle sonuçlanır - masaya ihtiyaç duymadan hiçbir sebep olmadan ekstra bir katılım ve kullanıcı başına birden fazla departmana izin verilmediğinde, kod yine de çalışmıyor.

EDIT - Çok ya da çok ilişkinin desteklenmesi gerekip gerekmediğinin temel itici gücü, işletme kurallarının açık olması. Birden fazla bölümdeki bir kullanıcının nasıl çalıştığı hakkında hiçbir fikriniz yoksa, tabloyu eklemenin pek bir anlamı yoktur, çünkü kodunuz bir kullanıcının birden fazla bölümdeki durumlarını doğru bir şekilde işleyemez.

Her durumda, kullanıcı başına birçok bölüme izin verdiğinizi hayal edin. Daha sonra departmana bağlı olarak komisyon tayin etmek için bir iş kuralı uyguladınız. Daha sonra birden fazla bölüme izin verildi. Neyse ki, komisyon kodunuzu, bunu dikkate alan bir şekilde yazma öngörüsünüz de vardı. Ne yazık ki, her iki bölümdeki kullanıcılar için her bölümden komisyon eklediniz . Yönetim, her satış için kişilerin rolüne dayanmanızı istedi. Peki, masayı önceden almak ne kadar iyiydi? Peki ya hiç ihtiyacın olmayan "sadece durumunda" olan diğer masalardan ne haber?

SONRA DÜZENLEME - Danışmanın tüm bu aracı tabloları eklemek istemiş olabileceği bir diğer sebep, bu takip eden soruda ele alınmaktadır; bir veri tabanını yeniden düzenlemenin neden yeniden doğrulama kodundan daha zor olduğunu ve bu da sizi doğru yönde yönlendirmeye meyilli olan bazı nedenler vermiştir. "İhtiyacınız olan tüm tabloları yerleştirin" yaklaşımı.


Sanırım benim WTF'imin ne olduğunu kelimelerle ifade ettin - adam bu geçici masaların TON'unu kullanıyor ve bu bana çok aptalca geldi. Şimdi bu soru için çok daha küçük bir örneğe ayırdım, o kadar kötü görünmediğinden onu gönderdiğim için kendimi aptal hissediyorum.
Jim

5
Yorumların çoğunda görebileceğiniz gibi, "Y başına sadece bir X olacak" hakkında sağlıklı bir şüphecilik var. Danışman, kendisini "nasıl bir Y başına sadece bir X olabilir?" Şikayetlerinden koruyor. Bazıları muhtemelen ortaya çıkacak. Ancak, çok fazla katılımı olan (çok kötü değil, ancak daha zor olan) ve henüz mevcut olmayan iş kurallarına karşı doğru olması gereken (kötü) kodları korumaktan sorumlu olmayacaktır - "kullanıcıların neden TÜMÜ aldığını" düşünün Her bölümün izinleri, her iznin en düşük seviyesine sahip olmalıdır "veya benzeri.
psr

@psr bir yazım hatası olduğunu düşünüyorum: "bölüm başına yalnızca bir kullanıcı olduğunu varsayan sorgular" "bir kullanıcının yalnızca bir bölüm içinde olduğunu varsayan sorgular" olmamalıdır?
BiAiB

@BiAiB - haklısın, demek istediğim bu.
psr

14

Gereklilik kullanıcı başına birden fazla bölüme sahipse, bu tasarım mantıklı olur. Buradaki tek yakınma, gerekli UserDepartmentTableolmayan bir yedek anahtara sahip olmaktır UserDepartmentID(sadece UserIdve DepartmentIdbirleşik birincil anahtar yapın).

Bir kullanıcı yalnızca tek bir bölüme aitse, tasarımınız mantıklı olur (bölüm arama tablosu hala iyi bir şey olsa da).


18
... Kullanıcı başına birden fazla bölüm mümkündür.
Blrfl

1
Kesinlikle, @Blrfl. Bugünün asla gerçekleşmeyeceği, yarının CEO'su olan bir anevrizmadır çünkü yapmaz.
Adam Crossland

2
Bu tür tedaviye neyin layık olduğuna karar vermenin bir kısmı, sorun alanını anlamaktır. Bazı uygulamalarda, 3804 numaralı çalışanın şirkete Ann Smith ve Ann Jones (evlendikten sonra) adıyla tanındığını bilmek önemli olabilir, bu da çalışanların tablonun adını normalleştirmek için akıllıca bir şeydir. Jim'in durumunda, tarihin kalması için kırıcı masasını genişletmek faydalı olabilir, böylece Ann İK'dan BT'ye geçerse, ona bağlı eski bir isteğin gerçekten İK'nın talebi olduğunu ve BT'nin talebi olduğunu yansıtabilir.
Blrfl

8
YAGNI - veritabanları yeniden düzenlenebilir.
JeffO

2
@Oded, Entity Framework gibi bazı ORM eşleyicileri, birleşik birincil anahtara sahip tablolarla iyi çalışmaz.
maple_shaft

5

Sorunuzda bazı gereksinimler net değil. Doğru cevap, müşterinizin ne istediğine bağlıdır.

0-Bir kullanıcı ile çalışan arasındaki fark nedir?

1-Bir çalışanı varsaymak = kullanıcı, ya bir çalışan departmanları değiştirirse?

2-Bir grup çalışan 1 talepte bulunabilir mi?

3-Bir çalışan birden fazla bölüme ait olabilir mi? Peki ya CEO

4-Talepte bulunabilecek bir çalışan grubu var mı?

5-Bir çalışan kaydı silindiğinde talebe ne olur?

6-Bir isteği silebilir misiniz? İstek silindiğinde ne olur (çalışan kaydını RI ile silmediğinizden emin olun)

7-Çalışan “aynı” talebi birden fazla kez yapabilir (“aynı” kelimesini tanımlayın)

8-Çalışanlar için şirketten ayrıldıklarında talepler nasıl ele alınır (isteklerini iptal eder veya istekleri siler?)

Daha fazla soru olabilir, ancak amacım, çözümün tam gereksinimlere ve proje kapsamına bağlı olduğudur. Bu belirlendikten sonra şema doğrudan türetilebilir. Buna göre sunulan her iki çözüm de doğru olabilir.


+1 bunlar, bu tür bir şema tasarlamadan önce netleştirilmesi gereken harika sorulardır. Mantık akışını beğendim.

@ Surfer513: Güzel yorumunuz için teşekkür ederiz.
NoChance

1

Açık bir şekilde yüksek ücretli danışmanınızın yaptığı şekilde bir birleştirme masası kullanmanın bazı avantajlarından bahseden birkaç noktadan oluşan bir form eklemek istiyorum.

  • Düzgün bir şekilde dizine eklenir (örneğin, UserDepartmentTable iki yabancı anahtarı dizine eklerse), yabancı anahtarların benzersiz olmaması nedeniyle, böyle bir birleştirme tablasında yalnızca küçük bir performans kaybı olur. Yabancı anahtarların benzersiz olmaları garanti edilirse, tanıdığım küçük veritabanı teorisine UserDepartmentTable.Departmentgöre, Usertablodaki diğer sütunları aramaktan daha zor değildir .
  • Birleştirme tablosu, kullanıcı ile departman arasındaki ilişki hakkındaki diğer bilgileri ayarlama konusunda size daha fazla esneklik sağlar (örneğin, yaratılıştaki zaman damgaları).
  • Birleştirme tablosu, ilişkilendirmeyi oldukça kolay bir şekilde "sürmenize" olanak tanır (örneğin, kullanıcı bölümleri değiştirdiğinde, bazı dizin boolean bayrağını UserDepartmentTable.Activeyanlışlamak ve etkin olan yeni bir ilişkilendirme oluşturmak gibi) tetikler . Aynı zamanda iki masalı modelle (sadece Kullanıcı ve Departman) departman birlikteliğine sahip olmak da mümkündür, ancak daha zordur ve birincil anahtarların kopyalanmasını önlemek için en az bir sütun daha eklemek veya veritabanı akrobasi yapmak gerekir.
  • Kolayca bire çok ya da çoktan bire ya da çoktan çok dernek atamanıza izin verir.

Olduğu gibi, yüksek ücretli danışmanınızın yaptığı şeyi yapmamak için birkaç neden var.

  • Yukarıdaki faydaların tümü, gelecekteki ihtiyaçların beklenenleri olup, bugün için işleri karmaşık hale getirmektedir. YAGNI uyumlu değil. İki tablo modelinizden bir kat tablo modeline geçiş yapan bir geçişi yazmak daha sonra büyük bir zorluktur. İşletmenizin ihtiyacı ortaya çıktığında bunu yapabilirsiniz. Bundan önce yapmak kafa karıştırıcı olabilir.
  • Diğer geliştiricilerin kafasını karıştırır. Evet, durumunuzun bir web geliştiricisinin (danışmanların kararlarını gözden geçirdiğiniz yerde) bir katılım tablosunu anlamak ve tanımak olacağını söyleyebilirim, ancak hala gerekenden daha karmaşık ve iş ihtiyacının eksikliğini göz önünde bulundurarak, karışıklığa neden olur.

güzel analiz - ancak, günlük işimde dev olarak herhangi bir boyuta sahip olduğumu söyleyemem, db / c # / vb / etc hakkında bir şey bilen tek kişi benim olduğum dışında ... varsayılan olarak zaman dev. bu oldukça küçük bir proje, bu yüzden danışmanlar çok sayıda masa ve bir araya gelerek “wtf” diyerek beni terk ettiler (ama size iyi insanlar sayesinde şimdi "oic ..." diyorum)
Jim

Oldukça eski bir konu, ancak yine de alakalı ... yeniden yapılanma çok zor olabilir, gelecekte bir yerine birden fazla bölüme ihtiyacınız olduğunu, ancak Kullanıcılar'da FK olarak yalnızca bir bölüm kimliğine sahip olduğunuzu hayal edin. Büyük olasılıkla yinelenen başvuruları (Users.DeptID ve UsersDepartmentsTable) veya Users.DeptID veya XML'deki virgülle ayrılmış listeler gibi tam bir çöp ile bitireceksiniz. YAGNI veya KISS tarafından önerildiği gibi doğru çözüm kolayca eklenemedi, ancak engellenecek.
Erik Hart

0

İhtiyaç duyduğum bilginin tam yapısı olmadan söyleyemem korkunç mu değil mi. Ancak en azından gösterilen parça "WTF" tasarımlarından değildir. Sadece 3. Normal Veri Biçimi Formu olarak görünüyor (teorik olarak ayrıca 4. ve 5. sıradayız)

Kullanıcı konuşması için bazı konuşmalarda, gösterilen parçadaki "doğal" ve "yapay" anahtarların iki okulu arasında yer verilebilir. Daha fazlası değil, gördüğüm kadarıyla

Normalleştirme bir sürü sebebi iyi DB-geliştirici / tasarımcı kuraldır * de * normalleştirmeler hız kazanmak çoğunlukla için gelişmelerin ortasında bazen kullanılmaktadır

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.