Article View: pl.comp.bazy-danych
Article #194107Re: PostgreSQL - jak najlepiej definiować dynamiczne pola?
From: Marek
Date: Mon, 09 Feb 2015 22:36
Date: Mon, 09 Feb 2015 22:36
138 lines
8423 bytes
8423 bytes
W dniu 2015-02-09 o 18:54, wloochacz pisze: >> b) W dynamicznie dostawianych polach w tabeli właściwej (tzn. >> zawierającej dane, które rozszerzamy o dodatkowe pola) z narzuceniem >> typu pól i budowaniem na nich indeksów gdzie trzeba. >> >> To wtedy nie ma problemu w tworzeniu relacji. Aczkolwiek dynamiczne >> dostawianie pól to nie jest profesjonalne podejście... > Uzasadnij, bo mam dokładnie odwrotne wyobrażenie. Uzasadnić to, że nie jest profesjonalnym podejściem iż żyjąca aplikacja modyfikuje sobie sama strukturę bazy danych? Już raz cytowałem kolegę Cezarego (2ga wypowiedź w wątku). Też mam pewne obiekcje. > Tylko jest kilka ALE - nie wyobrażam sobie ręcznego zarządzania tym > bajzlem. to musi być rozwiązane systemowo i automatycznie w taki sposób, > aby raz dodane pole było widoczne dla całego systemu. Żaden problem. Wiele lat stosowałem takie rozwiązanie. Ani razu nie miałem problemów. Sama baza pilnuje siebie na poziomie triggerów i plpgsql. Jedyna ALE jakie poza nie profesjonalnym podejściem jakie doświadczyłem, to fakt, że przy dużej liczbie rekordów usuwanie (lub dodawanie - już nie pamiętam) pól czy indeksów trwało bardzo długo, co czasem kończyło się timeoutem PHP. Rozwiązałem to również ale tak czy owak szukam lepszej metody. > Bez rekompilacji systemu (albo zmiany kodów źródłowych w językach > skryptowych - jeżeli ktoś się ma ochotę czepić...). > Ale takie podejście przerasta większość "programistów". > Sorry - taka prawda. Niczego w kodach źródłowych nie zmieniałem. Mnie to nie przerosło a nie jestem jakimś mega programistą :-) Przykładowo (z życia wzięte), redaktor CMS zażyczył sobie dodać cechę lokalu (ma ogródek) w serwisie WWW poświęconym deweloperce. Chciał aby dodanie tej opcji stanowiło od razu kryterium wyszukiwania w części publicznej serwisu. Dodał nowe pole, nazwał je, zaznaczył iż ma się w publicznej wyszukiwarce pojawić, ustawił samodzielnie w lokalach, które mają ogródek a które nie i aplikacja śmiga. Niczego nie musiałem doprogramowywać. > Po drugie, nie każdemu takie podejście potrzebne. W realnym zastosowaniu > okazuje się, że wykorzystanie paradygmatu EAV (doczytaj se w wikipedii > czy gdzie tam chcesz co to, po co i na co) ze wszystkimi jego wadami > daje po prostu radę. Chodzi o wirusowe zapalenie tętnic u koni? :-D Żartuję... ale coś takiego właśnie stosowałem, co miało swoje poważne ograniczenia. Np. trudno jest budować indeksy i constrainty jeśli wartości w tym modelu raz są datą, raz są liczbą, raz są tekstem. Stąd mój były pomysł rozbudowy modelu EAV o dublowanie wartości w tabelach. Ale o tym dalej bo zaciekawiło mnie co napisałeś. > I od tego bym na Twoim miejscu zaczął, skoro dla Ciebie "ogromna" baza > danych ma 100 tabel ;-) A tak, dla mnie to już ogromna :-) >> Na wszelki wypadek zobrazuję co mam na myśli. Jakaś tabela, powiedzmy, >> 1. W tabeli dodatkowych pól powstaje pole D, jego opisy etc. > W EAV nie dodaje się pola, tylko wiersz do tabeli definicji pola. > Na jego poziomie definiujesz nazwę, typ danych, constraint i link do > relacji/obiektu biznesowego. Ja bym jeszcze dodał flagę określającą, czy > dana wartość jest skalarna czy wektorowa. ... i tu jest to "dalej" o jakim wyżej wspominam. Też tak kombinuję ale utknąłem właśnie na budowaniu constraintów. Posłużmy się tabelami jak tu aby łatwiej było rozmawiać: http://programowanie.opole.pl/archives/1692 słabo się to rozwiązanie nadaje bo entity_id nie określa o jaką tabelę chodzi. Tabel typu "entities" może być wiele. Tak więc values musi mieć jedno pole więcej do identyfikacji o jaką tabelę chodzi. Powiedzmy byłoby to pole typu wyliczeniowego (to mi wystarczy) entity_name. No i teraz jak zbudować constraint między parą entity_id/entity_name wiążący którąś z kilku tabel entities1, entities2 ... Czyli entity_id ma się odnosić do entity1 gdy pole entity_name zawiera entity1. Ale to samo entity_id może się odnosić do każdej innej tabeli również. A po drugie, usprawniłbym tabelę values o różne reprezentacje wartości: TEXT, INT, DATETIME, FLOAT i być może coś jeszcze. Typ atrybutu określałby, które z tych pól reprezentuje wartość.Choć z drugiej strony więcej niż jedno pole wartości atrybutu może strasznie utrudnić programowanie aplikacji. Obawiam się tego bardzo. Z kolei potrzebuję zindeksować pole wartości INT po to aby móc budować na nim klucze obce. Trochę to skomplikowane zaczyna być. >> 2. W tabeli wartości następuje skojarzenie w/w pola D z rekordem w >> tabeli "dokument" i w uniwersalnym typie text pola "wartość" jest >> przechowywana liczba oznaczająca ID użytkownika w tabeli userów. No ale >> raczej kiepsko byłoby budować indeksowanie na polu tekstowym, które raz >> jest liczbą a innym razem tekstem. > Zależy. > Ale po cholerę Ci indeks na tym polu? Hmmm.. jeśli pole jest kluczem obcym, to wszędzie czytam, że zawsze powinien być indeks na nim. >> 3. Z w/w powodu dostawiamy pole danych D do tabeli "dokument" (lub >> tabeli powiązanej poprzez dziedziczenie - inherit) > Dziedziczenie w bazach relacyjnych? Ho, ho... można i tak, ale ja bym > się w to nie bawił. Miałem na myśli separację tabeli dynamicznie dostawianych pól od tabeli "entities" posługując się nomenklaturą z linku. Wtedy możemy grzebać jedynie w tabeli potomnej a zostawić w spokoju rodzica. > Oczywiście są bazy post-relacyjne lub obiektowo-relacyjne, które > zapewniają rożne wsparcie do takich zabawek (mam na myśli OOP w ujęciu > bazo-danowym). Mówimy o Postgresie wyłącznie. > Moim zdaniem - nie warto. Więcej z tym kłopotów niż pożytku. > Ale ja tam się na tym nie znam... Bo ja wiem czy to takie zagmatwane? Zamiast robić SELECT * FROM document robisz SELECT * FROM document_child. Zmieniasz tylko nazwę tabeli przy SELECTach i nic się nie zmienia w kodzie. Dla porządku możesz też przy UPDATE'ach, INSERT'ach - jak uznasz za stosowne. > Constrainty (banał) i budowanie SQL (a tu zależy - może to być w miarę > proste lub nie) możesz sobie załatwić po stronie aplikacji. > Napiszesz to raz i będzie działało z dowolnym typem dokumentu. > Tu nie ma co dywagować, tylko doczytać o EAV i zakodować. > Do roboty! ;-) Powoli mnie przekonujesz. Musimy tylko szczegóły dopracować. Mógłbym oczywiście programowo tworzyć constrainty. Raczej zbudowałbym je w plpgsql a nie w aplikacji. Baza niech pilnuje swojej integralności sama. -- Pozdrawiam, Marek
Technical Details
Message-ID:
<mbbcop$3il$1@news.icm.edu.pl>Path:
mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!.POSTED!not-for-mailReferences:
<mag0cl$o93$1@news.icm.edu.pl> <slrnmcqmva.5h7.tom@tv2.dom.local> <makuln$8ps$1@news.icm.edu.pl> <00393f98-4afb-4213-934d-9156200c7bcb@googlegroups.com> <mavv3h$n7l$1@news.icm.edu.pl> <8e718611-b061-4aaa-9fb0-1687681dcb94@googlegroups.com> <mb25li$mon$1@news.icm.edu.pl> <f6a66af6-182a-47d7-a297-7a1b998ebee2@googlegroups.com> <mb2g3c$isp$1@news.icm.edu.pl> <e64d3758-bdb8-4f73-b75a-3aa9b5f789e6@googlegroups.com> <54d5e7a7$0$2188$65785112@news.neostrada.pl> <1e428ab3-3e7f-4a50-a7b0-d5d458ad2a65@googlegroups.com> <54d66936$0$2206$65785112@news.neostrada.pl> <89a37815-f4ab-423f-bdc8-13ff32bb4f7e@googlegroups.com> <ac14966e-c0e4-498b-9257-25d1e6363d0b@googlegroups.com> <mbahen$9em$1@news.icm.edu.pl> <54d8f45a$0$2214$65785112@news.neostrada.pl>Show Full Headers
Complete Article Headers
Path: mbox-mo1.pugleaf.net!news-archive.icm.edu.pl!news.icm.edu.pl!.POSTED!not-for-mail From: Marek <precz@spamowi.com> Newsgroups: pl.comp.bazy-danych Subject: Re: PostgreSQL - jak najlepiej definiować dynamiczne pola? Date: Mon, 09 Feb 2015 23:36:07 +0100 Organization: ICM, Uniwersytet Warszawski Lines: 138 Message-ID: <mbbcop$3il$1@news.icm.edu.pl> References: <mag0cl$o93$1@news.icm.edu.pl> <slrnmcqmva.5h7.tom@tv2.dom.local> <makuln$8ps$1@news.icm.edu.pl> <00393f98-4afb-4213-934d-9156200c7bcb@googlegroups.com> <mavv3h$n7l$1@news.icm.edu.pl> <8e718611-b061-4aaa-9fb0-1687681dcb94@googlegroups.com> <mb25li$mon$1@news.icm.edu.pl> <f6a66af6-182a-47d7-a297-7a1b998ebee2@googlegroups.com> <mb2g3c$isp$1@news.icm.edu.pl> <e64d3758-bdb8-4f73-b75a-3aa9b5f789e6@googlegroups.com> <54d5e7a7$0$2188$65785112@news.neostrada.pl> <1e428ab3-3e7f-4a50-a7b0-d5d458ad2a65@googlegroups.com> <54d66936$0$2206$65785112@news.neostrada.pl> <89a37815-f4ab-423f-bdc8-13ff32bb4f7e@googlegroups.com> <ac14966e-c0e4-498b-9257-25d1e6363d0b@googlegroups.com> <mbahen$9em$1@news.icm.edu.pl> <54d8f45a$0$2214$65785112@news.neostrada.pl> NNTP-Posting-Host: 89-69-222-145.dynamic.chello.pl Mime-Version: 1.0 X-Trace: news.icm.edu.pl 1423521369 3669 89.69.222.145 (9 Feb 2015 22:36:09 GMT) X-Complaints-To: usenet@news.icm.edu.pl NNTP-Posting-Date: Mon, 9 Feb 2015 22:36:09 +0000 (UTC) User-Agent: Mozilla/5.0 (Windows NT 6.3; WOW64; rv:31.0) Gecko/20100101 Thunderbird/31.4.0 In-Reply-To: <54d8f45a$0$2214$65785112@news.neostrada.pl> Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit