Neden tüm Active Record nefret ediyor? [kapalı]


103

OOP hakkında daha fazla şey öğrendikçe ve çeşitli tasarım modellerini uygulamaya başladıkça, insanların Active Record'da nefret ettikleri vakalara geri dönmeye devam ediyorum .

Çoğu zaman insanlar bunun iyi ölçeklenmediğini söyler (en iyi örnek olarak Twitter'ı örnek alırlar) - ama aslında kimse neden iyi ölçeklenmediğini açıklamaz ; ve / veya AR'nin artılarını eksiler olmadan nasıl başarabiliriz (benzer ama farklı bir model aracılığıyla?)

Umarım bu, tasarım kalıpları hakkında kutsal bir savaşa dönüşmez - tüm bilmek istediğim **** özellikle **** Aktif Kayıt'ta neyin yanlış olduğu.

İyi ölçeklenmiyorsa, neden olmasın?

Başka ne gibi sorunları var?


9
Sanırım genel olarak tasarım kalıplarına karşı pek çok nefret ve hoşnutsuzluk yanlış kullanımla bağlantılı. İnsanlar bunları aşırı kullanma ve yanlış bağlamda kullanma eğilimindedir ve orijinal çözümden daha karmaşık bir çözümle
sonuçlanır

1
Ruby'nin Aktif Kayıt uygulaması daha çok bir ORM gibidir.
Jimmy T.

1
Takdir, daha fazla tanınma, daha akıllı ve keskin-kanayan-keskin görünmek için sosyal bir fenomen var, insanlar mevcut herhangi bir standart, model, yaygın olarak benimsenen teknolojilerin herhangi bir olumsuz yutturmacasını mekanik olarak tekrarlama eğiliminde olup, bir sonraki dalgaya devrim niteliğinde ilerleme.
Andre Figueiredo

Yanıtlar:


90

Orada ActiveRecord Tasarım Desen ve ActiveRecord Raylar orm Kütüphane ve .NET için vuruş-off ve diğer dillere bir ton da var.

Bunların hepsi farklı şeyler. Çoğunlukla bu tasarım modelini takip ederler, ancak onu birçok farklı şekilde genişletirler ve değiştirirler, bu nedenle herhangi biri "ActiveRecord Sucks" demeden önce, "hangi ActiveRecord, yığınlar var?" Diyerek nitelendirilmesi gerekir.

Yalnızca Rails'in ActiveRecord'una aşinayım, kullanım bağlamında ortaya çıkan tüm şikayetleri ele almaya çalışacağım.

@BlaM

Aktif Kayıtlarda gördüğüm sorun, her zaman sadece bir tablo olması

Kod:

class Person
    belongs_to :company
end
people = Person.find(:all, :include => :company )

Bu, SQL ile birlikte SQL oluşturur LEFT JOIN companies on companies.id = person.company_idve ilişkili Şirket nesnelerini otomatik olarak oluşturur, böylece bunu yapabilirsiniz people.first.companyve veriler zaten mevcut olduğu için veritabanına basması gerekmez.

@ pix0r

Active Record ile ilgili temel sorun, nesneleri doldurmak ve veritabanı kayıtlarını değiştirmek için veritabanı sorgularının otomatik olarak oluşturulması ve yürütülmesidir.

Kod:

person = Person.find_by_sql("giant complicated sql query")

Çirkin olduğu için bu cesaret kırılmıştır, ancak sadece sade ve basitçe ham SQL yazmanız gereken durumlarda, bu kolayca yapılabilir.

@Tim Sullivan

... ve modelin birkaç örneğini seçerseniz, temelde "... arasından * seçim yapın"

Kod:

people = Person.find(:all, :select=>'name, id')

Bu, yalnızca veritabanından adı ve kimlik sütunlarını seçecektir, eşlenen nesnelerdeki diğer tüm 'öznitelikler', bu nesneyi manuel olarak yeniden yüklemediğiniz sürece sıfır olacaktır.


Güçlü! Bu belirli özelliği bilmiyordum. Cephaneliğime koymam gereken bir başka AR yanlısı argüman.
Tim Sullivan

Birleştirme, Aktif Kayıt modelinin ötesine geçer.
Jimmy T.

"Person.find_by_sql" Active Record kalıbı değildir. Neredeyse "Aktif kayıt" beni başarısızlığa uğrattı, bu yüzden manuel olarak yama yapmam gerekiyor.
magallanes

52

ActiveRecord'un Modelin nispeten düz olduğu hızlı CRUD tabanlı uygulamalar için iyi olduğunu her zaman buldum (pek çok sınıf hiyerarşisinde olduğu gibi). Ancak, karmaşık OO hiyerarşileri olan uygulamalar için DataMapper muhtemelen daha iyi bir çözümdür. ActiveRecord, tablolarınız ve veri nesneleriniz arasında 1: 1 oranını varsaysa da, bu tür bir ilişki daha karmaşık etki alanlarıyla zorlaşır. Martin Fowler , kalıplarla ilgili kitabında, Modelinizin oldukça karmaşık olduğu durumlarda ActiveRecord'un bozulma eğiliminde olduğuna dikkat çekiyor ve alternatif olarak bir DataMapper'ı öneriyor .

Bunun pratikte doğru olduğunu buldum. Etki alanınızda çok fazla mirasın olduğu durumlarda, devralmayı RDBMS'nizle eşlemek, ilişkileri veya kompozisyonu eşlemekten daha zordur.

Bunu yapma şeklim, bu DataMapper (veya "hizmet katmanı") sınıfları aracılığıyla denetleyicileriniz tarafından erişilen "etki alanı" nesnelerine sahip olmaktır. Bunlar doğrudan veritabanını yansıtmaz, ancak bazı gerçek dünyadaki nesneler için OO temsiliniz olarak işlev görür. Etki alanınızda bir User sınıfınız olduğunu ve bu User nesnesini aldığınızda zaten yüklenmiş olan başka nesneler için referanslara veya koleksiyonlara sahip olmanız gerektiğini varsayalım. Veriler birçok farklı tablodan geliyor olabilir ve bir ActiveRecord modeli bunu gerçekten zorlaştırabilir.

Kullanıcı nesnesini doğrudan yüklemek ve bir ActiveRecord tarzı API kullanarak verilere erişmek yerine, denetleyici kodunuz örneğin UserMapper.getUser () yönteminin API'sini çağırarak bir Kullanıcı nesnesi alır. İlişkili nesnelerin ilgili tablolarından yüklenmesinden ve tamamlanmış Kullanıcı "etki alanı" nesnesinin arayana geri döndürülmesinden sorumlu olan bu eşleyicidir.

Esasen, kodu daha yönetilebilir hale getirmek için başka bir soyutlama katmanı ekliyorsunuz. DataMapper sınıflarınızın ham özel SQL veya bir veri soyutlama katmanı API'si çağrıları içermesi, hatta bir ActiveRecord modeline kendilerinin erişip erişmemesi, güzel, doldurulmuş bir Kullanıcı nesnesi alan denetleyici kodu için gerçekten önemli değildir.

Her neyse, ben böyle yaparım.


5
Görünüşe göre ActiveRecord'a aşina değilsin. "ActiveRecord, tablolarınız arasında 1: 1 oranını varsayar". Kesinlikle doğru değil. ActiveRecord her türden harika ilişkisel sihre sahiptir. Bkz api.rubyonrails.org/classes/ActiveRecord/Associations/…
tybro0103

16
@ JoãoBragança - belki alaycı bir yorumdan ziyade, bir kişinin verileri parçalandığında ortaya çıkan zorlukları gerçekten açıklayabilirsiniz - böylece geri kalanımız bir şeyler öğrenebilir :)
Taryn East

11

İnsanların ActiveRecord'da neden "nefret ettikleri" ile "yanlış" olan arasında muhtemelen çok farklı nedenler olduğunu düşünüyorum.

Nefret konusunda, Rails ile ilgili her şeye karşı çok fazla zehir vardır. Bunda neyin yanlış olduğuna gelince, muhtemelen tüm teknolojiler gibi ve bunun iyi bir seçim olduğu durumlar ve daha iyi seçimlerin olduğu durumlar var. Tecrübelerime göre, Rails ActiveRecord'un özelliklerinin çoğundan yararlanamadığınız durum, veritabanının kötü yapılandırıldığı yerdir. Verilere erişmek için çok sayıda saklı yordamın gerekli olduğu ve ilk normal biçimi ihlal eden şeylerle birincil anahtarlar olmadan verilere erişiyorsanız, daha çok bir SQL sarmalayıcısı olan bir şey kullanmanız daha iyi olur. Veritabanınız nispeten iyi yapılandırılmışsa, ActiveRecord bundan yararlanmanıza izin verir.

ActiveRecord'da işlerin zor olduğunu söyleyen yorumcuları yanıtlama temasına bir kod parçacığı yanıtıyla eklemek için

@Sam McAfee Diyelim ki, etki alanınızda bir Kullanıcı sınıfı var ve bu Kullanıcı nesnesini aldığınızda zaten yüklenmiş olan başka nesneler için referanslar veya koleksiyonlar olması gerekiyor. Veriler birçok farklı tablodan geliyor olabilir ve bir ActiveRecord modeli bunu gerçekten zorlaştırabilir.

user = User.find(id, :include => ["posts", "comments"])
first_post = user.posts.first
first_comment = user.comments.first

Dahil etme seçeneğini kullanarak, ActiveRecord varsayılan geç yükleme davranışını geçersiz kılmanıza izin verir.


8

Uzun ve geç cevabım, tam bile değil, ama iyi bir açıklama NEDEN bu kalıptan, fikirlerden ve hatta bazı duygulardan nefret ediyorum:

1) kısa versiyon: Active Record , veritabanı ile uygulama kodu arasında " güçlü bir bağlantı " içeren " ince bir katman " oluşturur . Bu mantıksal, hiçbir sorun, hiçbir sorun çözmez. IMHO , programcı için bazı sözdizimsel şeker haricinde HERHANGİ BİR DEĞER sağlamaz (daha sonra ilişkisel bir veritabanında bulunan bazı verilere erişmek için bir "nesne sözdizimi" kullanabilir). Programcılar için biraz rahatlık yaratma çabası (IMHO ...), düşük seviyeli veritabanı erişim araçlarına, örneğin basit, kolay, sade ve benzer yöntemlerin bazı varyasyonlarına (tabii ki, kavramlar ve zarafet ) daha iyi yatırılmalıdır. kullanılan dil).hash_map get_record( string id_value, string table_name, string id_column_name="id" )

2) uzun versiyon: Nesnelerin "kavramsal kontrolüne" sahip olduğum herhangi bir veritabanı odaklı projede AR'den kaçındım ve iyiydi. Genelde katmanlı bir mimari oluşturuyorum (er ya da geç yazılımınızı katmanlara ayırırsınız, en azından orta ve büyük ölçekli projelerde):

A1) veritabanının kendisi, tablolar, ilişkiler, hatta DBMS izin veriyorsa bazı mantık (MySQL de artık büyümüştür)

A2) çoğu zaman, bir veri deposundan daha fazlası vardır: dosya sistemi (veritabanındaki bloblar her zaman iyi bir karar değildir ...), eski sistemler (bunlara "nasıl" erişileceğini hayal edin, birçok çeşit mümkündür .. ama bu konu değil ...)

B) veri tabanı erişim katmanı (bu seviyede, araç yöntemleri, veri tabanındaki verilere kolayca erişme yardımcıları çok açıktır, ancak AR burada bazı sözdizimsel şeker dışında herhangi bir değer sağlamaz)

