• Najnowsze pytania
  • Bez odpowiedzi
  • Zadaj pytanie
  • Kategorie
  • Tagi
  • Zdobyte punkty
  • Ekipa ninja
  • IRC
  • FAQ
  • Regulamin
  • Książki warte uwagi

Zapętlone zapytanie do bazy

Object Storage Arubacloud
0 głosów
600 wizyt
pytanie zadane 2 października 2017 w SQL, bazy danych przez kevin Mądrala (5,010 p.)

Witam!

Mam takie pytanie bo chyba sam coś zagmatwałem. Postawiłem sobie założenie dla strony wielojęzykowej aby tłumaczenia wyrazów zapisywać w bazie danych. Dla każdej podstrony pobierać tylko te wyrazy których dana podstrona używa więc tabela w bazie wygląda następująco:

Tabela: language

id ( jako CHAR ) <- i jest to nazwa wyrazu/zdania do tłumaczenia

pl <- język Polski

eng <- język Angielski

Przykładowe rekordy wyglądają tak:

id                     | pl                 | eng

text_log_in            | Zaluguj Się      | Log In

text_log_out          | Wyloguj się     | Log Out

Pole id pozostaje mi dać jako UNIQUE i nie ma sensu mi dawać tutaj do tabeli żadnego Auto Increment skoro pobieram rekordy na podstawie id jako tekst. Napisałem funkcję do pobierania tłumaczenia tylko jednego pola pl bądź eng lecz mam nadzieję że istnieje bardziej cywilizowany sposób do pobierana rekordów:

  function load_language( $language, $words )
  {
    try
    {
      $loaded_words = [];
      
      //
      //  Połączenie z bazą danych
      //
      $db_connect = connect_db_PDO();

      //
      // Zapytanie, wartość $language jako może wystąpić to 'pl' lub 'eng' !
      $query = 'SELECT '. $language .' FROM language WHERE id = :id';

      //
      //  Pętla pobierająca tłumaczenie w danym języku dla każdego podanego słowa
      foreach ($words as $key => $value)
      {
        if(isset($loaded_words[$value]))    // Debug
          echo 'Uwaga! Ponowne wczytanie słowa - '.$value.'</br>';

        $stmt = $db_connect->prepare($query);
        $stmt->bindValue(':id', $value, PDO::PARAM_STR);

        $stmt->execute();

        if($stmt->rowCount())
        {
          $loaded_words[$value] = $stmt->fetch(PDO::FETCH_ASSOC)[$language];
        }
        else    // Debug
        {
          $loaded_words[$value] = 'Nie znaleziono !';
          echo 'Uwaga! Nie znaleziono tłumaczenia - '.$value.'</br>';
        }
        
        $stmt = null;
      }
      
      return $loaded_words;
    }
    catch(PDOException $e)
    {
      return null;
    }
  }

 

Krótkie wyjaśnienie, do funkcji podaję tablicę słów które trzeba pobrać z bazy dla danej podstrony. Słowa te są odpowiednikiem id w bazie. Tablica ma postać $words[0] = "text_log_out"; $words[1] = "text_log_in"; Wynik zwrócony przez funkcję chcę mieć jako tablicę asocjacyjną gdzie wartość to tłumaczenie słowa w danym języku a identyfikuję index tabeli za pomocą id tłumaczenia z bazy. Nie pasuję mi tylko że na darmo tworzę tablicę $words w postaci która później nie będzie istniała. Sprawa druga to taka że wykonuję w pętli zapytanie do bazy dla każdego tłumaczenia, czy nie ma na to innego sposobu ?

 

Z poważaniem,

1 odpowiedź

0 głosów
odpowiedź 2 października 2017 przez Ehlert Ekspert (212,670 p.)

Masz źle zaprojektowaną tabelę. Rozbiłbym to na 3 tabele:

language_codes:

Id(int) code
1 pl

translations_ids:

Id name
1 thanks

translations

