SQLite 3 odczyt z tysiąca tabel...

0

Witam.
Od kilku dni próbuje rozgryźć SQLite3 i wertuję net w poszukiwaniu rozwiązania i nic sensownego nie znajduję. Dlatego postanowiłem, poprosić Was, czyli specjalistów o pomoc.

Mam bazę, w której jest blisko tysiąc tabel. W każdej z nich są po trzy kolumny (id, rating,ip) - są więc takie same (znajdują się w nich tylko różne dane).

Chciałbym odczytać i porównać dane ze wszystkich na raz (rekord rating gdzie ip=1).

Nie da się więc przy pomocy UNION bo niby jak? Mam tysiąc razy to powtórzyć? Nie da się też zastosować zmiennej po FROM więc jak?

Najlepiej by było tak: - najpierw pobieram nazwy tabel (name) i od razu pobieram dane z tabel z pola "rating" (gdzie id jest równe 1) :

<?php 
try
{
$db = new PDO('sqlite:./rating/database/ratings2.sqlite');
}
catch (PDOException $e)
{
print "Błąd połączenia z bazą!: " . $e->getMessage() . "<br/>";
die();
}
$statement = $db->query('SELECT name FROM sqlite_master UNION SELECT rating FROM name WHERE id="1" ');
foreach($statement as $wiersz)
{
echo(" = ".$wiersz['name']."<br />");
echo(" = ".$wiersz['rating']."<br />");
}
$statement->closeCursor();
?>

Ale to oczywiście nie może działać...

Może więc podmieniać nazwy tabel pod $zmienna i w ten sposób odczytywać pola rating ze wszystkich tabel?

$statement = $db->query('SELECT name FROM sqlite_master UNION SELECT rating FROM $zmienna WHERE id="1" ');
foreach($statement as $wiersz)
{
echo(" = ".$wiersz['name']."<br />");
echo(" = ".$wiersz['rating']."<br />");
$zmienna = $wiersz['name'];
}

Bez szans... - też nie zadziała...

Czy ktoś ma jakiś pomysł? Nie wiem w którym kierunku iść...

0

Taką bazę już masz i musisz to zrobić, czy dopiero rozwijasz aplikację? Bo może warto by było zastosować chociaż delikatną normalizację na początek?

0

No właśnie już mam taką bazę i jej modyfikacja nie wchodzi w rachubę (wykorzystywana jest przez inne skrypty).

0

a co stoi na przeszkodzie, żeby pobrać nazwę tych tabel z bazy (google wie jak) i skleić potem zapytanie z tysiącem unionów lub zrobić tysiąc zapytań do poszczególnych tabel i skleić wynik po stronie php? Innej opcji nie ma.

0

Nazwy łatwo pobrać: SELECT name FROM sqlite_master
ale nie wiem jak potem sklecić resztę (by pobrać rekordy ze wszystkich tabel).
W Google wszędzie pełno przykładów na połączenie odczytu wyników z dwóch czy kilku tabel ale już z takiej ilości to nic nie znalazłem.
Baza jest dynamiczna - ciągle powstają nowe tabele - odpada więc wklepanie tysiąc razy UNION SELECT.....

0

Ja się zastanawiam czy takie tysiąc unionów sqlite da radę obsłużyć. W oraclu 9 lub 10 na pewno miałem ograniczenie że nie mogłem dać w zapytaniu "IN" ponad 100 elementów z palca (jako wynik subselecta się dało dowolną ilość). A jeżeli to ma iść serio na stronę to 1000+1 selectów będzie wolne jak muł.

@xvidasd Podziel się rozwiązaniem, bo sam jestem ciekaw.

0

czym się różni wg Ciebie złożenie w jedną całość zapytań z 3 tabel od takiego z 300?

0

Tym że złożenie 3 tabel widziałem. 300 w życiu bym nie pomyślał że można zrobić.

0
xvidasd napisał(a)

Baza jest dynamiczna - ciągle powstają nowe tabele - odpada więc wklepanie tysiąc razy UNION SELECT.....

Musiał bym to zrobić w pętli by sprawdzić czy to ma sens przy takiej ilości..
Tylko czy jest jakiś sposób na użycie zmiennej zamiast nazwy tabeli w składni:

SELECT coś FROM $zmienna
??

0

przecież to są podstawy PHP! Może zacznij od czegoś prostszego

0

Tak tylko nie wiem czemu nie działa w SQLite3 ....

0

Może tak:

$tables = array();
foreach($tabs as $tab){
$tables[] = "SELECT rating FROM {$tab} WHERE xxx";
}

$sql = implode("\n UNION \n", $tables);

0

nie czaisz - musisz wykonać n + 1 zapytań do bazy, gdzie n to liczba tabel. Najpierw robisz jedno o listę tabel a potem dla każdej tabeli robisz osobne zapytanie i wszystko wkładasz do jednej tabeli/wyświetlasz czy co tam chcesz z tym zrobić. Weź tylko pod uwagę, że jak będziesz miał tych danych dużo i będziesz je chciał najpierw posortować to możesz zajechać serwer.

Rozważ może zrobienie jednej tabeli zbiorczej, do której wrzucisz dane ze wszystkich tabel a na tych istniejących utworzysz triggery, które będą zasilać nowymi danymi tą dużą tabelę.

0

Zrobiłem troszkę inaczej i działa!

<?php 
try
{
	$db = new PDO('sqlite:./rating/database/ratings2.sqlite');
}
catch (PDOException $e)
{
    print "Błąd połączenia z bazą!: " . $e->getMessage() . "<br/>";
    die();
}
$tables = array();
$tabless = array();
$statement = $db->query("SELECT name FROM sqlite_master");
foreach($statement as $wiersz)
{
	$i = $wiersz['name'];
	
	$statementt = $db->query("SELECT rating FROM {$i} WHERE id='1'  ");
	foreach($statementt as $wierszz)
		{  
		 $tables[] = $wiersz["name"];
		 $tabless[] = $wierszz["rating"];
		}
}
$statement->closeCursor();

arsort($tabless);
foreach ($tabless as $klucz => $wartosc)
		{
		echo $tables[$klucz];
		echo $wartosc."<br />";
		}
?>

Zamiast UNION najpierw odczytuję nazwy tabel a potem w pętli odczytuję dane z tabel.

1

A kto taką bazę zaprojektował?

1 użytkowników online, w tym zalogowanych: 0, gości: 1