Globals bir veritabanından ne kadar farklı?


250

Sadece karşılaştım bu eski soruya küresel durumu hakkında çok kötü olduğunu ve üst olarak kabul cevabı başka bir yerde başka bir kod gelip değiştirebilir olabileceğinden, küresel değişkenler ile çalışır herhangi bir kod güvenemeyeceğinizi iddia soran onun değer ve ardından verilerinizin farklı olması nedeniyle kodunuzun davranışının ne olacağını bilmiyorsunuz! Ancak buna baktığımda, yardım edemem ama bunun gerçekten zayıf bir açıklama olduğunu düşünüyorum, çünkü bunun bir veritabanında depolanan verilerle çalışmaktan ne farkı var?

Programınız bir veritabanındaki verilerle çalışırken, sisteminizdeki diğer kodların onu değiştirip değiştirmemesi veya tamamen farklı bir programın değişmesi durumunda bile, bu konuda umursamıyorsunuz. Verinin ne olduğu umrunda değil; bütün mesele bu. Önemli olan kodunuzun karşılaştığı verilerle doğru bir şekilde ilgilenmesidir. (Belli ki burada önbelleğe almanın sık sık dikenli meselesine bakıyorum, ama şu an için bunu görmezden gelelim.)

Ancak, üzerinde çalıştığınız veriler, bir veritabanı (veya kullanıcı girişi veya bir ağ soketi veya bir dosya, vb.) Gibi kodunuz üzerinde kontrol sahibi olmayan bir harici kaynaktan geliyorsa ve yanlış bir şey olmazsa Bununla birlikte, kodunuzun içindeki küresel veriler nasıldır - hangi programınızın üzerinde daha fazla kontrol sahibi olduğu - bir şekilde hiç kimsenin problem olarak görmediği tamamen normal şeylerden çok daha az kötü olduğu zaman bir şekilde kötü bir şey?


117
Emekli

10
Bir uygulamada, genellikle veritabanına erişmek için bir araç sağlarsınız, bu ortalama veritabanına erişmek isteyen işlevlere geçer. Bunu global değişkenlerle yapmazsınız, sadece el altında olduklarını bilirsiniz. Bu orada önemli bir fark var.
Andy

45
Global durum, rasgele sayıda uygulama tarafından eşzamanlı olarak erişilen sonsuz sayıda sütunun bulunduğu tek bir satır bulunan tek bir tablo içeren tek bir veritabanına sahip olmak gibidir.
BevynQ

42
Veritabanları da kötüdür.
Stig Hemmer

27
Burada yaptığınız argümanı "tersine çevirmek" ve diğer yöne gitmek eğlencelidir. Başka bir yapıya işaretçi olan bir yapı, mantıksal olarak , bir tablonun bir satırındaki başka bir tablonun başka bir sırasına geçen bir yabancı anahtardır. Yürürme bağlantılı listeler de dahil olmak üzere herhangi bir kodla çalışma, veritabanındaki verileri değiştirmekten farklı mıdır? Cevap: öyle değil. Soru: Öyleyse neden bu kadar farklı araçlar kullanarak hafıza içi veri yapılarını ve veri tabanı veri yapılarını değiştiriyoruz? Cevap: Gerçekten bilmiyorum! İyi bir tasarımdan çok bir tarih kazası gibi görünüyor.
Eric Lippert

Yanıtlar:


118

Öncelikle, belirli bir konuyu vurguladığınız cevabının ve küresel devletin temel kötülüğünün, gelecekte sisteminizin davranışını değiştirmeyi zorlaştırabilecek öngörülemeyen yollarla eşleşmeyi sağladığını söyleyebilirim.

Ancak bu konuyu daha da ileriye götürmekle birlikte, tipik bir nesne yönelimli uygulamada küresel devlet ile bir veritabanında tutulan devlet arasında farklılıklar vardır. Kısacası, bunlardan en önemlileri:

  • Nesneye yönelik sistemler, orijinal türün bir alt türü olduğu sürece, bir nesneyi farklı bir nesne sınıfı ile değiştirmeye izin verir. Bu, sadece veri değil davranışın da değişmesini sağlar .

  • Bir uygulamadaki küresel durum, genellikle bir veritabanının yaptığı güçlü tutarlılık garantisi vermez - bunun için tutarlı bir durum gördüğünüz, atomik güncellemelerin vs. olmadığı bir işlem yoktur.

Ek olarak, veritabanı durumunu gerekli bir kötülük olarak görebiliriz; onu sistemlerimizden çıkarmak imkansızdır. Bununla birlikte, küresel devlet gereksizdir. Tamamen ortadan kaldırabiliriz. Bu yüzden bir veritabanıyla ilgili sorunlar kadar kötü olsa bile, bazı potansiyel sorunları ortadan kaldırabiliriz ve kısmi bir çözüm, çözümden daha iyidir.


44
Tutarlılığın amacı aslında asıl sebep olduğunu düşünüyorum: Genel değişkenler kodda kullanıldığında, genellikle ne zaman başlatıldığını söyleyen bir şey yoktur. Modüller arasındaki bağımlılıklar çağrılar sırasının derinliklerine gizlenmiştir ve iki çağrıyı değiştirmek gibi basit şeyler gerçekten kötü hatalara neden olabilir çünkü aniden bazı global değişken ilk kullanıldığında doğru şekilde başlatılmaz. En azından bu, üzerinde çalışmam gereken ve bir kabusun yeniden canlanmasını sağlayan eski kodla ilgili sorunum.
cmaster

24
@DavidHammen Ben aslında bahsettiğiniz uygulama kategorisinde açıkça bir çevrimiçi oyun için dünya-devlet simülasyonu üzerinde çalıştım ve hatta orada bile (ve bunun için) kullanmıyorum. Küresel devlet kullanılarak bazı verimlilik kazanımları elde edilebilse bile, sorun küresel devletin ölçeklenebilir olmamasıdır . Bu olur zor taşınmak kez kullanılacak tek evreli ve çok dişli mimarisine. Bir NUMA mimarisine taşındığınızda verimsiz hale gelir . Dağıtılmış bir mimariye geçtiğinizde imkansız hale gelir . Alıntıladığın yazı ...
Jules

24
1993. Bu sorunlar o zamanlar daha az sorun teşkil ediyordu. Yazarlar, 1000 nesnenin etkileşimlerini simüle eden tek bir işlemci sistemi üzerinde çalışıyorlardı. Modern bir sistemde, en azından çift çekirdekli bir sistemde bu tür bir simülasyon üzerinde çalışacaksınız, ancak büyük olasılıkla tek bir sistemde en az 6 çekirdek olabilir. Hala daha büyük problemler için bir kümede çalıştırırsınız. Bu tür bir değişim için, küresel devletten kaçınmalısınız çünkü küresel devlet etkili bir şekilde paylaşılamıyor.
Jules

