calif
4.09.2010, 15:41:34
Witam!
Potrzebuję Trigger'a (chyba tak to się nazywa), który robiłby taką coś:
Gdy ktoś rejestruje się na forum MyBB - czyli zostaje dodany rekord do tabeli mybb_users, trigger reaguje i dopisuje tego samego użytkownika (rekord) do innej tabeli.
Tak, abym mógł zainstalować większą ilość for na jednej bazie danych, aby na wszystkich forach byli Ci sami użytkownicy.
Przypuśćmy jedna tabela z ludźmi to: mybb_users, a druga to mybb1_users, kolejna mybb2_users itp. itd.
Jak to zrobić?
Pozdrawiam!
calif
everth
4.09.2010, 17:13:22
Nie wiem czy jest to rozwiązanie ale chyba oszczędniej będzie to zrobić tworząc aliasy dla mybb_users za pomocą widoków, np.
CREATE VIEW `mybb1_users` AS SELECT * FROM `mybb_users`;
calif
4.09.2010, 21:48:30
Dzięki wielkie! Daję punkt.
Działa.
@Down,
dzięki za odp. już sprawdziłem.
Pozdrawiam!
everth
4.09.2010, 21:54:56
Niepotrzebna - potrzebujesz jednej tabeli - mybb_users, przy założeniu że wszystkie skrypty operują na tabeli o takiej samej strukturze. Tutaj jest tylko jedna tabela - widoki są niejako aliasami. Przetestuj to sobie najpierw, bo widoki nie są pełnoprawnymi tabelami i może to nie być do końca stabilne (choć wydaje mi się że powinno śmigać bez problemu).
cojack
4.09.2010, 22:21:59
Widok nie jest aliasem, tylko interfejsem.
Podany przykład nie robi tego czego oczekiwałeś.
Musisz utworzyć trigger:
CREATE FUNCTION "insertNewUsersToOtherUserTablesFunction" RETURNS TRIGGER AS $BODY$
DECLARE
"__row" RECORD;
BEGIN
SELECT
*
INTO
"__row"
FROM
"mybb_users"
WHERE
"user_id" = NEW."user_id"; -- czy jak tam sie kolumna nazywa
INSERT INTO "mybb_users1" SELECT * FROM "__row";
INSERT INTO "mybb_users2" SELECT * FROM "__row";
-- i tak dalej...
RETURN NEW;
END;
$BODY$ LANGUAGE 'plpgsql';
CREATE TRIGGER "insertNewUsersToOtherUserTablesTrigger"
AFTER INSERT ON "mybb_users"
FOR EACH ROW EXECUTE PROCEDURE "insertNewUsersToOtherUserTablesFunction"();
To jest przykład dla postgresa, nie znam procedur w mysql, ale analogicznie będziesz mógł napisać swoją. Nie zapomnij że po każdej takiej sytuacji będziesz musiał w każdej tabeli ustawić na nowo seq klucza głównego.
everth
4.09.2010, 22:30:41
Cytat
Podany przykład nie robi tego czego oczekiwałeś.
@cojack możesz rozwinąć?
Używając triggerów musi pozakładać je na każdej nowej tabeli user w każdym skrypcie forum (zakładając że wszystkie muszą się synchronizować). Przy każdej rozbudowie czegoś takiego o nowe forum musi modyfikować wyzwalacze na każdej tabeli poprzedniej. To nie jest wygodne.
cojack
4.09.2010, 22:36:24
Pytanie jak zrobić:
Gdy ktoś rejestruje się na forum MyBB - czyli zostaje dodany rekord do tabeli mybb_users, trigger reaguje i dopisuje tego samego użytkownika (rekord) do innej tabeli.
Odpowiedź:
CREATE VIEW `mybb1_users` AS SELECT * FROM `mybb_users`;
Ty idiotę ze mnie robisz czy mi się tylko wydaje?
@edit
i co chłop każdą linijkę w kodzie, w każdym forum będzie zmieniał z mybb_users na mybb1_users? A co przy kluczach obcych, będą się do widoku odwoływać?
everth
4.09.2010, 23:02:29
Cytat
i co chłop każdą linijkę w kodzie, w każdym forum będzie zmieniał z mybb_users na mybb1_users

