Büyük bir "tanrı masası" kullanmanın kötü olmasının birçok nedeni var. Bir telafi örneği veri tabanı ile ilgili sorunları açıklamaya çalışacağım. Spor etkinliklerini modellemeye çalıştığınızı varsayalım. Oyunları ve bu oyunlarda oynayan takımları modellemek istediğinizi söyleyeceğiz. Birden fazla tabloya sahip bir tasarım şöyle görünebilir (bilerek bu çok basittir, bu nedenle daha fazla normalleşmenin uygulanabileceği yerlere takılmayın):
Teams
Id | Name | HomeCity
Games
Id | StartsAt | HomeTeamId | AwayTeamId | Location
ve tek bir masa veritabanı böyle görünecek
TeamsAndGames
Id | TeamName | TeamHomeCity | GameStartsAt | GameHomeTeamId | GameAwayTeamId | Location
İlk önce, bu masalarda endeks oluşturmaya bakalım. Bir takım için şehirdeki bir indekse ihtiyacım olursa, onu Teams
masaya ya da TeamsAndGames
masaya kolayca ekleyebilirim . Ne zaman bir indeks oluşturursanız, bir yerde diskte saklanması ve tabloya satırlar eklenerek güncellenmesi gerektiğini unutmayın. Teams
Masanın durumunda bu oldukça basittir. Yeni bir takım ekledim, veritabanı endeksi günceller. Peki ya ne için TeamsAndGames
? Peki, aynısıTeams
örnek. Bir takım eklerim, indeks güncellenir. Ama bir oyun eklediğimde de oluyor! Bu alan bir oyun için boş olsa da, endeks hala o oyun için güncellenmeli ve diskte saklanmalıdır. Bir indeks için bu kulağa fena gelmiyor. Ancak bu tabloya sıkışmış birçok varlık için birçok endekse ihtiyacınız olduğunda, endeksleri depolayan çok fazla alan harcarsınız ve uygulama yapmadıkları şeyler için onları güncelleyen çok fazla işlemci zamanı harcarsınız.
İkincisi, veri tutarlılığı. İki ayrı masa kullanılması durumunda, hangi takımların bir oyunda oynadığını tanımlamak Games
için Teams
masadan masaya yabancı anahtarlar kullanabilirim . Ve varsayarak yapamıyor HomeTeamId
ve AwayTeamId
sütunlar null değil, veritabanı Yatırdığım her oyun 2 takım var olmasını sağlayacaktır ve bu ekipler veritabanında mevcut olduğunu. Peki ya tek masa senaryosu? Eh, bu tabloda birden fazla varlık olduğu için, bu sütunlar null edilebilir olmalıdır (onları null yapamaz hale getirebilir ve orada çöp verilerini zorlayabilir, ama bu sadece korkunç bir fikirdir). Bu sütunlar null ise, veritabanı artık iki takımı olan bir oyun eklediğinizde artık garanti edemez.
Ama yine de bunun için gitmeye karar verirseniz ne olacak? Yabancı anahtarları, bu alanların aynı tabloda başka bir varlığa işaret edeceği şekilde ayarlarsınız. Ancak şimdi veritabanı, bu varlıkların doğru tür olduklarından değil, tabloda bulunduğundan emin olacaktır. Kolayca GameHomeTeamId
başka bir oyunun kimliğini ayarlayabilir ve veritabanı hiç bir şekilde şikayet etmez. Birden fazla tablo senaryosunda bunu denediyseniz, veritabanı uygun bir sonuç verir.
Bu meseleleri hafifletmeyi deneyebilirsiniz, "peki, bunu asla asla kodda yapmadığımızdan emin olacağız" diyerek. İlk defa hatasız kod yazma yeteneğinize ve bir kullanıcının deneyebileceği her tuhaf kombinasyonunu hesaba katma yeteneğinize güveniyorsanız, hemen devam edin. Şahsen ben de bu şeylerden birini yapma yeteneğimden emin değilim, bu yüzden veritabanının bana ekstra güvenlik ağı vermesine izin vereceğim.
(Tasarımınız, yabancı anahtarlar kullanmak yerine satırlar arasında tüm ilgili verileri kopyaladığınız bir yerdeyse, bu daha da kötüleşir. Yazım / diğer veri tutarsızlıklarının çözülmesi zor olacaktır. "ya da kasıtlıysa (çünkü onlar iki ayrı insan)?)
Üçüncüsü, hemen hemen her sütunun boş olması veya kopyalanmış veya çöp verilerle doldurulması gerekir. Bir oyunun bir TeamName
veya ihtiyacı yok TeamHomeCity
. Bu yüzden her oyunun içinde bir tür yer tutucusuna ya da null olması gerekiyor. Ve null ise, veritabanı mutlu bir şekilde hayırlı bir oyun alacaktır TeamName
. İş mantığınız asla gerçekleşmemesi gerektiğini söylese bile, adı olmayan bir takımı da alacak.
Ayrı tablolar (geliştirici aklını korumak da dahil olmak üzere) isteme nedeniniz için bir kaç neden vardır. Daha büyük bir masanın daha iyi olmasının birkaç nedeni bile vardır (denormalizasyon bazen performansı arttırır). Bu senaryolar az ve çok arasındadır (ve genellikle bunun gerçekten bir sorun olduğunu, eksik bir endeks veya başka bir şey olmadığını göstermek için performans ölçütleriniz olduğunda ele alınmalıdır).
Son olarak, bakımı kolay bir şey geliştirin. Sırf "işe yarıyor" tamam demek değil. Tanrı tablolarını korumaya çalışmak (tanrı sınıfları gibi) bir kabustur. Daha sonra acı çekmek için kendini hazırlıyorsun.