Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [php][mysql] Aktualizacja list relacyjnych, Problem koncepcyjny
markonix
post 19.08.2013, 11:55:01
Post #1





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Może na prostym, fikcyjnym przykładzie:

Dodajemy wpis w CMS.
Jednym z atrybutów wpisu są TAGI (0..n).
Tagi dodawane są dynamicznie przez pola input (JS).
Dodajemy wpis i kilka tagów my przypisanych.
Tutaj nie ma większego problemu - korzystamy z INSERT w pętli, PS bądź insert batch (akurat teraz pracuje na CodeIgniter).
Na tagi mamy oddzielną tabelę w bazie o strukturze:
[ id ] [ art_id ] [ name ]

I teraz chciałbym edytować listę. W jaki sposób?

1) update na podstawie [id], w porządku ale co zrobić gdy ktoś doda nowy tag? Wtedy też trzeba wykrywać nowo dodane wartości?
2) co zrobić w przypadku usunięcia? znów kolejne zapytania?

Najprostsze rozwiązanie jakie mi przychodzi do głowy to:
- usuwamy wszystko co ma art_id = X
- dodajemy na nowo tagi
Te rozwiązanie jest jednak niewygodne ze względu na szybkie narastanie wartości ID -> np. mając 20 tagów każda edycja (bez względu na to ile się zmieniło) zwiększa najwyższe id o 20. Poza tym te operacje wydają mi się mało wydajne - nawet gdy nie zmieni tagów to wykonają się dwa spore zapytania.

Praktycznie ten problem koncepcyjny wraca do mnie jak bumerang. Za każdym razem mam jakiś pomysł ale żaden mnie nie satysfakcjonuje.

Jakieś sugestie?


--------------------
Go to the top of the page
+Quote Post
nospor
post 19.08.2013, 13:00:11
Post #2





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Tabela ART
ID
blablabla

Tabela TAG
ID
NAME
blablabla

TABELA ART_TAG
ID_ART
ID_TAG

Zauwaz ze tabela wiazaca nie ma wlasnego ID i nie ma tu mowy ze cos ci bedzie narastac.
Robiac edycje kasujesz wszystko z danego arta i dodajesz na nowo.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
markonix
post 19.08.2013, 13:19:29
Post #3





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Tzn uproszczając chodzi Ci o:

ARTS: id, title...
Tags: id_art, name

Czyli pominięcie ID w tabeli tagu?

Takie rozwiązanie raz zastosowałem i działa w porządku choć nadal nie rozwiązuje kwestii optymalności - duży delete, duży insert.
Te rozwiązanie także ma minus że TAGi nie mają swoich ID co może potem narobić kłopotów.
Twoja struktura problem z ID niweluje ale dodaje tu już trzecią tabelę - kolejne JOINy, troszkę taki przerost formy. Poza tym pierwszy insert nie da się załatwić jednym zapytaniem bo musisz najpierw dodawać wpis do tabeli TAG aby otrzymać id, potrzebne w tabeli ART_TAG.

Mam jeszcze inny pomysł (na dwóch tabelach):
podwójny indeks na id i art_id UNIQ. Wykonanie INSERT / UPDATE ON DUPLICATE na każdym rekordzie.
Potem wszystkie ID wykorzystane lecą do DELETE NOT IN.
Też troszkę zapytań ale na dwóch tabelach i delete, który wywali mniej rekordów.

Jeszcze 3 brzydka ale optymalna opcja.
Na jednej tabeli i dodatkowa kolumna "tags" z tablicą (serializacja).

Ten post edytował markonix 19.08.2013, 13:21:42


--------------------
Go to the top of the page
+Quote Post
nospor
post 19.08.2013, 13:22:43
Post #4





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Te rozwiązanie także ma minus że TAGi nie mają swoich ID co może potem narobić kłopotów.
Kurcze..... widzisz ile ja ci podalem tabel a ile ty twierdzisz ze ja ci podalem? Ja ci podalem 3 tabele, ty to ni z gruszki ni z pietruszki upraszcasz do dwoch tabel.....

Spojrz co ci podalem:
tabela na arty
tabela na tagi (tu tag ma swoje ID)
tabela wiążąca tag z artem - to w tej tabeli wiazesz do jakiego arta nalezy jaki tag i to w tej tabeli kasujesz i dodajesz łączenia.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
markonix
post 19.08.2013, 13:29:51
Post #5





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Wszystko rozumiem, po prostu czytaj do końca posty.


--------------------
Go to the top of the page
+Quote Post
nospor
post 19.08.2013, 13:32:43
Post #6





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Sorka, to po co wracasz do swojej struktury piszac tak, jakbys pisal o mojej.... zmuszasz ludzic do czytania calego posta wink.gif