Przecież to są prefiksowane tabele (przynajmniej ja tak to zrozumiałem). Kod musiałby poprawiać (choć nie grzebałem w bebechach myBB) gdyby postawił 20 skryptów i chciał się z nich odwoływać do jednej tabeli users.
Właśnie dlatego napisałem żeby sobie to
dokładnie przetestował. To jest proteza, a nie rozwiązanie. Tak samo protezą jest zastosowanie wyzwalaczy - te ostatnie trudno rozbudować, a w przy widokach nie działa praktycznie nic poza prostym CRUDem. Choć akurat o kluczach rzeczywiście nie pomyślałem w tym wypadku.
calif
4.09.2010, 23:14:35
Niestety everth, gdy rejestruję na forum które działa na mybb_*, uzytkownik nie pokazuje sie na drugim forum z mybb1_*.
cojack, uzywam mysql, ale Twoje rozwiązanie chyba pasuje.
Gdzie mam to "dać", wpisać?

Nigdy nie zajmowałem się w ten sposób bazami danych, dlatego takie noobskie pytania
cojack
5.09.2010, 08:36:33
No jak to gdzie, wrzuć to do phpMyAdmin i wykonaj jako zapytanie SQL.
calif
5.09.2010, 11:29:04
cojack, czyli to przy kazdym zarejestrowaniu czy to do tabeli mybb_users, mybb1_users, czy też mybb2_users, zapisze do wszystkich tych 3 tabel jeden rekord (użytkownika) tak?
cojack
5.09.2010, 14:34:45
Tak dokładnie, tylko nie zapominaj o sequence. Należy zaktualizować i ustawić na następną wartość.
everth
5.09.2010, 17:15:55
@cojack - nie
Jeśli założysz te wyzwalacze na każdą modyfikowaną tabelę to gwarantuje ci że każde zapytanie na nich zwróci ci błąd. Choćby dlatego że procedura będzie próbowała zmodyfikować tabelę na której został postawiony wyzwalacz. Z kolei modyfikowanie każdego wyzwalacza osobno by modyfikował wszystkie sąsiednie tabele jest trochę bez sensu.
Trochę sobie to przetestowałem i wyszło mi że najwygodniejszym rozwiązaniem będzie łańcuchowanie zdarzeń - czyli dla 3 tabel - modyfikacja np. tabeli 2 wyzwala akcję na tabeli 3, tabela 3 na 1 - 1 sprawdza że rekord istnieje na 2, więc łańcuch się kończy. Każdy insert,update,delete jest propagowany na sąsiednie tabele dzięki czemu powinny one zachować spójność. Dla większej ilości tabel triggery można generować np. za pomocą PHPa. Pozostaje pytanie o wydajność takiego rozwiązania.
Przykładowe wyzwalacze na insert dla 3 tabel -
tu.
calif
5.09.2010, 19:07:40
everth, wysłałeś mi kod dla 3 tabel, gdy zostaje dodany użytkownik, a gdy zostaną zmodyfikowany użytkownik, albo usunięty? Też będzie to działać?
A jeśli byś mógł, to powiedz jak wyobrażasz sobie takie coś dla 5 tabel (bo tak będzie w moim przypadku), mogłbyś przedstawić kod do owej operacji?
Pozdrawiam!
everth
5.09.2010, 21:01:21
Tworzysz wyzwalacze dla AFTER DELETE, AFTER UPDATE. Wzorzec masz. Do wygenerowania i zarządzania triggerami dla większej ilości tabel możesz sobie napisać jakiś skrypt (np. w PHPie). Jedyne co zmieniasz to nazwy triggerów i tabel na których operują. Pamiętaj żeby dla triggera AFTER DELETE zmienić warunek z IF NOT EXISTS na IF EXISTS.
Jak chcesz dodać nową tabelę to oznacz sobie sobie trigger na ostatniej tabeli np. dopiskiem
last - wtedy przy dodawaniu kolejnej tabeli do konfiguracji po prostu usuwasz go usuwasz (tabela ostatnia staje się przedostatnią). Rekonstruujesz triggery na dwóch ostatnich tabelach - tak żeby przedostatnia wskazywała na ostatnią, a ta z kolei na pierwszą (wtedy na ostatniej jest trigger
last). Przy usuwaniu tabeli z czegoś takiego musisz zrekonstruować wskaźnik na tabeli poprzedzającej by wskazywał na właściwą (czyli jak mamy 1->2->3->1 i usuwamy 2, to ma być 1->3->1). To jest coś jak lista jednokierunkowa.
Tu masz wszystko o triggerach w MySQL.
calif
7.09.2010, 18:52:47
Dziękuję bardzo.
Pomogliście mi bardzo.
Temat można zamknąć.
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę
kliknij tutaj.