19
Bence veritabanı durumunu "gerekli bir kötülük" olarak adlandırmak biraz zor. Yani, ne zamandan beri devlet kötülük oldu? Devlet bir veritabanının bütün amacıdır. Devlet bilgidir. Devlet olmadan, sahip olduğun tek şey operatörler. Çalışacak bir şeyi olmayan operatörler ne işe yarar? Bu devlet bir yerlere gitmeli. Günün sonunda, işlevsel programlama sadece bir sona erme aracıdır ve devletin değişmemesi, hiçbir şey yapmanın bir anlamı olmayacaktı. Pastacı pastayı gerekli bir kötülük olarak adlandırmak gibi bir şey - bu kötülük değil. Her şeyin noktası bu.
J ...

5
@DavidHammen "hala oyundaki her nesne hakkında en az bir şey bilen bir nesne var" mutlaka doğru değil. Modern dağıtılan simülasyonunda büyük bir tekniktir mevkiinde yararlanarak ve uzak nesneler anlamına yaklaşımlar böyle yapıyor değil o uzak nesnelerin sahipleri tarafından kendilerine sağlanan yalnızca hangi verilerin, uzakta her şeyi bilmemiz gerekir.
JAB

75

İlk olarak, bağladığınız soruya verilen cevaplara dayanarak küresel değişkenlerle ilgili sorunlar nelerdir?

Çok kısaca program durumunu tahmin edilemez kılar.

Veritabanları, zamanın büyük çoğunluğudur, ACID uyumludur. ACID özellikle bir veri deposunu öngörülemeyen veya güvenilmez hale getiren temel sorunlara yöneliktir.

Ayrıca, küresel devlet, kodunuzun okunabilirliğine zarar verir.

Bunun nedeni, küresel değişkenlerin kullanımlarından uzakta, belki de farklı bir dosyada bile olsa bir kapsamda mevcut olmasıdır. Bir veritabanı kullanırken, okuduğunuz koda göre yerel olan (veya olması gereken) bir kayıt seti veya ORM nesnesi kullanıyorsunuzdur.

Veritabanı sürücüleri, genellikle, sorun alanından bağımsız olarak aynı verilere erişmek için tutarlı ve anlaşılır bir arabirim sağlar. Bir veritabanından veri aldığınızda, programın verilerin bir kopyası vardır . Güncellemeler atomiktir. Siz kendiniz senkronizasyon eklemediğiniz sürece, birden fazla iş parçacığının veya yöntemin atomik olmayan aynı veri parçası üzerinde çalıştığı global değişkenlerin aksine. Verilerdeki güncellemeler tahmin edilemez ve izlenmesi zor. Güncellemeler serpiştirilebilir, bu da çok iş parçacıklı veri bozulmalarının (örneğin serpiştirilmiş artışlar gibi) bog standardı ders kitabı örneklerine neden olur.

Veritabanları tipik olarak başlamak için genel değişkenlerden farklı verileri modeller, ancak bunu bir an için bir kenara bırakırsak, veritabanları temelden başlayarak global değişkenlerle ilgili endişelerin çoğunu azaltan bir ACID uyumlu veri deposu olarak tasarlanır.


4
+1 Söylediğiniz şey, veritabanlarının işlemlere sahip olması ve çok sayıda küresel devletin atomik olarak okunmasını ve yazılmasını mümkün kılıyor . Tamamen bağımsız olan her bilgi için sadece global değişkenler kullanılarak çözülebilecek iyi bir nokta .
lbb0

1
@ l0b0 işlemleri ACID hedeflerinin çoğuna ulaşan mekanizmadır, doğru. Ancak DB arayüzünün kendisi, verileri daha yerel bir kapsama alanına getirerek kodu daha açık hale getirir. Kaynaklarla deneme bloğuyla bir JDBC RecordSet veya tek bir işlev çağrısı kullanarak bir veri parçası alan bir ORM işlevi kullanmayı düşünün. Bunu, global bir yerde okuduğunuz koddan uzakta olan verileri yönetmekle karşılaştırın.

1
Bu nedenle, fonksiyonun başlangıcındaki bir yerel değişkene (bir mutex ile) değeri kopyalarsam, yerel değişkeni değiştirir ve ardından değeri, sonunda genel değişkene geri kopyalarsam genel değişkenleri kullanmam uygun olur. işlev? (... sözlü olarak sordu.)
RM

1
@RM İki noktadan bahsetti. Ortaya attığınız şey, ilkine hitap edebilir (program durumu tahmin edilemez), ancak ikinciye hitap etmez (kodunuzun okunabilirliği). Aslında, programınızın okunabilirliğini daha da kötüleştirebilir: P.
riwalk

1
@RM İşleviniz tutarlı şekilde çalışır, evet. Ancak, bu arada başka bir şeyin global değişkeni değiştirip değiştirmediği ve bu değişimin ona yazdıklarınızdan daha önemli olup olmadığı sorusunu sorarsınız. Tabii ki veritabanları da aynı problemde olabilir.
Graham

45

Birkaç gözlem önerirdim:

Evet, bir veritabanı küresel bir durumdur.

Aslında, belirttiğiniz gibi süper küresel bir devlettir. Bu evrensel! Kapsamı veritabanına bağlanan herhangi bir şeyi veya herhangi birini gerektirir . Ve yıllarca deneyime sahip birçok insanın, verilerdeki "garip şeylerin" ilgili uygulamaların birinde veya daha fazlasında "beklenmeyen davranış" yarattığına dair korku hikayeleri anlatabileceğinden şüpheliyim ...

Global bir değişken kullanmanın olası sonuçlarından biri, iki farklı "modül" ün bu değişkeni kendi amaçları için kullanmasıdır. Ve bu ölçüde, bir veritabanı tablosu farklı değildir. Aynı soruna kurban olabilir.

Hmm ... İşte şey:

Bir modül dışsal olarak bir şekilde çalışmazsa, hiçbir şey yapmaz.

Kullanışlı bir modül veri verilebilir veya onu bulabilir . Ve, verileri döndürebilir veya durumu değiştirebilir . Ancak, dış dünya ile bir şekilde etkileşime girmezse, hiçbir şey yapmaz.

Şimdi, tercihimiz veriyi almak ve veriyi geri getirmektir . Çoğu modülden, dış dünyanın ne yaptığını tamamen göz ardı ederek yazılabilirlerse yazmaları daha kolaydır. Ama sonuçta, bir şey gerekiyor bulmak veri ve değiştirmek o dış, küresel devlet.

Ayrıca, gerçek dünyadaki uygulamalarda, veriler çeşitli işlemlerle okunup güncellenebilmesi için mevcuttur . Bazı sorunlar kilitler ve işlemlerle önlenir. Ancak, bu işlemlerin prensipte birbirleriyle çelişmesini önlemek , günün sonunda, basitçe dikkatli düşünmeyi gerektirir . (Ve hatalar yapıyor ...)

Ancak, genel olarak doğrudan küresel devletle de çalışmıyoruz .