C) uygulama nesneleri katmanı: "uygulama nesneleri" bazen veritabanındaki bir tablonun basit satırlarıdır, ancak çoğu zaman bunlar zaten bileşik nesnelerdir ve daha yüksek bir mantık eklenmiştir, bu nedenle bu düzeyde AR nesnelerine zaman yatırmak kesinlikle faydasızdır , değerli kodlayıcıların zamanının boşa harcanması, çünkü bu nesnelerin "gerçek değeri", "daha yüksek mantığı" her durumda AR nesnelerinin üzerine uygulanmalıdır - AR ile ve olmadan! Ve örneğin, neden "Günlük giriş nesneleri" soyutlamasına sahip olmak istersiniz? Uygulama mantık kodu bunları yazar, ancak bu onları güncelleme veya silme özelliğine sahip olmalı mı? kulağa aptalca geliyor ve App::Log("I am a log message")bazı büyüklüklerin kullanımı daha kolayle=new LogEntry(); le.time=now(); le.text="I am a log message"; le.Insert();. Ve örneğin: uygulamanızdaki günlük görünümünde bir "Günlük giriş nesnesi" kullanmak 100, 1000 veya hatta 10000 günlük satırı için çalışacaktır, ancak er ya da geç optimize etmeniz gerekecek - ve bahse girerim çoğu durumda, sadece Bu küçük ifadeyi çok sayıda kod sarma ve gizleme ile katı sabit AR fikir çerçevelerine sarmak yerine, uygulama mantığınızda (bu, AR fikrini tamamen bozan) küçük güzel SQL SELECT ifadesini kullanın. AR kodu yazmak ve / veya oluşturmakla harcadığınız zaman, günlük giriş listelerini okumak için çok daha akıllı bir arayüze yatırılabilirdi (birçok yönden, sınır gökyüzüdür). Kodlayıcılar , amaçlanan uygulamaya uyan uygulama mantığını gerçekleştirmek için yeni soyutlamalar icat etmeye cesaret etmeli ve aptalca kalıpları yeniden uygulamamalıdır., bu ilk bakışta iyi geliyor!

D) uygulama mantığı - etkileşimli nesnelerin mantığını ve uygulama mantığı nesnelerini oluşturma, silme ve listeleme (!) Mantığını uygular (HAYIR, bu görevler nadiren uygulama mantığı nesnelerinin kendisine sabitlenmelidir: masanızdaki kağıtlar ofisinizdeki diğer tüm sayfaların adları ve yerleri? nesneleri listelemek için "statik" yöntemleri unutun, bu saçma, insan düşünme biçimini [tümü değil-AR çerçevesi benzeri bir yapıya uydurmak için yaratılmış kötü bir uzlaşma -] AR düşünme)

E) kullanıcı arayüzü - pekala, aşağıdaki satırlarda yazacağım şey çok, çok, çok öznel, ancak benim deneyimime göre, AR üzerine inşa edilen projeler genellikle bir uygulamanın UI bölümünü ihmal etti - zaman, belirsiz soyutlamalar oluşturmak için boşa harcandı . Sonunda, bu tür uygulamalar kodlayıcıların çok zamanını boşa harcadı ve kodlayıcıların içeride ve dışarıda teknolojiye eğilimli uygulamaları gibi hissettirdi. Kodlayıcılar kendilerini iyi hissediyorlar (kağıt üzerindeki konsepte göre sonunda sıkı çalışma, her şey bitmiş ve doğru ...) ve müşteriler "bunun böyle olması gerektiğini öğrenmeleri gerekiyor", çünkü bu "profesyonel" .. tamam pardon, konuyu ele alıyorum ;-)

Evet, kuşkusuz, bunların hepsi öznel, ama benim deneyimim (Ruby on Rails hariç, farklı olabilir ve bu yaklaşımla sıfır pratik deneyimim var).

Ücretli projelerde, daha yüksek seviye uygulama mantığı için yapı taşı olarak bazı "aktif kayıt" nesneleri oluşturmaya başlama talebini sık sık duydum. Tecrübelerime göre, bu bariz bir şekilde sıklıklaMüşterinin (çoğu durumda bir yazılım geliştirme şirketi) iyi bir konsepte, büyük bir görüşe, ürünün nihayetinde ne olması gerektiğine dair genel bir bakışa sahip olmaması için bir tür mazeretti. Bu müşteriler katı çerçeveler içinde düşünüyorlar ("on yıl önceki projede iyi çalıştı .."), varlıkları detaylandırabilirler, varlık ilişkilerini tanımlayabilirler, veri ilişkilerini bozabilirler ve temel uygulama mantığını tanımlayabilirler, ancak sonra dururlar ve bunu size teslim edin ve ihtiyacınız olan her şeyin bu olduğunu düşünün ... genellikle tam bir uygulama mantığı, kullanıcı arayüzü, kullanılabilirlik vb. kavramlarından yoksundurlar ... büyük görüşten yoksundurlar ve ayrıntılar ve AR yöntemini takip etmenizi istiyorlar, çünkü .. peki, neden o projede yıllar önce çalıştı, insanları meşgul ve sessiz tutuyor? Bilmiyorum. Ama "ayrıntılar" erkekleri oğlanlardan ayırın, yoksa .. orijinal reklam sloganı nasıldı? ;-)

