Skocz do zawartości
mastah7991

Wykonanie SELECT i UPDATE w jednym zapytaniu z różnych tabel

Polecane posty

Witam

Jako że moja znajomość z mysql nie jest największa, postanowiłem napisać tu temat z pomocą.

 

Mając bazę danych mam tam 2 tabele.

Struktura pierwszej tabeli to kolejno

  • ID (auto numerowane)
  • STEAMID (klucz główny)
  • NICK
  • EXP
  • POZIOM

Za to 2 tabela to

  • ID
  • Umiejętność
  • Poziom

a tu klucz główny to ID+umiejętność

 

i teraz jak mogę 1 zapytaniem zaktualizować dane w 2 tabeli znając steam_id?

Czy ma to być podobnego coś do tego:

UPDATE umiejetnosci SET poziom=10 WHERE (Umiejetnosc='szybkosc' AND id=(SELECT ID FROM Gracze WHERE Steamid='Moj_Steam_id')

Jeśli nie czy może ktoś podpowiedzieć/nakierować jak to zrobić jednym zapytaniem?

Uważam że pobieranie ID jednym zapytaniem a potem aktualizowanie następnym jest mniej optymalne.

 

Pozdrawiam

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

O wiele byś sobie ułatwił sprawę ustawiając STEAMID jako klucz główny.

 

Ludzie z jakiegoś powodu mają wbite do głowy, że każda tabela musi mieć auto incremented pole ID, i nie ważne co to jest.

 

Jak sobie uświadomisz, że tabela NIE MUSI mieć ID, a musi mieć coś, po czym jednoznacznie odwołasz się do konkretnego wiersza, to ci się życie ułatwi.

 

SteamID jest unikalny dla każdego gracza, zgadza się? A więc możesz go użyć jako klucza głównego w 1szej tabeli, i jako klucza obcego w drugiej tabeli, która jako głównego klucza używa SteamID + Umiejętność.

 

W ten sposób twoje zapytanie robi się o wiele prostsze.

UPDATE umiejetnosci SET poziom=10 WHERE STEAMID=0;

Co więcej, klucz główny w postaci SteamID spowoduje o wiele szybsze działanie całej bazy jeśli ustawisz go jako BIGINT UNSIGNED. Zwykłe ID jest najczęściej typu INT unsigned, a więc wydajność fetchowania po tym i po tym jest mocno zbliżona.

 

Łap przykład prosto ode mnie:

 

72seipq.png

 

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

dziękuje bardzo

myślałem że ustawienie ID będzie bardziej wydaje z powodu przechowywania Cyfry a nie ciągu znaków

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Będzie.

 

Jeśli u ciebie STEAMID jest typu VARCHAR to robisz to źle, powinien być BIGINT(17) UNSIGNED.

 

A różnica w operacjach na BIGINT UNSIGNED i INT UNSIGNED jest tak niewielka, że nie ma nawet co sprawdzać.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Będzie.

 

Jeśli u ciebie STEAMID jest typu VARCHAR to robisz to źle, powinien być BIGINT(17) UNSIGNED.

 

A różnica w operacjach na BIGINT UNSIGNED i INT UNSIGNED jest tak niewielka, że nie ma nawet co sprawdzać.

 

ostatnie pytanie.

Do ilu znaków przechowuje BIGINT(17) UNSIGNED?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

 

ostatnie pytanie.

Do ilu znaków przechowuje BIGINT(17) UNSIGNED?

 

BIGINT zawsze przechowuje 8 bajtowe liczby, czyli w przypadku unsigned jest to zakres <0, 18446744073709551615>. 17 to podpowiedź dla MySQLa, że to pole będzie miało zawsze do 17 cyfr, pomimo że jak widzisz BIGINT jest dostatecznie duży na przechowywanie 19 cyfr i niewielką część liczb 20-cyfrowych.

 

Używanie BIGINTa jest nieco bardziej wydajne niż używanie NUMERICa. Komputery lepiej sobie radzą z 64-bitową liczbą niż z numericiem składającym się z 17 cyfr. W tym drugim przypadku MySQL musi czytać cyfrę po cyfrze, podczas gdy w tym pierwszym jest to najzwyczajniejsza w świecie 64-bitowa liczba.

 

To działa na podobnej zasadzie, jak typ BOOL. W MySQL boolean nie istnieje, i jest zapisywany jako unsigned TINYINT(1). TINYINT jest najmniejszym rodzajem danych jaki MySQL obsługuje, a jedynka podpowiada, że będzie nas interesować tylko jedna cyfra (0 albo 1, pomimo że w to pole poprawnie można wpisać zakres <0,9>, a sam TINYINT UNSIGNED pozwala na zakres <0,255>).

Edytowano przez Archi (zobacz historię edycji)

Udostępnij ten post


Link to postu
Udostępnij na innych stronach
Gość Kamikadze

@Archi a mam taki małe pytanie.

 

Sprawdzałeś może co się stanie jak przykładowo masz kolumnę ID (int). Co się stanie jak granica INT zostanie przekroczona a skrypt będzie chciał dodać kolejny rekord?

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

@Archi a mam taki małe pytanie.

 

Sprawdzałeś może co się stanie jak przykładowo masz kolumnę ID (int). Co się stanie jak granica INT zostanie przekroczona a skrypt będzie chciał dodać kolejny rekord?

 

Zależy od systemu bazodanowego.

 

W MySQL będzie to:

 

ERROR 1467 (HY000): Failed to read auto-increment value from storage engine

 

Czyli zwykły failed insert.

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

W zwykłej kolumnie zatrzyma się na zakresie, czyli dla INT wartość 2147483647 choć byśmy chcieli wpisać np 3000000000

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Witam.

z góry przepraszam za brak odpowiedzi jednak mnie nie było i nie miałem czasu. Otóż BIGINT(17) UNSIGNED jest typem danych przechowującym cyfry, jednak SteamID jest to ciągznaków przykład STEAM:1:12345678

 

Czy jedyna opcja to varchar?

Jeśli tak to czy dodawać kolumny ID czy szukać po typie danych związanym z "ciągiem znaków"

Pozdrawiam

Udostępnij ten post


Link to postu
Udostępnij na innych stronach

Bądź aktywny! Zaloguj się lub utwórz konto

Tylko zarejestrowani użytkownicy mogą komentować zawartość tej strony

Utwórz konto

Zarejestruj nowe konto, to proste!

Zarejestruj nowe konto

Zaloguj się

Posiadasz własne konto? Użyj go!

Zaloguj się


×