Uygulama veri katmanında (SQL'de veya her neyse) yaşamıyorsa, modüllerimizin çalıştığı nesneler aslında paylaşılan global durumun kopyalarıdır . Gerçek, paylaşılan duruma etki etmeyenleri istediğimiz her şeyi yapabiliriz .

Ve bu küresel durumu değiştirmemiz gereken durumlarda, verdiğimiz bilgilerin değişmediği varsayımı altında, genel olarak yerel kürelerimizde yapacağımız aynı kilitleme işlemini gerçekleştirebiliriz.

Biz daha Ve son olarak, genellikle veritabanları ile farklı şeyler yapmak olabilir yaramaz globaller ile.

Yaramaz, kırılmış bir küresel şöyle görünür:

Int32 counter = 0;

public someMethod() {
  for (counter = 0; counter < whatever; counter++) {
    // do other stuff.
  }
}

public otherMethod() {
  for (counter = 100; counter < whatever; counter--) {
    // do other stuff.
  }
}

Bunun gibi işlemsel / operasyonel işler için veritabanlarını kullanmıyoruz. Veritabanının yavaş olması ve bizi engelleyen basit bir değişkenin göreceli uygunluğu olabilir: Veritabanlarıyla yapılan yavaş ve garip etkileşimlerimiz, onları tarihsel olarak değişkenlerle yaptığımız birçok hata için kötü adaylar haline getirmektedir .


3
Yolu garanti (biz kabul edemeyiz beri) bir veritabanında "Biz değişmedi verildi veriler" bir işlem olacaktır.
l0b0

Evet ... "aynı tarz kilitleme" ile ima edilmeli.
svidgen

Ancak, günün sonunda dikkatlice düşünmek zor olabilir.

Evet, veritabanları gerçekten de küresel bir durumdur - bu yüzden git veya ipfs gibi bir şey kullanarak veri paylaşmak çok caziptir.
William Payne

21

Aşağıdaki temel iddiaya katılmıyorum:

Programınız bir veritabanındaki verilerle çalışırken, sisteminizdeki diğer kodların onu değiştirip değiştirmemesi veya tamamen farklı bir programın değişmesi durumunda bile, bu konuda umursamıyorsunuz.

İlk düşüncem "Wow. Just Wow" idi. Tam olarak bundan kaçınmaya çalışmak için çok fazla zaman ve çaba harcanmaktadır - ve her bir uygulama için hangi takas ve zararların işe yaradığını hesaplamak için harcanmaktadır. Sadece görmezden gelmek felaket için bir reçetedir.

Ama aynı zamanda mimari düzeyde de diasgree. Global bir değişken sadece küresel durum değildir. Her yerden şeffaf şekilde erişilebilen küresel bir devlettir. Bir veritabanını kullanmanın aksine, bunun için bir tanıtıcıya sahip olmanız gerekir - (genel değişkende tanıtıcıdan daha fazla saklamadığınız sürece ....)

Örneğin global bir değişken kullanmak şuna benzeyebilir

int looks_ok_but_isnt() {
  return global_int++;
}

int somewhere_else() {
  ...
  int v = looks_ok_but_isnt();
  ...
}

Fakat aynı şeyi bir veritabanıyla yapmak, ne yaptığı konusunda daha açık olmak zorunda kalacaktı.

int looks_like_its_using_a_database( MyDB * db ) {
   return db->get_and_increment("v");
}

int somewhere_else( MyBD * db ) { 
   ...
   v = looks_like_its_using_a_database(db);
   ...
}

Bir veritabanı açıkça bir veritabanıyla karıştırılıyor. Bir veritabanı kullanmak istemiyorsanız, açık durumu kullanabilirsiniz ve bu veritabanı durumuyla neredeyse aynı görünmektedir.

int looks_like_it_uses_explicit_state( MyState * state ) {
   return state->v++;
}


int somewhere_else( MyState * state ) { 
   ...
   v = looks_like_it_uses_explicit_state(state);
   ...
}

Bu yüzden bir veritabanı kullanmanın, genel durumları kullanmaktan çok, açık durum kullanmaktan çok daha fazlası olduğunu savunuyorum.


2
Evet, OP: “ Verilerin ne olduğu umrumda değil; bütün mesele bu ” derken ilginç olduğunu düşündüm - umursamıyorsak, neden saklıyorsun? Sadece değişkenleri ve veriler kullanılarak duralım: İşte bir düşünce olduğunu hiç . Bu işleri çok daha kolaylaştıracak. "Dünyayı durdur, kurtulmak istiyorum!"

1
+1 Aynı veri tabanından yazma ve okuma farklı konu başlıkları veya uygulamalar çok sayıda iyi bilinen problemin potansiyel kaynağıdır, bu yüzden her zaman veri tabanı veya uygulama düzeyinde bununla başa çıkma stratejisi olmalı veya her ikisi de. Bu yüzden kesinlikle (uygulama geliştiricisi) veritabanında başka kim okuyor veya yazıyor umrumda değil.
Andres F.

1
+1 Bir yandan, bu cevap, bağımlılık enjeksiyonundan en çok nefret ettiğimi açıklamaktadır. Bu tür bağımlılıkları gizler.
jpmc26

@ jpmc26 Kelimeleri işaretliyor olabilirim, ancak yukarıdaki durum bağımlılık enjeksiyonunun (küresel aramanın aksine) bağımlılıkları açık hale getirmeye nasıl yardımcı olduğuna iyi bir örnek değil mi? Bana öyle geliyor ki, belki de JAX-RS ve Spring'in kullandığı açıklama sihri gibi, belirli API'ler ile ilgili sorunlarınız var.
Emil Lundberg

2
@EmilLundberg Hayır, sorun bir hiyerarşiniz olduğunda. Bağımlılık enjeksiyonu, daha düşük katmanların bağımlılıklarını yüksek katmanlardaki kodlardan gizleyerek hangi şeylerin etkileşime girdiğini takip etmeyi zorlaştırır. Mesela, eğer MakeNewThingbağlıysam MakeNewThingInDbve kontrolör sınıfım kullanıyorsa MakeNewThing, kontrol cihazımdaki koddan veritabanını değiştirdiğim belli değil. Peki ya şu anki işlemimi DB'ye yükleyen başka bir sınıf kullanırsam ? DI bir nesnenin kapsamını kontrol etmeyi çok zorlaştırır.
jpmc26

18

Devletin başka bir yerde değiştirilebilmesi nedeniyle, küresel değişkenlerin tek sebebinin güvenilemediği meselesi, kendi içinde, onları kullanmaya yetmeyecek bir neden olmadığı konusunda hemfikirdi (bu oldukça iyi bir sebep!). Bu sorunun cevabı, esas olarak, bir değişkenin erişiminin yalnızca ilgilendiği kod alanlarına erişiminin kısıtlanmasının daha anlamlı olacağı kullanımı açıklıyordu.

Ancak, veritabanları farklı bir konudur, çünkü tabiri caizse “küresel” olarak erişilmek amacıyla tasarlandılar.

Örneğin:

  • Veritabanları genellikle, kendilerine erişen dilden daha ileri giden yerleşik tür ve yapı doğrulaması yapar.
  • Veritabanları tutarsız durumları önleyen ve son durumun global bir nesnede neye benzeyeceğine dair hiçbir garanti bulunmadığı durumlarda (tektonun arkasına gizlenmemişse), işlemlere dayalı olarak neredeyse oy birliğiyle güncellenir.
  • Veri tabanı yapısı, en azından dolaylı olarak, tablodan veya nesne yapısından yola çıkılarak, kullanılan uygulamadan daha fazla belgelenir.

En önemlisi, veritabanları küresel bir değişkenden farklı bir amaca hizmet eder. Veritabanları, global değişkenlerin belirli nişlere (haklı olduğunda) hizmet ettiği büyük miktarlarda organize veriyi depolamak ve aramak içindir.


1
Huh. Neredeyse aynı bir cevap yazarken yarı yolda iken beni yendin. :)
Jules