Yıllar sonra (on yıllık aktif geliştirme deneyimi), bir müşteri "aktif kayıt modelinden" bahsettiğinde, alarm zilim çalar. Onları bu temel kavram aşamasına geri getirmeyi, iki kez düşünmelerini sağlamayı, kavramsal zayıflıklarını göstermeye çalışmayı ya da farkında değillerse onlardan kaçınmayı öğrendim (sonunda, bilirsiniz, henüz bilmeyen bir müşteri) ne istediğini biliyor, belki bildiğini düşünüyor ama bilmiyor ya da konsept çalışmasını bana bedelsiz olarak dışsallaştırmaya çalışıyor, bana çok değerli saatlere, günlere, haftalara ve aylara mal oluyor, hayat çok kısa ...).

Son olarak: BU TÜM neden bu saçma "aktif kayıt kalıbı" ndan nefret ediyorum ve bunu yapıyorum ve mümkün olduğunda ondan kaçınacağım.

DÜZENLEME : Buna Modelsiz bile diyebilirim. Herhangi bir sorunu çözmez (kalıplar sözdizimsel şeker yaratma amacı taşımaz). Bu pek çok sorun yaratır: tüm sorunların kökü (burada birçok cevapları belirtilen ..), yani sadece gizler son derece sınırlı desenler tanım olarak bir arayüz arkasında iyi iyi gelişmiş eski ve güçlü SQL.

Bu kalıp esnekliği sözdizimsel şekerle değiştirir!

Bir düşünün, AR sizin için hangi sorunu çözüyor?


1
Bir veri kaynağı mimari modelidir. Belki de Fowler's Patterns of Enterprise Application Architecture'ı okumalısınız? Modeli / ORM'yi gerçekten kullanmadan ve işleri ne kadar basitleştirdiğini bulmadan önce sizinkine benzer düşüncelerim vardı.
MattMcKnight

1
Hislerini paylaşıyorum Bir çerçeve bileşik anahtarları desteklemediğinde yanlış bir şey kokusu alıyorum .... SQLAlchemy'den önce her türlü ORM'den kaçındım ve genellikle bunu daha düşük bir seviyede, bir SQL oluşturucu olarak kullanıyoruz. Veri Eşleştiricisi'ni uygular ve çok esnektir.
Marco Mariani

1
İki günden beri "son teknoloji ürünü" ORM kullanan bir projede yer alıyorum, belki uygulamalar şimdi olgunlaştı (birkaç yıl önce çalıştığımla karşılaştırıldığında). Belki
fikrim

2
Proje bitti ve ne var biliyor musun? ORM hala berbat, bir grup "nesne yönelimli kod" ile ilişkisel bir şekilde kolayca ifade edilebilen haritalama problemleriyle çok fazla zaman harcadım. Tabii ki ORM, sorguları bir çeşit OOP + SQL-Mix şeklinde - tabii ki OOP benzeri bir sözdiziminde - ifade etmenin yollarını sağladı, ancak bu sadece bir SQL sorgusu yazmaktan daha fazla zaman aldı. Soyutlama, kullanıcıların OOP sözdiziminde SQL yazmasına izin vermek için OOP'nin üstüne "OOPSQLExperiment" sızdırıldı, şimdiye kadarki en kötü fikirdi. Hayır, bir daha asla.
Frunsi

