Ilişkisel veri tabanlarında nesne yönelimli-benzeri yapılar

11 Cevap php

Dostlarım,

Arka arkaya n-inci zaman için, ben yine aynı eski sorunu vuruyorum. Bu konuda "nasıl ağrısız bir şekilde veritabanı tabloları cepten yapıları harita yok."

Burada bir senaryo: benim sistemde "aktörler" çeşitli var - işçiler, işverenler, rehber. Bu ortak işlevselliği bazı parçalar var; diğer parçaları çok farklıdır. Tüm aktörler ile anlaşma kişiler "iletişim", "notlar" (yöneticiler müşterilere notlar bırakmak gibi), ve birkaç daha vardır. Diğerleri yapmadığı halde her aktör tipi ile ilgilenen diğer kuruluşların türleri ton vardır.

Şu anda, benim veritabanı şeması için tabloları içerir:

Aktörler:

  • işçi
  • işveren
  • temas

Ortaklıklar:

  • iletişim
  • notlar
  • vb

Kurum ve aktörler arasındaki ilişki tablo:

  • işçi-iletişim-assn
  • işveren-iletişim-assn
  • işçi-notlar-assn
  • vs, matkap olsun.

Bu benim için bir "kod kokusu" gibi hissediyor. Bir müşteri (yani "işveren" "temas" terfi) rollerini değiştirir zaman, deli komut bir demet çalıştırmak gerekir. I tamamen cepten odaklı dünyasında faaliyet ise iğrenç ... Öte yandan, bu çok daha kolay olacaktır - Ortak özellikleri ile tüm varlıklar için bir temel sınıf var ve onunla yapılabilir ...

DB dünyada, bu seçeneği teorik olarak mümkün görünüyor, ama çok dağınık ... Ie sesler Ben bu hakkı anlamak eğer, ben yeni bir base_actor tablo olurdu ve birbirlerine aktör bir base_actor_id olurdu, ve daha sonra dernekler base_actor ve kuruluşlar arasında olurdu ... Ama sonra, ben ters-dernek sorguları nasıl yapacağız? Yani "Bana tipi işçinin sadece aktörleri ile tüm iletişimi gösteriyor?"

Herhangi bir tavsiye? Herhangi bir genel "ilişkisel DB eşleme cepten yapılar" Konuyla ilgili düşünceler?

11 Cevap

Burada yaklaşık 10 yıl önce geldi bir çözüm. Bu tasarım kullanır sistemi hala çalışıyor, bu yüzden benim kod çoğu daha uzun hayatta kalmak için yeterince iyi çalıştı. ;) Bugün Scott bahseder ORM paketlerinden birini kullanabilirsiniz, ama sadece doğrudan SQL kullanarak hiçbir büyük sorunlar gerçekten var.

  1. Tablolar arasında birleştirme gibi miras ilişkilerin tüm model. Sisteminizde her tablo, belirli bir sınıfın özelliklerini yapacak.

  2. Tüm nesneler için birincil anahtar olarak sentetik bir nesne kimliği (oid) kullanın. Bir sıra jeneratör veya değiştirmemesi sütun oid değerlerini oluşturmak için gereklidir.

  3. Tüm kalıtsal sınıflar kendi ebeveyn olarak aynı oid türünü kullanmanız gerekir. Kademeli silme ile yabancı anahtar olarak oid tanımlayın. Ana tablo değiştirmemesi oid sütunu alır ve çocuklar düz oid sütunları olsun.

  4. Son sınıfları sorgular tablonun üzerine yapılır. Ya sorgu ya da sadece tembel yük ihtiyacınız nitelikler içine tüm üst sınıf tabloları katılabilirsiniz. Senin mirasın hiyerarşi derin ve birçok sınıfları varsa, bir ORM paketi gerçekten kodunuzu kolaylaştırabilirsiniz. Benim sistem, 3 maksimum miras derinliği ile en az 50 sınıfları vardı.

  5. Çocuk sınıflar (bir üst sınıfa yani üzerinde sorgular) karşısında sorguları tembel yük ya çocuk bir örnek başına bazında niteliklerini edebilir veya temel sınıflar ile katıldı Her çocuğun sınıf için sorguyu tekrarlayabilirsiniz. Bir üst sınıf sorguya dayalı tembel yükleme çocuk niteliklerini nesne türünü bilmek gerekir. Zaten ana sınıflarında yeterli bilgiye sahip olabilir, ama eğer sen değil türü bilgilerini eklemeniz gerekir. ORM paketi yardımcı olabilir Yine, bu nerede olduğunu.

Üye özellikleri olmadan sanal sınıflar tablo yapısında atlanabilir, ama bu sınıfa dayalı sorgulamak mümkün olmayacaktır.

İşte "tipi işçinin sadece aktörleri ile bana tüm iletişimi göstermek" ne benziyor.

select * from comm c, worker w where c.actor=w.oid;

Eğer iletişim alt sınıfları var ve (belki de sistem kısmi inşaat izin vermez) hemen tüm alt sınıf özelliklerini yüklemek isterseniz istekli tüm olası sınıflarına katılmak için, en kolay çözümdür.

select * from comm c, worker w, missive m where c.actor=w.oid and c.oid=m.oid;
select * from comm c, worker w, shoutout s where c.actor=w.oid and c.oid=s.oid;

Son bir şey. Eğer iyi bir veri tabanı ve doğru dizin olduğundan emin olun. Eğer veritabanı bu birleştirmeler optimize edemezsiniz eğer performans ciddi bir sorun olabilir.

.. Bu konuda "nasıl ağrısız bir şekilde veritabanı tabloları cepten yapıları harita yok."

Sen yok.

Nesne yönelimli ve ilişkisel cebir temelde iki farklı paradigmalar vardır. Eğer subjektif olmadan aralarında geçiş olamaz. Bu empedans uyumsuzluğu denir ve The Vietnam of Computer Science lakaplı olmuştur.

Bu deniyor ORM or Object Relational Mapping. İlişkisel tablolar OO yapıları harita yardımcı meram ürünlerin düzinelerce vardır. Ruby on Rails, örneğin, uçurumu yardımcı Aktif Kaydı sunuyor. PHP sizin için Propel ve Doctrine ve Porte ve diğerleri var.

Ne arıyorsun ne Disjoint-subtypes ... ORM kesmek olduğunu.

Eğer önermek apporach bana haklı görünüyor. Siz farklı aktör tipleri arasında ayırım için aktör-baz tabloya actortype sütun ekleyebilirsiniz. Her özel aktör tablonun PK 'kıllı' sorguları önlemek için actorbase tabloya FK olacağını ve miras gibi '-a' ilişki taklit etmek.

the best answer I've ever seen for this has been: http://en.wikipedia.org/wiki/The_Third_Manifesto

Ne yazık ki burada stackoverflow tek bir cevap alan sığan bir şey değil. Böyle bir kısaltma üçüncü manifesto doğru bir yansıması olmayacağını ben burada kısaltmak dener, ama seni uyarıyorum. Yerine kısaltmayı okuyarak tam olarak anlamak varsayarak, aslında lanet şeyi okumak için bu çözüm tüm eleştirileri yönlendirmek lütfen. Tamam, buraya gidiyor.

adlı üç yeni sütun türlerini işçi, işveren ve temas tanımlar. Ilgili türleri sütunlarında bu tür her saklayın nesneler. Veri modelinin geri kalanı için normalleşme standart kurallara uyun.

Benim duygu güncel popüler veritabanı teknolojisi aslında bu şeyler yapmak için "doğru" bir şekilde, (özellikle, bir çok veritabanı sistemleri, yeni tip tanımını izin vermez) desteklemiyor olması. bu nedenle ne önemli değil, her zaman bir uzlaşma duruma zorunda olacak. Ama üçüncü manifestosunu okuduktan sonra, en azından size ödün konum ne bileceksiniz.

ORM şu anda sorunun ezici popüler bir çözümdür, ama doğru çözüm olduğuna inanmıyorum.

Muhtemelen this question tartışıldığı gibi zaman Nesne Rol Modelleme ile tanımak değer. Gördüğüm en büyük sorun ilişkisel veri hakkında bir kavramsal tasarım tartışma olması için varolan hiçbir kabul metodoloji olmasıdır. Yapabileceğiniz en mantıklı modelleme (ERM genellikle). Nesne Rol Modelleme bu tartışma için temel sağlar. Ben size olabilecek benzer bir cepten tasarım tartışma tanınabilir eserleri görmek umuyoruz.

Birçok RDBMS sınıf kalıtım kadar aynı şekilde alt tablolar ana tabloları bağlayan bir tablo miras özelliği sunuyoruz. uygulama satıcıdan satıcıya biraz değişir, ama benzer kavramları uygulama dışında ağrı bazı alabilir.

Ayrıca, çoğu RDBMSs tetikleyiciler, depolanmış görüş ve uygulanması davranış ayırabilirsiniz saklanan prosedürleri bazı kombinasyonu var. Böyle PostgreSQL'in kuralları (manzaralı bir genelleme) gibi birçok durumda, çok sofistike kapsüllenmesini sunan ve kullanımı oldukça kolay.

Birkaç kişi nesne-ilişkisel empedans uyumsuzluğu kaydetti. En iyi çözüm sadece son zamanlarda popüler olmaya kazanmış olan OODBMS lehine olarak RDBMS vazgeçmek etmektir.

Bu API'ler ile herhangi bir nesne veritabanları bildiğim kadarıyla, saf PHP yok, dedi. Üretilen bir hızlı arama this result ama o yıllarda güncelleştirilmiş değil. Öte yandan, ben Hibernate, db4o dahil olmak üzere diğer dil için nesne veritabanlarının bol duydum ettik ve ZODB.

Ben PHP için LINQ kullanmanızı öneririz. Ben. Net LINQ hakkında biliyorum, ama ben PHPLinq bir cami sanırım.

http://phplinq.codeplex.com/

Veri modeli bir seviyeye eksik gibi bana sadece görünüyor. Ben daha çok bu gibi kurarsınız:

People Tablo - (gerçek insanlar hakkında sadece bilgi)

Roles Tablo - (roller insanların tipleri, yani İşçi, İşveren, İletişim olabilir - bu role ve bilgi özel)

PeopleRoles Tablo - (people_id, ROLE_ID, belki vs tarihlerini değiştirme / başlangıç)

Entities Tablo - (Kuruluşların farklı tanımlayın)

RoleEntities Tablo - (ROLE_ID, entity_id, vb)

Sonra bir başka Rolü (ya da onlara çeşitli roller için izin) bir Kişi değişen basit bir güncelleme olduğunu.