@Jules cevabınız şeylerin uygulama tarafında daha fazla ayrıntı sağlar; devam et.
Jeffrey Sweeney

Ancak, tamamen veri erişimi için saklı prosedürlere bağlı olmadığınız sürece, tüm bu yapı tabloların amaçlandığı şekilde kullanılmasını zorunlu kılmayacaktır. Veya bu işlemler uygun sırayla gerçekleştirilir. Veya bu kilitler (işlemler) gerektiği gibi oluşturulur.
svidgen

Merhaba, Java gibi statik bir dil kullanıyorsanız, 1 ve 3 numaralı noktalar hala uygulanabilir mi?
Jesvin Jose

@aitchnyu Mutlaka değil. Yapılmakta olan nokta, veritabanlarının, genel değişkenlerin tipik olarak bulunmadığı verileri güvenilir bir şekilde paylaşmak amacıyla oluşturulmuş olmasıdır. Sıkı bir dilde kendi kendini belgeleyen bir arabirim uygulayan bir nesne, gevşek bir yazılı NoSQL veritabanından bile farklı bir amaca hizmet eder.
Jeffrey Sweeney

10

Fakat buna baktığımda, yardım edemem ama bunun gerçekten zayıf bir açıklama olduğunu düşünüyorum, çünkü bunun bir veritabanında depolanan verilerle çalışmaktan ne farkı var?

Veya etkileşimli bir cihazla, bir dosyayla, paylaşılan hafızalı vb. İle çalışmaktan farklıdır. Her çalıştırıldığında aynı şeyi yapan bir program çok sıkıcı ve oldukça işe yaramaz bir programdır. Yani evet, zayıf bir argüman.

Bana göre, küresel değişkenler açısından fark yaratan fark, gizli ve korunmasız iletişim hatları oluşturmalarıdır. Klavyeden okumak çok açık ve korumalıdır. Belirli bir işlev çağrısı yapmam gerekiyor ve klavye sürücüsüne erişemiyorum. Aynısı dosya erişimi, paylaşılan hafıza ve veritabanınız için de geçerlidir. Bu işlevin klavyeden okuduğu, bir işlevin bir dosyaya eriştiği, diğer bazı işlevlerin paylaşılan belleğe eriştiği (ve bunun etrafında daha iyi korumalar olması) ve diğer bazı işlevlerin bir veritabanına eriştiği açıktır.

Öte yandan, küresel değişkenlerle, hiçbir şekilde açık değildir. API aramak diyor foo(this_argument, that_argument). Arama sırasında genel değişkenin g_DangerWillRobinsonbir değere ayarlanması gerektiğini ancak aramadan önce foo(veya aramadan sonra incelenmesini foo) söyleyen hiçbir şey yoktur .


Google, C ++ 'da const olmayan referans argümanlarının kullanılmasını yasakladı çünkü foo(x)değişecek olan kodun okuyucusu için açık değildir xçünkü bu fooargüman olarak sabit olmayan bir referans alır. (Hem işlev tanımı hem de arama sitesinin refanahtar kelimeyle bir referans parametresi seçmesi gerektiğini belirten C # ile karşılaştırın .) Bu konuda Google standardı ile aynı fikirde olmasam da, onların anlamını anlıyorum.

Kod bir kez yazılır ve birkaç defa değiştirilir, ancak her şey yolundaysa birçok defa okunur. Gizli iletişim hatları çok kötü karma. C ++ 'nın const olmayan referansı küçük bir gizli iletişim hattını temsil eder. İyi bir API veya iyi bir IDE bana "Ah! Bu referans olarak adlandırılır." Diyecek. Global değişkenler çok büyük bir gizli iletişim hattıdır.


Cevabınız daha mantıklı.
Billal Begueradj

8

Alıntılanan açıklamanın konuyu muhakemenin saçma olduğu noktaya getirdiğini düşünüyorum. Tabii ki, harici bir veritabanının durumu küresel duruma katkıda bulunur. Önemli soru nasılProgramınız (değiştirilebilir) küresel duruma bağlıdır. Beyaz alandaki dizeleri bölmek için bir kütüphane işlevi bir veritabanında saklanan aracı sonuçlara bağlıysa, bu tasarıma en azından aynı amaç için kullanılan global bir karakter dizisine itiraz edeceğim kadar itiraz ediyorum. Öte yandan, uygulamanızın bu noktada iş verilerini depolamak için tam gelişmiş bir DBMS'ye gereksinim duymadığına karar verirseniz ve küresel bir bellek içi anahtar değer yapısı işe yarayacaksa, bu mutlaka zayıf bir tasarımın işareti değildir. Önemli olan şudur - verilerinizi depolamak için hangi çözümü seçerseniz seçin - bu seçenek sistemin çok küçük bir bölümüne izole edilmiştir, böylece çoğu bileşen dağıtım için seçilen çözüme agnostik olabilir ve izolasyon ve dağıtımda birim testine tabi tutulabilir çözüm daha az çabayla daha sonra değiştirilebilir.


8

Ağırlıklı olarak yerleşik bellenim ile çalışan bir yazılım mühendisi olarak, neredeyse her zaman modüller arasında giden her şey için global değişkenler kullanıyorum. Aslında, gömülü için en iyi yöntemdir. Statik olarak atanırlar, bu yüzden yığını / yığını üfleme riski yoktur ve fonksiyon girişi / çıkışı sırasında yığın tahsisi / temizliği için fazladan zaman harcanmaz.

Bu olumsuz o zamanın yok bu değişkenlerin nasıl kullanıldığını düşünmek zorundayız ve bu bir çok veritabanı çekişmeler girer düşünce aynı tür aşağı gelir. Değişkenlerin herhangi bir zaman uyumsuz okuma / yazma işlemi atomik olmalıdır . Birden fazla yer değişken yazabiliyorsa, bazı düşünceler her zaman geçerli veri yazdıklarından emin olmak zorundadır, bu nedenle önceki yazma keyfi değiştirilmez (veya keyfi değiştirme yapmak güvenli bir şeydir). Aynı değişken bir kereden fazla okunursa, değişkenler okumalar arasındaki değeri değiştirirse ne olacağı göz önünde bulundurulmalı veya değişkenin bir kopyası başlangıçta alınmalı, böylece işlem tutarlı bir değer kullanılarak yapılsa bile Bu değer işleme sırasında eskimiş olur.