1
Yıllarca her şey için ham SQL yazdım. Rails AR bazen beni hayal kırıklığına uğratıyor ve pasif sorgulama için neredeyse sizinle aynı fikirdeyim ama çözdüğü şey bu: 1) Doğrulamayı geçemeyen verileri kaydetmeyi uygun şekilde zorlaştırıyor. 2) Son kalıcıdan bu yana hafızada nelerin değiştiğini izleme. 3) before_saveKayıt içinde tutarlılığı korumak için anlamlı geri aramalar yazmak için 2. maddeyi kullanmak 4) after_commitharici hizmet tetikleyicileri için kancalar. 5) DDL değişikliklerini değişiklik kümelerine (geçişlere) düzenlemek için iyi bir DSL. (Orada hala acı var, ancak 1 geliştiriciden fazla olduğunda hiçbir modelin olmaması daha kötü.)
Adamantish

6

Bazı mesajlar kafamı karıştırıyor. Bazı cevaplar "ORM" vs "SQL" veya bunun gibi bir şey olacak.

Gerçek şu ki, AR, veritabanı erişim kodunu yazmak için etki alanı nesnelerinizden yararlandığınız bir basitleştirme programlama modelidir.

Bu nesneler genellikle iş özniteliklerine (çekirdeğin özellikleri) ve bazı davranışlara (genellikle bu özellikler üzerinde çalışan yöntemler) sahiptir.

AR, veritabanıyla ilgili görevlere "bu etki alanı nesnelerine bazı yöntemler ekle" diyor.

Ve görüşümden ve tecrübelerime göre, kalıbı beğenmediğimi söylemeliyim.

İlk bakışta kulağa oldukça iyi gelebilir. Spring Roo gibi bazı modern Java araçları bu kalıbı kullanır.

Benim için asıl sorun sadece OOP endişesi. AR kalıbı, sizi nesnenizden alt yapı nesnelerine bir bağımlılık eklemeye zorlar. Bu alt yapı nesneleri, etki alanı nesnesinin AR tarafından önerilen yöntemlerle veritabanını sorgulamasına izin verir.

Her zaman iki katmanın bir projenin başarısı için anahtar olduğunu söylemişimdir. Hizmet katmanı (iş mantığının bulunduğu veya bir tür uzak teknoloji yoluyla, örneğin Web Hizmetleri olarak dışa aktarılabildiği yer) ve etki alanı katmanı. Bence, AR modelini çözmek için etki alanı katmanı nesnelerine bazı bağımlılıklar (gerçekten gerekli olmayan) eklersek, etki alanı nesnelerimizi diğer katmanlarla veya (nadir) harici uygulamalarla paylaşmak daha zor olacaktır.

AR'nin Spring Roo uygulaması ilginçtir, çünkü nesnenin kendisine değil, bazı AspectJ dosyalarında güvenir. Ancak daha sonra Roo ile çalışmak istemezseniz ve projeyi yeniden düzenlemeniz gerekirse, AR yöntemleri doğrudan etki alanı nesnelerinize uygulanacaktır.

Başka bir bakış açısı. Nesnelerimizi depolamak için İlişkisel Veritabanı kullanmadığımızı düşünün. Uygulamanın etki alanı nesnelerimizi örneğin bir NoSQL Veritabanında veya sadece XML dosyalarında depoladığını düşünün. Etki alanı nesnelerimizde bu görevleri yapan yöntemleri uygular mıydık? Ben öyle düşünmüyorum (örneğin, XM durumunda, etki alanı nesnelerimize XML ile ilgili bağımlılıklar eklerdik ... Gerçekten üzücü düşünüyorum). Öyleyse neden Ar modelinin dediği gibi ilişkisel DB yöntemlerini etki alanı nesnelerinde uygulamamız gerekiyor?

Özetlemek gerekirse, AR modeli küçük ve basit uygulamalar için daha basit ve iyi gelebilir. Ancak karmaşık ve büyük uygulamalarımız olduğunda, klasik katmanlı mimarinin daha iyi bir yaklaşım olduğunu düşünüyorum.


SO'ya hoş geldiniz. Yorumunuz için minnettarız, ancak bu soru NullUserException tarafından yapıcı olmadığı için 17 Aralık 2011'de 1:17
Tony Rad

