Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

Załóżmy, że mamy 3 obiekty
Produkt:
+nazwa
+opis

Samochód:
+poj_silnika

Rower:
+rozmiar_ramy

Samochód i rower dziedziczą z produktu. Jak najlepiej przedstawić to w bazie? Ostatnio wymyśliłem, żeby mieć tabelę produkt i do niej relacją 1:1 podłączone tabele samochód i rower, które mają tylko specyficzne dla siebie pola. Co myślicie o takim rozwiązaniu?

konto usunięte

Temat: Dziedziczenie - przełożenie obiektów na bazę

Wojciech Sznapka:
Co myślicie o takim rozwiązaniu?

zakładam, że produktów jest więcej niż rozmiarów ram i pojemności silnika razem wziętych

więc można też zrobić:

produkty:

id | nazwa | opis | poj_silnika | rozmiar_ramy, gdzie pola poj_silnika i rozmiar_ramy będą połączone kluczami obcymi z tabelami samochód/rower z możliwością wstawienia NULL. taki sobie słowniczek.
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

nie, liczba produktów = liczba samochodów + liczba rowerów
Przemysław Szczerbicki

Przemysław Szczerbicki Programista,
freelancer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Wygląda to na generalizację typów a to się rozwiązuje np poprzez dwa opcjonalne klucze obce w tabeli głównej: jeden do roweru, drugi do samochodu w Twoim wypadku.

pzdr.
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: Dziedziczenie - przełożenie obiektów na bazę

mozesz tez trzymac dane w osobnej tablicy i joinowac co potrzeba, masz wtedy mozliwosc dodania dowolnej ilosci cech do obiektu, oczywiscie najwygodniej cos takiego zrobic na jakims orm'ie
Paweł G.

Paweł G. Managing Director

Temat: Dziedziczenie - przełożenie obiektów na bazę

Wojciech Sznapka:
Samochód i rower dziedziczą z produktu. Jak najlepiej przedstawić to w bazie? Ostatnio wymyśliłem, żeby mieć tabelę produkt i do niej relacją 1:1 podłączone tabele samochód i rower, które mają tylko specyficzne dla siebie pola. Co myślicie o takim rozwiązaniu?

Ja bym tak to rozwiązał, ale czy to jest optymalne rozwiązanie, to pewności nie mam :)
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

też właśnie pewności nie mam co do tego rozwiązania. Co do orm'a, to właśnie używam doctrine, mogłem o tym wspomnieć na początku ;-) Doctrine oferuje dziediczenie, ale trzeba dublować dziedziczone kolumny w wszystkich potomnych. Btw. przydałoby się jeszcze coś w rodzaju klas abstrakcyjnych do doctrine'a.
Jarek W.

Jarek W. Software Engineer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Tak poza wszystkim, to jeśli używasz na przykład Oracle, to możesz też rzucić okiem na to (dokładniej: na podtypy) oraz na to (na slajd "Realizacja podtypów i łuków").
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

Jarek W.:
Tak poza wszystkim, to jeśli używasz na przykład Oracle, to możesz też rzucić okiem na to (dokładniej: na podtypy) oraz na to (na slajd "Realizacja podtypów i łuków").


dzięki wielkie, bardzo przydatne pdfy :-)
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: Dziedziczenie - przełożenie obiektów na bazę

Wojciech Sznapka:
też właśnie pewności nie mam co do tego rozwiązania. Co do orm'a, to właśnie używam doctrine, mogłem o tym wspomnieć na początku ;-) Doctrine oferuje dziediczenie, ale trzeba dublować dziedziczone kolumny w wszystkich potomnych. Btw. przydałoby się jeszcze coś w rodzaju klas abstrakcyjnych do doctrine'a.

templates, latwo sie je pisze i rezultat wlasnie taki jak klasa abstrakcyjna do tego jest to imitacja wielokrotnego dziedziczenia

a tak w ogole to Doctrine rzadzi :)Łukasz Cepowski edytował(a) ten post dnia 14.02.09 o godzinie 16:16
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

Łukasz Cepowski:
Wojciech Sznapka:
też właśnie pewności nie mam co do tego rozwiązania. Co do orm'a, to właśnie używam doctrine, mogłem o tym wspomnieć na początku ;-) Doctrine oferuje dziediczenie, ale trzeba dublować dziedziczone kolumny w wszystkich potomnych. Btw. przydałoby się jeszcze coś w rodzaju klas abstrakcyjnych do doctrine'a.

templates, latwo sie je pisze i rezultat wlasnie taki jak klasa abstrakcyjna do tego jest to imitacja wielokrotnego dziedziczenia

a tak w ogole to Doctrine rzadzi :)Łukasz Cepowski edytował(a) ten post dnia 14.02.09 o godzinie 16:16

Templates dały radę :-) Odnośnie doctrine, to całkowicie się zgadzam z Tobą :-)
Piotr P.