(Sonuncusu için, bir uçak karşı önlem sistemi üzerinde çalışan bir sözleşmenin ilk günümde, güvenlikle ilgili oldukça yüksek, yazılım ekibi bir hafta kadar bir süredir anlamaya çalıştıkları bir hata raporuna bakıyorlardı. Geliştirme araçlarını ve kodun bir kopyasını indirmek için yeterli zamanım vardı. "Bu değişken okuma ve neden arasında güncellenemedi mi?" Diye sordum ama gerçekten bir cevap alamadım. Sonuçta yeni bir adam tanıyor mu? Bu yüzden hala tartışıyorlarsa da, değişkeni atomik olarak okumak için koruyucu kod ekledim, yerel bir yapı yaptım ve temel olarak "hey beyler, bunu dene" demiştim. . :)

Bu nedenle, küresel değişkenler açıkça kötü bir şey değildir, ancak onları dikkatlice düşünmezseniz sizi çok çeşitli konulara açık bırakırlar.


7

Hangi boyutta yargıladığınıza bağlı olarak, global değişkenler ve veritabanı erişimi birbirinden ayrı olabilir, ancak onları bağımlılıklar olarak değerlendirdiğimiz sürece, onlar aynıdır.

Fonksiyonel programlamanın saf fonksiyon tanımını, sadece girdi olarak aldığı ve deterministik bir çıktı üreten parametrelere bağlı olması gerektiğini ifade edelim. Yani, iki kez aynı argüman kümesine bakıldığında, aynı sonucu vermesi gerekir.

Bir fonksiyon global bir değişkene bağlı olduğunda, artık saf olarak kabul edilemez, çünkü aynı set veya argümanlar için, farklı değişkenler verebilir çünkü global değişkenin değeri çağrılar arasında değişebilir.

Bununla birlikte, global değişkeni, fonksiyonun arabiriminin bir parçası olarak diğer argümanların bir parçası olarak kabul edersek, fonksiyon yine de belirleyici olarak görülebilir, bu yüzden sorun bu değil. Sorun yalnızca, görünüşte açık fonksiyonlardan beklenmedik bir davranışla şaşırdığımız ana kadar gizli kalması , sonra da gizli bağımlılıkları keşfetmek için uygulamalarını okumaya devam etmesi .

Bu bölüm, global bir değişkenin gizli bir bağımlılık haline geldiği an, programcılar tarafından kötülük olarak kabul edilir. Kodun nedenini zorlaştırır, nasıl davranacağını tahmin etmeyi zorlaştırır, yeniden kullanması zor, test edilmesi zor ve özellikle bir sorun oluştuğunda hata ayıklama ve sabitleme süresini artırır.

Veritabanına bağımlılığı gizlediğimizde de aynı şey olur. Veri tabanı sorgularına ve komutlarına doğrudan çağrılar yapan, bu bağımlılıkları gizleyen ve genel değişkenlerin neden olduğu aynı sıkıntıya neden olan fonksiyonlarımız veya nesnelerimiz olabilir; ya da açıkça ortaya koyabiliriz; ki bu, ortaya çıktığı gibi, depo deseni, veri deposu, ağ geçidi, vb. gibi birçok isimden geçen en iyi uygulama olarak kabul edilir.

Not: Eşzamanlılık olup olmadığı gibi, bu karşılaştırma için önemli olan başka hususlar da var, ancak bu nokta burada başka cevaplarla kapsanıyor.


Bunu bağımlılık açısından almanı seviyorum.
cbojar

6

Tamam, tarihsel noktadan başlayalım.

Eski bir uygulamadayız, tipik montaj ve C karışımınızla yazılmıştır. İşlev yok, sadece prosedürler var . Bir argüman veya argüman değerini döndürmek istediğinizde global bir değişken kullanırsınız. Söylemeye gerek yok, bunu takip etmek oldukça zor ve genel olarak her prosedür her global değişkenle ne isterse yapabilir. Şaşırtıcı olmayan bir şekilde, insanlar mümkün olan en kısa sürede farklı argümanlara ve geri dönüş değerlerine dönmeye başladılar (performans yapılmaması açısından kritik bir performans olmadığı sürece - örneğin, Build Engine (Duke 3D) kaynak koduna bakın). Küresel değişkenlerin nefreti burada doğdu - her bir prosedürün hangi küresel durumu okuyacağı ve değiştireceği hakkında çok az fikriniz vardı ve prosedürün güvenli bir şekilde çağrılmasını gerçekten yuvalayamadı.

Bu, küresel değişken nefretinin geçmişte kaldığı anlamına mı geliyor? Tam değil.

Öncelikle, şu anda üzerinde çalışmakta olduğum projedeki argümanları iletmek için aynı yaklaşımı gördüğümü belirtmek zorundayım . C # 'daki iki referans tipini yaklaşık 10 yıllık bir projede geçirmek için. Kelimenin tam anlamıyla böyle yapmak için iyi bir neden yok ve büyük olasılıkla ya kargo danışmanlığından ya da C # 'nın nasıl çalıştığını tam olarak yanlış anlamanın doğmasından doğdu.

Daha büyük nokta, global değişkenler ekleyerek, bu global değişkene erişimi olan her bir kod parçasının kapsamını genişletiyor olmanızdır. "Yöntemlerini kısa tut" gibi tüm önerileri hatırlıyor musun? 600 global değişkeniniz varsa (yine, gerçek dünyadan bir örnek: /), tüm yöntem kapsamlarınız bu 600 global değişken tarafından örtük olarak genişletilir ve kimin neye erişimi olduğunu takip etmenin basit bir yolu yoktur.

Yanlış yapılırsa (her zamanki gibi :), genel değişkenler birbirleriyle eşleşebilir. Fakat nasıl bağlandıkları hakkında hiçbir fikriniz yok ve küresel devletin her zaman tutarlı olmasını sağlayacak hiçbir mekanizma yok. Bir şeyleri tutarlı tutmak ve denemek için kritik bölümler ekleseniz bile, bunun uygun bir ACID veritabanıyla zayıf şekilde karşılaştığını göreceksiniz:

  • "İşlem" den önceki eski değerleri korumadığınız sürece, kısmi bir güncellemeyi geri alma imkanı yoktur. Söylemeye gerek yok, bu noktada, bir değeri argüman olarak iletmek zaten bir kazanç :)
  • Aynı duruma erişen herkes aynı eşitleme işlemine bağlı kalmalıdır . Ancak bunu uygulamanın yolu yok - kritik bölümü ayarlamayı unutursanız, battınız.
  • Tüm erişimi doğru şekilde senkronize etseniz bile, kısmen değiştirilmiş duruma erişen iç içe geçmiş aramalar olabilir. Bu, ya kilitlendiğiniz (kritik bölümleriniz önemsiz değilse) ya da tutarsız verilerle ilgilendiğiniz anlamına gelir (isteksiz ise).

Bu sorunları çözmek mümkün mü? Pek sayılmaz. Bunu halletmek için enkapsülasyona veya çok katı bir disipline ihtiyacınız var. İşleri doğru yapmak zor ve bu genellikle yazılım geliştirme başarısı için iyi bir tarif değil :)

Küçük kapsam, kodun nedenini kolaylaştıracak hale gelir. Global değişkenler en basit kod parçalarını bile dahil eder.

Elbette, bu küresel kapsamın kötü olduğu anlamına gelmez. Sadece aradığınız ilk çözüm olmamalı - "uygulaması basit, bakımı zor" için tipik bir örnek.


Fiziksel dünyaya çok benziyor: şeyleri geri almak çok zor.

Bu iyi bir cevap, ancak başlangıçta bir tez ifadesine (TL; DR bölümü) dayanabilir.
jpmc26

6

Global bir değişken bir araçtır, iyilik ve kötülük için kullanılabilir.

Bir veritabanı bir araçtır, iyilik ve kötülük için kullanılabilir.

Orijinal posterin belirttiği gibi, fark o kadar da büyük değil.

Deneyimsiz öğrenciler genellikle böceklerin başkalarının başına gelen bir şey olduğunu düşünür. Öğretmenler, kötü tasarımın cezalandırılması için basitleştirilmiş bir neden olarak "Küresel değişkenler kötüdür" ü kullanırlar. Öğrenciler genellikle 100 satırlık programlarının hatasız olduğu için aynı yöntemlerin 10000 satırlık programlarda kullanılabileceği anlamına gelmediğini anlamıyor.

Veritabanlarıyla çalıştığınızda, programın konusu olduğu için küresel devleti yasaklayamazsınız. Bunun yerine, ACID ve Normal Formlar vb. Gibi daha fazla ayrıntı kılavuzu alırsınız.

İnsanlar ACID yaklaşımını global değişkenlere kullanırsa, o kadar da kötü olmazlardı.

Öte yandan, veritabanlarını kötü tasarlarsanız, kabus olabilirler.


3
Stackoverflow'taki tipik öğrenci iddiası: Bana yardım et! Kodum mükemmel, ama doğru çalışmıyor!
David Hammen

"Küresel değişkenlere ACID yaklaşımı" - bkz. Clojure'deki referanslar.
Charles Duffy

@DavidHammen ve profesyonellerin öğrencilerin aksine beyinleri olduğunu düşünüyor musunuz?
Billal Begueradj

@BillalBEGUERADJ - Profesyoneller ve öğrenciler arasındaki fark budur. Yılların verdiği deneyime rağmen ve kod inceleme, test etme, vb. Gibi en iyi çabalara rağmen, kodumuzun mükemmel olmadığını biliyoruz.
David Hammen


5

Bana göre birincil kötülük, Globals'ın eşzamanlılık sorunlarına karşı korumasız olduğu yönünde. Globals ile bu tür meseleleri ele almak için mekanizmalar ekleyebilirsiniz, ancak çözdüğünüz eşzamanlılık sorunlarını ne kadar çok olursa, Globals'ınız veritabanını taklit etmeye başlar. İkincil kötülük kullanım sözleşmesi değildir.


3
Örneğin, errnoC.
David Hammen