3

Soru, Active Record tasarım modeliyle ilgili. Orm Aracı değil.

Orijinal soru raylarla etiketlenmiştir ve Ruby on Rails'de yerleşik olan Twitter'ı ifade eder. Rails içindeki ActiveRecord çerçevesi, Fowler'in Aktif Kayıt tasarım modelinin bir uygulamasıdır.


2

Active Record ile ilgili şikayetlerle ilgili gördüğüm en önemli şey, bir masa etrafında bir model oluşturduğunuzda ve modelin birkaç örneğini seçtiğinizde, temelde "... 'dan * seç" yapıyorsunuz. Bu, bir kaydı düzenlemek veya bir kaydı görüntülemek için uygundur, ancak, örneğin, veritabanınızdaki tüm kişiler için şehirlerin bir listesini görüntülemek istiyorsanız, "Şehirden ..." seçimini yapabilir ve yalnızca şehirleri alabilirsiniz. . Bunu Active Record ile yapmak, tüm sütunları seçmenizi, ancak yalnızca Şehir'i kullanmanızı gerektirir.

Tabii ki, çeşitli uygulamalar bunu farklı şekilde ele alacaktır. Yine de bu bir sorun.

Şimdi, yapmaya çalıştığınız belirli şey için yeni bir model oluşturarak bunun üstesinden gelebilirsiniz, ancak bazı insanlar bunun faydadan çok çaba olduğunu iddia edebilir.

Ben, Aktif Kaydı kazıyorum. :-)

HTH


2
"Bunu Active Record ile yapmak, tüm sütunları seçmenizi, ancak yalnızca Şehir'i kullanmanızı gerektirir." Aslında bir seçme cümlesi belirlemek son derece kolaydır.
MattMcKnight

1

SubSonic'in tek sütunlu şeyi yapma şeklini seviyorum.
Ya

DataBaseTable.GetList(DataBaseTable.Columns.ColumnYouWant)

veya:

Query q = DataBaseTable.CreateQuery()
               .WHERE(DataBaseTable.Columns.ColumnToFilterOn,value);
q.SelectList = DataBaseTable.Columns.ColumnYouWant;
q.Load();

Ancak Linq, tembel yükleme söz konusu olduğunda hala kraldır.


1

@BlaM: Bazen bir katılımın sonucu için aktif bir kayıt uyguladım. Her zaman Tablo <--> Aktif Kayıt ilişkisi olmak zorunda değildir. Neden "Bir Katılma ifadesinin sonucu" <--> Aktif Kayıt değil?


1

Bir tasarım modeli olarak Aktif Kayıt'tan bahsedeceğim, ROR'u görmedim.

Bazı geliştiriciler, temiz ve düzgün kod yazma konusunda akıllı kitaplar okudukları için Active Record'dan nefret ederler ve bu kitaplar, aktif kaydın tek yanıt verme ilkesini ihlal ettiğini, etki alanı nesnesinin sürekli cahil olması gerektiği şeklindeki DDD kuralını ihlal ettiğini ve bu tür kitaplardan diğer birçok kuralı ihlal ettiğini belirtir. .

İkinci şey, Active Record'daki etki alanı nesneleri, veritabanı ile 1'e 1 olma eğilimindedir; bu, bazı tür sistemlerde bir sınırlama olarak kabul edilebilir (çoğunlukla n katmanlı).

Bu sadece soyut şeyler, bu modelin gerçek uygulamasını raylarda yakut görmedim.


0

Aktif Kayıtlarda gördüğüm sorun, her zaman sadece bir tablo olmasıdır. Sorun değil, gerçekten tek bir tabloyla çalıştığınız sürece sorun değil, ancak verilerle çalıştığınızda çoğu durumda bir yerde bir tür katılımınız olacak.

Evet, birleştirme genellikle performans söz konusu olduğunda hiç katılmamaktan daha kötüdür , ancak birleştirme genellikle önce A tablosunun tamamını okuyarak ve sonra elde edilen bilgileri B tablosunu okuyup filtrelemek için kullanarak "sahte" birleştirmeden daha iyidir .