Cytat
Twoja struktura problem z ID niweluje ale dodaje tu już trzecią tabelę - kolejne JOINy, troszkę taki przerost formy. Poza tym pierwszy insert nie da się załatwić jednym zapytaniem bo musisz najpierw dodawać wpis do tabeli TAG aby otrzymać id, potrzebne w tabeli ART_TAG.

Tak sie robi prawidlowo. Dzieki temu tag o nazwie XYZ jest jeden w bazie. W twoim rozwiazaniu tagow XYZ bedzie tyle, ile razy ludzie przy roznych artach go wpisza. Tak sie nie robi i juz.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
markonix
post 19.08.2013, 13:40:20
Post #7





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Czyli idąc dalej to przy pierwszym dodawaniu wpisu skrypt musiałby najpierw sprawdzać czy dany TAG już istnieje.
Jeżeli nie to dodaje i zwraca ID, jeżeli jest to musiałby dodatkowo pobierać jego ID (nie widzę w Googlach jakiejś ciekawej konstrukcji typu INSERT OR RETURN KEY IF EXISTS).


--------------------
Go to the top of the page
+Quote Post
nospor
post 19.08.2013, 13:43:43
Post #8





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Czyli idąc dalej to przy pierwszym dodawaniu wpisu skrypt musiałby najpierw sprawdzać czy dany TAG już istnieje.
Dokladnie

Cytat
jeżeli jest to musiałby dodatkowo pobierać jego ID (nie widzę w Googlach jakiejś ciekawej konstrukcji typu INSERT OR RETURN KEY IF EXISTS).
jejkus.... przeciez robiac sprawdzanie czy jest czy nie ma to mozesz od razu to ID pobierac. Jak ci pobierze ID, znaczy ze jest, jak ci nie pobierze, znaczy ze nie ma


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post
markonix
post 19.08.2013, 13:55:21
Post #9





Grupa: Zarejestrowani
Postów: 2 707
Pomógł: 290
Dołączył: 16.12.2008
Skąd: Śląsk

Ostrzeżenie: (0%)
-----


Czytaj całe zdania, które cytujesz zresztą.

Chodziło mi o załatwienie tego jednym zapytaniem - INSERT nowy TAG, jeżeli BRAK wtedy RETURN ID.
Ale się nie da. Sprawdzasz czy najpierw istnieje (i pobierasz te ID, to oczywiste), jeżeli nie ma to dodajesz i tak w pętli przy każdym tagu.
Liczba zapytań = liczba tagów x 3 (sprawdzenie, insert w tabeli pierwszej, insert w tabeli drugiej).

W każdym razie te rozwiązanie nie jest mi na rękę, przykład z tagami faktycznie może nie był dobrą analogią do mojego aktualnego problemu bo po prostu wartości dodawane z małym prawdopodobieństwem będą się dublować (np. imię i nazwisko, wtedy tym bardziej nie chciałbym aby jedno ID miały dwie różne osoby o takim samym imieniu i nazwisku).

Ps. No i ogólnie teraz jeszcze jak myślę.
Twoje rozwiązanie nie przewiduje literówek.
Dodałem 10 tagów, w jednym była literówka.
Poprawiam literówkę, daje wyślij (nie dodaje nic, nie usuwam).
Skrypt usuwa wszystkie wpisy z TABELA ART_TAG.
Dodaje od nowa w tym jednego tagu nie znajduje.

Dochodzi tutaj obserwowanie czy nie ma jakichś tagów "bękartów" nie używanych nigdzie.

Ten post edytował markonix 19.08.2013, 13:58:52


--------------------
Go to the top of the page
+Quote Post
nospor
post 19.08.2013, 14:03:11
Post #10





Grupa: Moderatorzy
Postów: 36 557
Pomógł: 6315
Dołączył: 27.12.2004




Cytat
Czytaj całe zdania, które cytujesz zresztą.
To pisz po ludzku. To kolejny post gdzie piszesz tak jakbys pisal o dwoch roznych rzeczach a potem ze niby nie i ze to niby moje nieumiejetne czytanie....

Cytat
Skrypt usuwa wszystkie wpisy z TABELA ART_TAG.
Dodaje od nowa w tym jednego tagu nie znajduje.

Wszystko zalezy jak ty te tagi dodajesz/zarzadzasz nimi.
Poprawienie literowki w arcie, polega na tym, ze usuwasz zly tag i dodajesz nowy - wowczas wszystko jest jak nalezy. Nie mozna edytowac nazwy juz dodanych tagow, a nawet jesli to przewidujesz, to edycja nazwy w z automaty usuwa dany tag z arta i edycje czyni nowym tagiem w arcie.


--------------------

"Myśl, myśl, myśl..." - Kubuś Puchatek || "Manual, manual, manual..." - Kubuś Programista
"Szukaj, szukaj, szukaj..." - Kubuś Odkrywca || "Debuguj, debuguj, debuguj..." - Kubuś Developer

Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 14.08.2025 - 14:34