1
Bu, tam olarak neden küresel ve veritabanlarının aynı olmadığını açıklar. Başka farklılıklar olabilir ama spesifik göreviniz kavramı tamamen yok ediyor. Hızlı bir kod örneği verdiyse, eminim çok fazla oy alırsınız. örneğin, MyFunc () {x = globalVar * 5; // .... Başka bir işlem; y = globalVar * 34; // Hata! Bazı başka işlemler, bazı diğer işlemler sırasında globalVar'ı değiştirebilirdi ve x ve y, hesaplamalarında globalVar için farklı değerler kullanıyor, bu da neredeyse kesinlikle istenen sonuçları vermeyecek.
Dunk

5

Diğer cevaplardan bazıları, bir veritabanını kullanmanın neden iyi olduğunu açıklamaya çalışır. Onlar yanlış! Bir veritabanı global bir durumdur ve aynı şekilde bir singleton veya global bir değişken kadar kötüdür. Yerel bir Harita veya Dizi yerine kolayca kullanabileceğiniz bir veritabanı kullanmak her türlü yanlışlıktır!

Küresel değişkenler, kötüye kullanım riski taşıyan küresel erişime izin verir. Global değişkenlerin de bir tarafı vardır. Global değişkenler genellikle kaçınmalısınız şey, olduğu söylenen değil Hiç kullanmak asla bir şey. Onlardan kolayca kaçınabiliyorsanız onlardan kaçınmalısınız. Ancak, faydalar dezavantajlardan ağır basarsa, elbette onları kullanmalısın! *

Aynı şey **, küresel durum olan veritabanları için de geçerlidir - aynı küresel değişkenler gibi. Bir veritabanına erişmeden bunu yapabiliyorsanız ve ortaya çıkan mantık ihtiyacınız olan her şeyi yapar ve eşit derecede karmaşıksa, bir veritabanı kullanmak, projeniz için herhangi bir yararı olmadan artmış risk ekler.

Gerçek hayatta, birçok uygulama tasarım için küresel devlet, bazen ısrarcı küresel devlet gerektirir - bu yüzden dosyalarımız, veritabanlarımız, vb.


* Buradaki istisna öğrencilerdir. Öğrencilerin küresel değişkenleri kullanmalarını yasaklamak mantıklıdır, böylece alternatiflerin ne olduğunu öğrenmeleri gerekir.

** Bazı cevaplar yanlış bir şekilde veritabanlarının bir şekilde diğer küresel devlet biçimlerinden daha iyi korunduğunu iddia eder (soru açıkça sadece küresel değişkenlerle değil, küresel durumla ilgilidir ). Bu bollocks. Veritabanı senaryosunda sunulan birincil koruma, diğer tüm küresel durumlar için tamamen aynı olan konvansiyondur. Çoğu dil const, yapıcıya yerleştirildikten sonra durumlarını değiştirmeye izin vermeyen sınıflar ya da iş parçacığı bilgileri veya program durumunu hesaba katabilecek alıcılar ve belirleyiciler gibi küresel devlet için de birçok ek koruma sağlar .


2

Bir anlamda, küresel değişkenler ile bir veritabanı arasındaki fark, bir nesnenin özel ve genel üyeleri arasındaki farkla aynıdır (kimsenin hala ortak alan kullandığını varsayarsak). Tüm programın bir nesne olduğunu düşünüyorsanız, o zaman geneller özel değişkenlerdir ve veritabanı ortak alanlardır.

Buradaki anahtar ayrım, üstlenilen sorumluluğun bir parçası.

Bir nesne yazdığınızda, üye yöntemlerini koruyan herkesin özel alanların iyi davranıldığından emin olacağı varsayılır. Ancak zaten kamuya açık alanların durumu hakkındaki varsayımlardan vazgeçtiniz ve onlara daha fazla özen gösterin.

Aynı varsayım, küresel v / s veritabanına daha geniş bir düzeyde uygulanır. Ayrıca, programlama dili / ekosistemi, özel v / s halkına erişim kısıtlamalarını (paylaşılmamış bellek) globals v / s veritabanında uyguladığı gibi sağlar.

Çok okuyuculuk devreye girdiğinde, özel v / s genel v / s küresel v / s veritabanı kavramı sadece bir spektrumdaki ayrımlardan ibarettir.

static int global; // within process memory space
static int dbvar; // mirrors/caches data outside process memory space

class Cls {
    public: static int class_public; // essentially the same as global
    private: static int class_private; // but public to all methods in class

    private: static void method() {
        static int method_private; // but public to all scopes in method
        // ...
        {
            static int scope1_private; // mutex guarded
            int the_only_truly_private_data;
        }
        // ...
        {
            static int scope2_private; // mutex guarded
        }
    }
}

1

Bir veritabanı olabilir küresel devlet olabilir ama her zaman olmak zorunda değildir. Kontrolünüz olmadığı varsayımına katılmıyorum. Bunu yönetmenin bir yolu kilitleme ve güvenlik. Bu kayıt, tablo veya veritabanının tamamında yapılabilir. Başka bir yaklaşım, eğer veriler eskiyse bir kaydın değiştirilmesini önleyecek bir tür sürüm alanına sahip olmaktır.

Genel bir değişken gibi, bir veritabanındaki değerler kilidini açtıktan sonra değiştirilebilir, ancak erişimi denetlemenin birçok yolu vardır (tüm kullanıcılara parolayı veri değiştirmesine izin verilen hesaba vermeyin.). Sınırlı erişimi olan bir değişkeniniz varsa, bu çok genel değildir.


0

Birkaç fark var:

  • Bir veritabanı değeri olabilir anında değiştirilebilir. Öte yandan kodunda ayarlanan bir küresel değeri olamaz başvurunuzu yeniden düzenlemek ve kodunuzu değiştirmek sürece değiştirilemez. Aslında, bu kasıtlı. Bir veritabanı zaman içinde değişebilecek değerler içindir, ancak global değişkenler yalnızca asla değişmeyecek olan şeyler için ve gerçek veriler içermediklerinde olmalıdır.

  • Bir veritabanı değerinin (satır, sütun) bir bağlamı ve veritabanında ilişkisel bir eşlemesi vardır. Bu ilişki, Jailer gibi araçlar kullanılarak kolayca çıkarılabilir ve analiz edilebilir (örneğin). Öte yandan, küresel bir değişken biraz farklıdır. Tüm kullanımları bulabilirsiniz, ancak değişkenin dünyanızın geri kalanıyla etkileşime girdiği tüm yolları anlatmanız imkansız olacak .

  • Global değişkenler daha hızlı . Veritabanından bir şey almak için bir veritabanı bağlantısı yapılmasını gerektirir, benim için bir seçim yapın ve ardından veritabanı bağlantısı kapatılmalıdır. Gereksinim duyabileceğiniz her tür dönüşüm bunun üzerine gelebilir. Bunu, kodunuzda erişilen global bir varlıkla karşılaştırın.

Bunlar şu anda düşünebildiğim tek şey, ama daha fazlası olduğuna eminim. Basitçe söylemek gerekirse, bunlar iki farklı şeydir ve farklı amaçlar için kullanılmaları gerekir .


0

Elbette globals her zaman uygunsuz değildir. Varlar çünkü meşru bir kullanımları var. Küresellerle olan temel sorun ve bunlardan kaçınmak için uyarının birincil kaynağı, bir global kullanan kodun o ve yalnızca bir global olanağa bağlı olmasıdır.

Örneğin, sunucu adını saklayan bir HTTP sunucusu düşünün.

Sunucu adını genel olarak saklarsanız, işlem aynı anda iki farklı sunucu adı için aynı anda mantık çalıştıramaz. Belki de özgün tasarım hiçbir zaman bir kerede birden fazla sunucu örneği çalıştırmayı düşünmemişti, ancak daha sonra bunu yapmak istediğinize karar verirseniz, sunucu adı global ise, basitçe yapamazsınız.

Buna karşılık, eğer sunucu ismi bir veritabanında ise, problem yoktur. HTTP sunucusunun her bir örneği için bu veritabanının bir örneğini oluşturabilirsiniz. Sunucunun her bir örneği kendi veritabanı örneğine sahip olduğundan, kendi sunucu adına sahip olabilir.

Dolayısıyla, küresellere yapılan ana itiraz, küresel olana erişen tüm kodlar için yalnızca bir değer olabilir, veritabanı girişleri için geçerli değildir. Aynı kod, belirli bir giriş için farklı değerleri olan farklı veritabanı örneklerine kolayca erişebilir.


0

Bunun ilginç bir soru olduğunu düşünüyorum ama cevaplaması biraz zor çünkü “küresel devlet” terimi altında iki ana başlık var. Birincisi, 'küresel eşleşme' kavramı. Bunun kanıtı, küresel devlet için verilen alternatifin bağımlılık enjeksiyonu olduğudur. Mesele şu ki, DI küresel devleti mutlaka ortadan kaldırmaz. Diğer bir deyişle, küresel devlete bağımlılıklar enjekte etmek kesinlikle mümkün ve yaygındır. DI'nin yaptığı şey, global değişkenlerle birlikte gelen kaplini ve yaygın olarak kullanılan Singleton modelini kaldırmaktır. Biraz daha az belirgin bir tasarımın yanı sıra, bu tür bir bağlamanın ortadan kaldırılmasının çok az bir dezavantajı vardır ve kaplinin ortadan kaldırılmasının yararları, bu küreler üzerindeki bağımlılıkların sayısı ile birlikte üssel olarak artar.

Bunun diğer yönü paylaşılan durumdur. Genel olarak paylaşılan devlet ile genel olarak paylaşılan devlet arasında gerçekten net bir ayrım olup olmadığından emin değilim, ancak maliyetler ve faydalar çok daha farklıdır. Basitçe söylemek gerekirse, paylaşılan durumun faydalı olmasını gerektiren sayısız yazılım sistemi vardır. Örneğin, Bitcoin, devleti küresel olarak (kelimenin tam anlamıyla) merkezi olmayan bir şekilde paylaşmanın çok zekice bir yoludur. Değişken durumu, büyük tıkanıklıklar yaratmadan düzgün bir şekilde paylaşmak zordur ancak faydalıdır. Dolayısıyla, gerçekten yapmanız gerekmiyorsa, paylaşılabilir değişken durumu en aza indirerek başvurunuzu basitleştirebilirsiniz.

Dolayısıyla, veritabanlarının küresellerden nasıl farklı olduğu sorusu da bu iki yönden ayrılmıştır. Kavrama tanıtıyorlar mı? Evet, yapabilirler ancak uygulamanın nasıl tasarlandığına ve veritabanının nasıl tasarlandığına bağlıdır. Tasarımların detayları olmadan veritabanlarının global eşleşmeyi sağlayıp sağlamadığına dair tek bir cevabı olan çok fazla faktör var. Devlet paylaşımını sağlayıp sağlamadıklarına gelince, bu bir veritabanının ana noktası. Soru onların iyi yapıp yapmadıkları. Yine, bunun alternatifler ve diğer birçok takas gibi birçok bilgi olmadan cevap veremeyecek kadar karmaşık olduğunu düşünüyorum.


0

Biraz farklı düşünürdüm: "global değişken" gibi davranış, veritabanı yöneticileri (DBA'lar) tarafından ödenen bir fiyat çünkü işlerini yapmak için gerekli bir kötülük.

Küresel değişkenlerle ilgili sorun, diğerlerinin de belirttiği gibi, keyfi bir sorun değildir. Sorun, kullanımlarının programınızın davranışını daha az ve daha az tahmin edilebilir hale getirmesidir; çünkü değişkeni kimin ve nasıl kullandığını belirlemek zorlaşır. Bu, modern yazılım için büyük bir sorundur, çünkü modern yazılımdan genellikle birçok esnek şey yapması istenir. Bir çalışma sırasında milyarlarca hatta trilyonlarca karmaşık durum manipülasyonu yapabilir. Bu yazılımın o milyarlarca veya trilyonlarca operasyonda ne yapacağına dair doğru ifadeleri kanıtlama yeteneği son derece değerlidir.

Modern yazılım söz konusu olduğunda, tüm dillerimiz kapsülleme gibi, bu konuda yardımcı olacak araçlar sağlar. Bunu kullanmama seçimine gerek yok; bu da “küreseller kötülük” zihniyetine yol açıyor. Yazılım geliştirme alanının birçok bölgesinde, bunları kullanan tek kişi, nasıl daha iyi kodlanacağını bilmeyen insanlardır. Bu, yalnızca doğrudan sorun değil aynı zamanda geliştiricinin ne yaptıklarını bilmediğini dolaylı olarak öneriyorlar. Diğer bölgelerde, küresellerin tamamen normal olduğunu göreceksiniz (özellikle gömülü yazılım, özellikle de ISR'lerle iyi çalıştığı için küreselleri sever). Bununla birlikte, oradaki pek çok yazılım geliştiricinin ortasında, azınlık sesidir, bu yüzden duyduğunuz tek ses “küresel şeytanlardır”.

Veri tabanı gelişimi bu azınlık ses durumlarından biridir. DBA işi yapmak için gerekli araçlar çok güçlü ve onların teori olduğu değil kapsülleme köklü. Performanslarının her bir veritabanını veritabanlarından çıkarmak için, dünyaya benzer her şeye tamamen serbest erişime ihtiyaçları var. Canavar 100 milyon satırlık (veya daha fazla!) Veritabanlarından birini kullanın ve DB motorlarının neden herhangi bir zımba tutmasına izin vermediklerini takdir edersiniz.

Bunun için bir bedel öderler, sevgili bir bedel. DBA'lar, detaylara gösterilen özenle neredeyse patolojik olmak zorunda kalıyorlar, çünkü aletleri onları korumuyor. Koruma şeklindeki en iyisi ACID veya belki de yabancı anahtarlardır. Patolojik olmayanlar kendilerini tamamen kullanışsız, hatta yozlaşmış bir tablo karışıklığıyla bulurlar .

100k line yazılım paketlerine sahip olmak nadir değildir. Teoride, yazılımdaki herhangi bir satır herhangi bir zamanda herhangi bir global etkileyebilir. DBA’larda veritabanını değiştirebilecek 100k farklı sorgu bulamazsınız. Bu, sizi kendinizden korumak için gereken detaylara dikkat ederek sürdürmek için makul olmazdı. Eğer bir DBA böyle büyük bir şeye sahipse, kasıtlı olarak "global benzeri" sorunları göz ardı ederek, erişimcileri kullanarak veritabanlarını kapsamaya alırlar ve daha sonra bu "daha güvenli" mekanizma boyunca ellerinden geldiğince çalışırlar. Böylece, itme kıpırdadığında, veritabanı insanları bile küresellerden kaçınır. Onlar sadece tehlike bir sürü gelir ve olan alternatifler vardır sadece gibi güçlü ama tehlikeli değildir.

Diğer şeyler eşitse, etrafta camları kırmayı veya güzelce süpürülmüş kaldırımları tercih etmeyi mi tercih edersiniz? Evet, kırık camın üzerinde yürüyebilirsiniz. Evet, bazı insanlar bile bunu yaparak geçimini sağlar. Ama yine de, kaldırımı süpürmelerine ve devam etmelerine izin verin!


0

Bence öncül yanlış. Veritabanının (çok büyük) bir içerik nesnesi yerine "küresel devlet" olması gerekmiyor. Kodunuzun global değişkenler veya sabit bir global veritabanı bağlantı parametreleri aracılığıyla kullandığı belirli bir veritabanına bağlanıyorsanız, başka hiçbir genel durumdan farklı değildir ve daha az kötü değildir. Öte yandan, veritabanı bağlantısı için bir bağlam nesnesini doğru bir şekilde geçirirseniz, genel durum değil, büyük (ve yaygın olarak kullanılan) bağlamsal durumdur.

Farkı ölçmek kolaydır: Program mantığınızın iki örneğini, her biri kendi veritabanını kullanarak, kodda invazif değişiklikler yapmadan tek bir programda / işlemde çalıştırabilir misiniz? Öyleyse, veritabanınız gerçekten "global devlet" değildir.


-2

Globals şeytan değildir; Onlar sadece bir araçtır. Küresel programların YANLIŞI, herhangi bir diğer programlama özelliğinin yanlış kullanımı gibi sorunludur.

Genel tavsiyem, küresellerin yalnızca diğer çözümlerin daha az optimal olduğu iyi anlaşılmış ve düşünülmüş durumlarda kullanılması gerektiğidir. En önemlisi, bu küresel değerin nerede değiştirilebileceğini iyi bir şekilde belgelemiş olduğunuzdan ve çok okuyuculu çalışıyorsanız, global ve ortak bağımlı kürelerin işlem yapabildikleri bir şekilde erişmelerini sağladığınızdan emin olmak istiyorsunuz.


Seçmenlerden bazıları sizin beğenilerinizi açıklamayı düşünür mü? Bir açıklama yapmadan aşağı oy vermek kaba görünüyor.
Byron Jones

-2

Salt Okunur kalıbı ve verilerinizin yazdırırken güncel olmadığını varsayalım. Sıra, çakışmaları başka bir yolla yazar veya işler. Hoş geldiniz cehennem şeytan, küresel db kullanıyorsunuz.

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.