Piotr P. Software Developer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Łukasz Cepowski:
mozesz tez trzymac dane w osobnej tablicy i joinowac co potrzeba, masz wtedy mozliwosc dodania dowolnej ilosci cech do obiektu, oczywiscie najwygodniej cos takiego zrobic na jakims orm'ie

Co się dzieje gdy dziedziczenie odbywa sie na poziomie klasy *i* na poziomie bazy? Na przykład:

Samochod.insert(); /* ID = X */
Produkt.delete(X);

Rower.insert(); /* ID = Y */
Produkt.update(Y);
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: Dziedziczenie - przełożenie obiektów na bazę

Piotr P.:
Co się dzieje gdy dziedziczenie odbywa sie na poziomie klasy *i* na poziomie bazy? Na przykład:

Samochod.insert(); /* ID = X */
Produkt.delete(X);

Rower.insert(); /* ID = Y */
Produkt.update(Y);

jezeli dane trzymasz w kilku tabelach to robisz miedzy nimi relacje za pomoca kluczy obcych i ustawiasz kaskadowe usuwanie.

wtedy po Twoim: Produkt.delete(X), zostanie usuniety rekord z tabeli glownej + rekordy z innych tabeli (np: rekord z profilem obiektu, lub rekordy z tablicy referencyjnej z cechami).

imho jezeli klasa produkt to manager obiektow to taki sposob troche smierdzi bo jest malo wygodny.

ogolnie ja bym sprobowal zrobic to w mniej wiecej taki sposob:

class Object extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('objects');

/// Jakas tam nazwa obiektu.
$this->hasColumn('name', 'string');
}

public function setUp()
{
/// Zwraca kolekcje cech dla obiektu.
$this->hasMany('Object_Property as properties', array(
'local' => 'id',
'foreign' => 'object_id',
'onDelete' => 'CASCADE'
));
}
}

class Object_Property extends Doctrine_Record
{
public function setTableDefinition()
{
$this->setTableName('objects_properties');

/// Nazwa cechy.
$this->hasColumn('name', 'string');

/// Wartosc cechy.
$this->hasColumn('value', 'string');

/// Id obiektu do ktorego nalezy cecha.
$this->hasColumn('object_id', 'integer');
}

public function setUp()
{
/// Relacja z obiektem.
$this->hasOne('Object as object', array(
'local' => 'object_id',
'foreign' => 'id'
));
}
}

i wtedy moge zrobic np:

class Samochod extends Object { /.../ }
class Rower extends Object { /.../ }

i uzywanie np:

$samochod = new Samochod();
$samochod->name = 'Jakas zajebista fura';
$samochod->properties[0]->name = 'rozmiar kola';
$samochod->properties[0]->value = (string) 123;
$samochod->properties[1]->name = 'spalanie na 100km';
$samochod->properties[1]->value = 'tyle co czlog';
$samochod->save();

$rower = new Rower();
/.../
$rower->delete(); /// wywala wszystkie rekordy zwiazane z rowerem.

moglem cos pojeb%c ale mniej wiecej oto mi chodzilo :PŁukasz Cepowski edytował(a) ten post dnia 19.02.09 o godzinie 12:46
Adam Brodziak

Adam Brodziak PHP, football, fun

Temat: Dziedziczenie - przełożenie obiektów na bazę

Artykuł o stragetiach mapowania obiektów z dziedziczeniem na relacyjną bazę danych.
Piotr P.

Piotr P. Software Developer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Łukasz Cepowski:
Piotr P.:
Co się dzieje gdy dziedziczenie odbywa sie na poziomie klasy *i* na poziomie bazy? Na przykład:

Samochod.insert(); /* ID = X */
Produkt.delete(X);

Rower.insert(); /* ID = Y */
Produkt.update(Y);

jezeli dane trzymasz w kilku tabelach to robisz miedzy nimi relacje za pomoca kluczy obcych i ustawiasz kaskadowe usuwanie.

wtedy po Twoim: Produkt.delete(X), zostanie usuniety rekord z tabeli glownej + rekordy z innych tabeli (np: rekord z profilem obiektu, lub rekordy z tablicy referencyjnej z cechami).

Usuwam Produkt więc Samochod powinien zostać nietknięty.
W drugim przypadku aktualizuje Produkt więc Rower powinien zostac nietknięty. Pomijając kwestie pozoimu abstrakcji dostępu do bazy ( baza A obsługuje klucze obce i trigery a baza B już nie ), w obydwu przypadkach operacji dokonuje na obiekcie klasy bazowej więc ani Rower ani Samochód nie powinień mieć zmienionych rekordów.
Przemysław Szczerbicki

Przemysław Szczerbicki Programista,
freelancer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Piotr P.:

Usuwam Produkt więc Samochod powinien zostać nietknięty.
W drugim przypadku aktualizuje Produkt więc Rower powinien zostac nietknięty. Pomijając kwestie pozoimu abstrakcji dostępu do bazy ( baza A obsługuje klucze obce i trigery a baza B już nie ), w obydwu przypadkach operacji dokonuje na obiekcie klasy bazowej więc ani Rower ani Samochód nie powinień mieć zmienionych rekordów.

Skoro produkt jest generalizacją dla samochodu i przestaje on istnieć to samochód jako szczególny przypadek takiego produktu ( w relacji 1:1 ) powinien też zostać usunięty. Przykladowo mamy pojazdy( które są właśnie produktem ) 2-kołowe, 3-kołowe, 4-kołowe i usuwamy te 4-kołowe no to samochód 'out' tak na moje oko ;)

Co do obsługi kluczy obcych i triggerów to własnie ta warstaw abstrakcji powinna zapewnić 'symulację' takiego zachowania jeśli sam silnik bazy danych tego nie zapewnia.

pzdr.
Łukasz C.

Łukasz C. Senior Technical
Architect

Temat: Dziedziczenie - przełożenie obiektów na bazę

Piotr P.:
Piotr P.:
Co się dzieje gdy dziedziczenie odbywa sie na poziomie klasy *i* na poziomie bazy? Na przykład:

Samochod.insert(); /* ID = X */
Produkt.delete(X);

Rower.insert(); /* ID = Y */
Produkt.update(Y);

Usuwam Produkt więc Samochod powinien zostać nietknięty.
W drugim przypadku aktualizuje Produkt więc Rower powinien zostac nietknięty. Pomijając kwestie pozoimu abstrakcji dostępu do bazy ( baza A obsługuje klucze obce i trigery a baza B już nie ), w obydwu przypadkach operacji dokonuje na obiekcie klasy bazowej więc ani Rower ani Samochód nie powinień mieć zmienionych rekordów.

no ja ten kod odczytalem tak ze masz obiekt samochod ktory dziedziczy z produktu, no i chcesz usunanc produkt o podanym X a wiec samochod - na chlopski rozum usuwasz dokladnie ten samochod a nie jakies abstrakcyjne cus :S
Piotr P.

Piotr P. Software Developer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Przemysław Szczerbicki:
Piotr P.:

Usuwam Produkt więc Samochod powinien zostać nietknięty.
W drugim przypadku aktualizuje Produkt więc Rower powinien zostac nietknięty. Pomijając kwestie pozoimu abstrakcji dostępu do bazy ( baza A obsługuje klucze obce i trigery a baza B już nie ), w obydwu przypadkach operacji dokonuje na obiekcie klasy bazowej więc ani Rower ani Samochód nie powinień mieć zmienionych rekordów.

Skoro produkt jest generalizacją dla samochodu i przestaje on istnieć to samochód jako szczególny przypadek takiego produktu ( w relacji 1:1 ) powinien też zostać usunięty.

Dlaczego? Czy w klasie która jest rodzicem definiujesz wywołanie metody abc dla każdej klasy potomnej? Skąd Obiekt klasy produkt ma wiedzieć że istnieje obiekt potomny taki jak samochod albo rower? Rozumiem w drugą stronę parent::method, ale w tym przypadku chcesz wywołać child::method?

Co to znaczy "szczególny przypadek"? Klasa Rower czy Samochód jest potomną klasy Produkt. Tu chyba nie ma nic szczególnego :)
Piotr P.

Piotr P. Software Developer

Temat: Dziedziczenie - przełożenie obiektów na bazę

Łukasz Cepowski:

no ja ten kod odczytalem tak ze masz obiekt samochod ktory dziedziczy z produktu, no i chcesz usunanc produkt o podanym X a wiec samochod - na chlopski rozum usuwasz dokladnie ten samochod a nie jakies abstrakcyjne cus :S

Na chłopski rozum to ja założyłem, że klasa Produkt wprowadzi metody dostępu do bazy. Więc usuwając Produkt nie usuwam Samochodu. Dlaczego uważasz, że klasa rodzica powinna implementować funkcjonalność klasy potomnej?

Można by przyjąć, że każda klasa będzie posiadać własną implementację dostępu do bazy, ale wówczas wystarczy dopisanie kilku interjfejsów ( co jest bez sensu w PHP ) lub potraktowanie klasy Produkt jako klasy abstrakcyjnej, ale wtedy wątek nie miałby sensu :)
Wojciech Sznapka

Wojciech Sznapka CTO @ STS Zakłady
Bukmacherskie

Temat: Dziedziczenie - przełożenie obiektów na bazę

w tym przypadku nie ma klasy produkt, są tylko obiekty klasy samochód i rower, które mają wspólne cechy, które to można sprowadzić do abstrakcyjnej klasy produkt i z niej dziedziczyć.



Wyślij zaproszenie do