![]() |
![]() ![]() |
![]() |
![]()
Post
#1
|
|
Grupa: Zarejestrowani Postów: 83 Pomógł: 1 Dołączył: 25.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
Witam, mam takie dwie tabele w bazie danych:
tabela "dane" ilsoc_userow int ... tabela "uzytkownicy" id_usera int (PRIMARY KEY) .... Podczas zakladania nowego konta (wpis przez INSERT) calosc dziala w ten sposob: pobierz ilosc userow -> $ilosc=ilosc_userow+1 -> zapisz ilosc userow w "dane" -> utworz przez INSERT wpis w "uzytkownicy" gdzie "id_usera"=$ilosc no i wszystko byloby cacy, gdyby nie to, ze jezeli 2-ch uzytkownikow zalozy konto w tej samej sekundzie to jeden wpis robi sie poprawnie, a drugi jest pusty (wpis bez zadnych danych) Jak mozna temu zaradzic? -------------------- Pomogłem? Kilknij "Pomógł"
|
|
|
![]()
Post
#2
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Kolumna id_usera powinna zwiększać się automatycznie. Ilość user-ów ma niewiele (a na pewno nie powinna mieć nic) wspólnego z ich identyfikatorami. System jest źle zaprojektowany.
EDIT Liczbę user-ów (bez tych, którzy np. konto usuną) można pobrać zawsze:
Gwoli wyjaśnienia. Załóżmy, że w systemie masz 5 użytkowników: id nazwa 1 user1 2 user2 3 user3 4 user4 5 user5 W takim wypadku w tabeli dane ilosc_userow jest równa 5. Załóżmy, że użytkownik 1 usunie konto. Wtedy ilosc_userow jest równa 4. Dodanie nowego usera powoduje, że ilosc_userow znowu się zwiększa do 5, ale w bazie danych jest już użytkownik o id 5 i nie można dodać takiego użytkownika. Nic z tym nie zrobisz, po prostu system jest źle zaprojektowany. Ten post edytował mortus 7.09.2011, 17:22:02 |
|
|
![]()
Post
#3
|
|
Grupa: Zarejestrowani Postów: 83 Pomógł: 1 Dołączył: 25.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
hmm... pewnie masz racje wprowadze ta zmiane, do tej pory uzywalem zapisu ilosc w innej tabeli, poniewaz po 1. liczba uzytkownikow jest podana na dole strony i myslalem, ze uzywanie SELECT COUNT bedzie bardziej obciazalo baze niz pobranie "gotowej" wartosci a po 2. wpis w innej tabeli eliminowalby rowniez uzywanie SELECT COUNT podczas rejestracji...
Zastanawia mnie czy COUNT jest "lekkie" czy przy duzej ilosci rekodrow moze zamulic. Sam myslalem nad rozwiazaniem: <zablokuj tymczasowo baze> wykonaj instrukcje <odblokuj baze> ale nie wiem czy istnieje taka mozliwosc oraz czy jest skuteczna (co z uzytkownikiem/uzytkownikami, ktory w tym czasie jest blokowany - tj. rowniez zaklada konto) inny sposob, aczkolwiek nie wiem czy mozliwy, to cos w rodzaju:
Inna sprawa jest czy jezeli uzyje metody pobierania przez COUNT - czy to bez blokowania bazy wystarczy Ps. jezeli chodzi o usuwanie uzytkownikow i o rzeczy o ktorej piszesz to mam tego swiatomosc i po prostu nie usuwam wpisow tylko mam kolumne "typ" z danymi 1|2|3 dla konto aktywne|konto nieaktywne|konto usuniete Ten post edytował shycat 7.09.2011, 17:29:22 -------------------- Pomogłem? Kilknij "Pomógł"
|
|
|
![]()
Post
#4
|
|
Grupa: Zarejestrowani Postów: 2 178 Pomógł: 596 Dołączył: 25.09.2009 Skąd: Piwniczna-Zdrój Ostrzeżenie: (0%) ![]() ![]() |
Jedynym słusznym wyjściem jest przeprojektowanie bazy danych, co wyjaśniłem wyżej po wyedytowaniu wiadomości. Istnieje możliwość blokowania tabel, jednak dla któregoś z dwóch użytkowników zawsze skończy się to błędem. Liczbę użytkowników jak najbardziej możesz przechowywać w tabeli dane, jednak to ta liczba powinna być uzależniona od liczby wierszy w tabeli uzytkownicy, a nie na odwrót. Najlepiej będzie zmusić kolumnę id_usera do automatycznego zwiększania wartości.
Cytat Ps. jezeli chodzi u usuwanie uzytkownikow i o rzeczy o ktorej piszesz to mam tego swiatomosc i po prostu nie usuwam wpisow tylko mam kolumne "typ" z danymi 1|2|3 dla konto aktywne|konto nieaktywne|konto usuniete Przez lata może to doprowadzić do olbrzymiej nadmiarowości danych, co będzie owocowało brakiem optymalności. Zauważ, że do każdego zapytania musisz dodawać warunek sprawdzający, czy użytkownik przypadkiem już nie istnieje, co przy dużej liczbie rekordów będzie dodatkowo obciążać bazę danych. |
|
|
![]()
Post
#5
|
|
Grupa: Zarejestrowani Postów: 83 Pomógł: 1 Dołączył: 25.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
Cytat Zauważ, że do każdego zapytania musisz dodawać warunek sprawdzający, czy użytkownik przypadkiem już nie istnieje Nie bardzo rozumiem co masz na mysli. To czy uzytkownik "istnieje" czyli wartosc kolumny "typ", jest sprawdzane tylko podczas logowania, aktywacji konta (klikniecie w link z emaila) i w momencie gdy ktos wchodzi na profil danego uzytkownika. Ok, wiec teraz w sumie moje istotne pytanie, czy jest jakis sposob wykonania przykladu, o ktorym juz pisalem: (lub w inny sposob, ale za pomoca jednego zapytania) Czy po prostu musze pierw pobrac wartosc COUNT, a potem count+1 i uzyc tego jako ID -------------------- Pomogłem? Kilknij "Pomógł"
|
|
|
![]()
Post
#6
|
|
Grupa: Zarejestrowani Postów: 27 Pomógł: 3 Dołączył: 19.05.2009 Ostrzeżenie: (0%) ![]() ![]() |
Nie można tego zrobić transakcją?
|
|
|
![]()
Post
#7
|
|
![]() Grupa: Zarejestrowani Postów: 317 Pomógł: 58 Dołączył: 6.11.2005 Ostrzeżenie: (0%) ![]() ![]() |
Triggery założone na INSERT i DELETE rozwiążą wszystkie problemy.
-------------------- |
|
|
![]()
Post
#8
|
|
Grupa: Zarejestrowani Postów: 83 Pomógł: 1 Dołączył: 25.02.2008 Ostrzeżenie: (0%) ![]() ![]() |
Hm, wlasnie skonczylem wertowanie tego forum i czesci wynikow google dla roznych stron... i nigdzie nie znalazlem informacji o tym, jak mozna zablokowac na chwile baze danych, po to, aby dwa wpisy sie nie zdublowaly (nie zaleznie czy ID jest pobierane z innej tabeli czy przez COUNT biezacej) i oczywiscie po wykonaniu zadania baze odblokowac... oraz zeby w czacie "blokowania" inny uzytkownik, ktory akurat w tej samej sekundzie wykona INSERT'a mogl w jakis sposob dodac swoj wpis... takze poddaje sie w moich poszukiwaniach i prosze o w miare dokladna instrukcje, bo "tiggery zalozone na insert i delete"... nic mi nie mowi, wspomniane transakcje tez chyba nie pomoga, poniewaz z tego co wyczytalem, to uzywa sie ich glownie na dzialaniach pomiedzy roznymi tabelami - a nie tu tkwi moj problem.
------------------------------------------------------------------------- Pobuszowałem jeszcze troche i mysle, ze w moim przypadku dobre bedzie uzycie AUTO_INCREMENT dla `id` userow + LOCK I UNLOCK TABLES. Nigdzie nie znalazlem informacji o tym, ze Cytat Istnieje możliwość blokowania tabel, jednak dla któregoś z dwóch użytkowników zawsze skończy się to błędem lecz z tego co wyczytalem, "drugi" uzytkownik bedzie musial "poczekac", az "pierwszy" skonczy wykonywac zapytanie. -------------------- Pomogłem? Kilknij "Pomógł"
|
|
|
![]()
Post
#9
|
|
![]() Grupa: Zarejestrowani Postów: 317 Pomógł: 58 Dołączył: 6.11.2005 Ostrzeżenie: (0%) ![]() ![]() |
"tiggery zalozone na insert i delete"... nic mi nie mowi Zerknij sobie np. tutaj: http://forge.mysql.com/wiki/Triggers. Trzeba chwilę poświęcić na czytanie, ale zapewniam Cię, że warto. -------------------- |
|
|
![]() ![]() |
![]() |
Wersja Lo-Fi | Aktualny czas: 20.07.2025 - 02:15 |