id lang_id translations_id contain
1 2 1 Thanks
2 1 1 Dziękuję
56 20 1 Arigato
komentarz 2 października 2017 przez kevin Mądrala (5,010 p.)

Dobrze ale czemu źle ? Gdybym dodał kolumnę id do tabeli to pobierał bym rekordy na sposób identyczny czyli poprzez "doklejanie" OR

$query = "SELECT pl FROM language WHERE";
foreach ($words as $key => $value)
{

    if($key == 0) { $query .= "translation = :" . $value; } 
    $query .= " OR translation = :" . $value;
}

 

komentarz 2 października 2017 przez Ehlert Ekspert (212,670 p.)
Ja myślę na przyszłość. Przy Twoim pomyśle kiedy będziesz mieć 20000 haseł w 25 językach to Twoje zapytania zabiją bazę danych.
komentarz 3 października 2017 przez kevin Mądrala (5,010 p.)
id translation pl eng
1 log_in Zaloguj się Log In
2 log_out Wyloguj się Log Out

Ale dlaczego trzy ? Tutaj mam to w jednej tabeli ( i nawet id nie potrzeba ) pobierając tłumaczenie pobieram tylko jedną kolumnę pl lub eng, aby nie robić zapytań n razy dodaję operator OR

$query = "SELECT pl FROM language WHERE";
foreach ($words as $key => $value)
{
     if($key == 0) { $query .= "translation = " . $value; } 
    $query .= " OR translation = " . $value;
}

 

komentarz 3 października 2017 przez Ehlert Ekspert (212,670 p.)
To jak będziesz miał dodać 20 języków do dodasz 20 kolumn?
komentarz 3 października 2017 przez kevin Mądrala (5,010 p.)

Masz racje :) Ale to tylko o to chodzi ?

Druga sprawa to skoro mam trzy tabele ? To jak wygląda zapytanie ?

Aby wykonać

SELECT contain FROM translations WERE translations_id IN ( 1, 2, 3 ...) AND lang_id = 1

To muszę wykonać zapytanie pobierające id języka oraz kolejne zapytanie pobierające id translations_id. Czy nie mogę zrobić tego w jednym zapytaniu ?

Podobne pytania

0 głosów
1 odpowiedź 2,572 wizyt
pytanie zadane 28 lipca 2017 w SQL, bazy danych przez Mateusz1223 Bywalec (2,440 p.)
+1 głos
1 odpowiedź 132 wizyt
+1 głos
2 odpowiedzi 251 wizyt
pytanie zadane 2 lutego 2022 w SQL, bazy danych przez XDBX Użytkownik (640 p.)

92,555 zapytań

141,403 odpowiedzi

319,557 komentarzy

61,940 pasjonatów

Motyw:

Akcja Pajacyk

Pajacyk od wielu lat dożywia dzieci. Pomóż klikając w zielony brzuszek na stronie. Dziękujemy! ♡

Oto polecana książka warta uwagi.
Pełną listę książek znajdziesz tutaj.

Akademia Sekuraka

Kolejna edycja największej imprezy hakerskiej w Polsce, czyli Mega Sekurak Hacking Party odbędzie się już 20 maja 2024r. Z tej okazji mamy dla Was kod: pasjamshp - jeżeli wpiszecie go w koszyku, to wówczas otrzymacie 40% zniżki na bilet w wersji standard!

Więcej informacji na temat imprezy znajdziecie tutaj. Dziękujemy ekipie Sekuraka za taką fajną zniżkę dla wszystkich Pasjonatów!

Akademia Sekuraka

Niedawno wystartował dodruk tej świetnej, rozchwytywanej książki (około 940 stron). Mamy dla Was kod: pasja (wpiszcie go w koszyku), dzięki któremu otrzymujemy 10% zniżki - dziękujemy zaprzyjaźnionej ekipie Sekuraka za taki bonus dla Pasjonatów! Książka to pierwszy tom z serii o ITsec, który łagodnie wprowadzi w świat bezpieczeństwa IT każdą osobę - warto, polecamy!

...