@BlaM: Kesinlikle haklısın. Aktif Kaydı hiç kullanmamış olsam da, diğer cıvatalı ORM sistemlerini (özellikle NHibernate) kullandım ve iki büyük şikayetim var: nesneler yaratmanın aptalca yolları (yani .hbm.xml dosyaları, her biri kendi derlemelerinde derlenir) ve yalnızca nesneleri yüklerken ortaya çıkan performans vuruşu (NHibernate, eşdeğer bir SQL sorgusu neredeyse hiç işlem yapmadığında hiçbir şey yüklemeyen bir sorguyu birkaç saniye boyunca tek çekirdekli bir işlemi hızlandırabilir). Elbette Aktif Kayda özgü değil, ancak ORM sistemlerinin (ve ORM benzeri sistemlerin)
çoğunun öyle

Hbm.xml dosyalarını kullanmanın birçok alternatifi vardır. Örneğin bkz. NHibernate.Mapping.Attributes ve fluent-nhibernate.
Mauricio Scheffer,

Nesne oluşturma performansı hakkında, hiç bu kadar mükemmel problemlerle karşılaşmadım, bir profilciyle kontrol etmek isteyebilirsiniz.
Mauricio Scheffer,

@mausch: Profilciye gerek yok. Oldukça iyi bilinen bir sorun. En son sürüm için geçerli olup olmadığını bilmiyorum (henüz işimde kullanmıyorum). ayende.com/Blog/archive/2007/10/26/…
TheSmurf

4
Bulgulara: joins veya: ekler IE Customer.find (: all,: include =>: contact,: condition => "active = 1") kullanarak SQL birleştirme yapar, her ikisinin de tam bir tablo taraması değil.
Tilendor

0

ActiveRecord ile ilgili sorun, sizin için otomatik olarak oluşturduğu sorguların performans sorunlarına neden olabilmesidir.

Sonunda, sorguyu en başta elle yazmanın daha verimli olup olmayacağını merak etmenize neden olan sorguları optimize etmek için bazı sezgisel olmayan hileler yaparsınız.


0

SQL optimizasyonu ile ilgili diğer tüm yorumlar kesinlikle geçerli olsa da, aktif kayıt modeliyle ilgili ana şikayetim, genellikle empedans uyumsuzluğuna yol açmasıdır . Etki alanımı temiz ve düzgün bir şekilde kapsüllenmiş halde tutmayı seviyorum, bu da aktif kayıt kalıbı genellikle tüm yapma umutlarını yok ediyor.


ActiveRecord , ilişkisel bir şemaya karşı OO tarzında kodlamanıza izin vererek aslında empedans uyuşmazlığı sorununu çözer .
Mauricio Scheffer,

Detaylandırmak ister misin? Genel fikir birliği, ilişkisel bir veritabanından sonra modellenen nesnelerin tanımı gereği nesneye yönelik olmadığıdır (çünkü ilişkisel veritabanları kalıtım ve çok biçimlilik gibi OO kavramları etrafında dönmez).
Kevin Pang

İlişkisel bir şema ile kalıtımı eşlemenin bilinen üç yolu vardır. Ref: castleproject.org/ActiveRecord/documentation/trunk/usersguide/…
Mauricio Scheffer

Bence Castle Active Record OSS projesini tasarım modelini Active Record ile karıştırıyorsunuz. Asıl soru (ve cevabım) tasarım modeline atıfta bulunuyor. Castle Active Record projesi, OO gelişimine yardımcı olacak şeyler içeriyor, ancak modelin kendisi değil.
Kevin Pang 04

Ben sadece referans olarak Castle'dan alıntı yapıyordum. RoR'un ActiveRecord'u yalnızca Tek tablo kalıtımını uygular ( martinfowler.com/eaaCatalog/singleTableInheritance.html ), ancak diğer stratejiler de değerlendirilmektedir ( blog.zerosum.org/2007/2/16/… )
Mauricio Scheffer

0

Çoktan çoğa polimorfik ilişki yapmayı deneyin. Çok kolay değil. Özellikle STI kullanmadığınızda.

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.