Autor Zpráva
kimmy
Profil *
Zdravím,

prosím vás, nevěděli byste někdo, jak vyřešit můj problém? Mám databázi MySQL, kde načítám z šesti RSS zdrojů zprávy (například z idnes.cz, denik.cz, atd.). Načítám z každého tohoto serveru do databáze 10 linků. V databázové tabulce mám jako atributy id (auto-increment), server (např. www.idnes.cz) a link (odkaz na jednotlivé zprávy). Záznamů je tady v tabulce 60. A teď jde o tohle:

Zprávy se musí v db samozřejmě aktualizovat. Protože ale zprávy na serverech přibývají rychle, chtěla bych nějak šikovně použít příkaz UPDATE (aby sloupec ID měl stále hodnoty od 1 do 60), aby se z databáze vždy vymazal nejstarší řádek daného serveru a místo něj se do db vložil nový.

Dejme tomu, ze pro ID 1 až 10 uchovávám server www.idnes.cz a 10 jeho nejaktuálnějších linků. ID 11 až 20 je pro www.lidovky.cz a tak dále. Když ale skript proběhne (bude probíhat Cronem), potřebuji, aby se všech 10 záznamů daného serveru posunulo. To znamená, aby se nová zpráva zapsala na začátek na ID=0. Záznam, který byl na ID=0 by se měl posunout na ID=1. Záznam, který byl na ID=1, by se měl posunout na ID=2 atd.. A záznam, který měl ID=10 by se měl z tabulky vymazat. (Stejně tak pro jiný server, který má "rezervováno" ID např. 30 až 40 by se 31 posunulo na 32, 32 na 33, atd)

Doufám, že mi rozumíte. Takto by se mělo zaručit to, že zprávy budou v tabulce seřazeny od nejaktuálnější, a databáze se nebude zbytečně zvětšovat (ID bude vždy 1 až 60).

Zatím jsem stvořila něco takového, ale funkční to moc není. Buď se mi přepíše všech 10 linků daného serveru na jeden stejný, nebo se mi do db vloží nový řádek se zprávou a s ID=61 .. a to nechci.. Zatím mám tedy toto:

for ($i=0; $i<=9; $i++) {
				$sql2 = "SELECT link, server FROM rss WHERE link = '".$rs['items'][$i]['title']."' AND server = '".$rs['link']."'";
				$result2 = mysql_query ($sql2);
				$row2 = mysql_fetch_array ($result2);
				$pole[] = $row2;
				$smarty->assign ('pole', $pole);
				if (!$row2) {
			
					$sql = "UPDATE rss SET link = '".$rs['items'][$i]['title']."' WHERE id IN (SELECT MIN (id) FROM rss WHERE server = '".$rs['link']."')";
					$result = mysql_query ($sql);
				}
			} 


Pro informaci je $rs pole, do kterého ukládám celý obsah RSS kanálu. No a jak jde poznat, používám Smarty šablony, ale to nemá na vytvoření sql dotazu vliv.

Nevěděli byste tedy někdo, jak tento dotaz opravit, aby to zapisovalo do databáze tak, jak jsem popsala výše? Byla bych moc a moc vděčná, už se tu s tím trápím dlouho. Předem děkuju!
kimmy
Profil *
Moc se omlouvám ze překlep, ID rovno nule se do tabulek nezapisuje, ID začíná od jedné... Ale i tak doufám, že je pochopitelné, co jsem mým dotazem chtěla říct. Ještě jednou moc děkuji za případnou ochotu.
Kcko
Profil
A neni to jedno ze se ID zvysuje? Osobne bych to udelal tak po insertu 10 novych linku z konkretniho serveru bych ty stare jednodusse vymazal.

// INSERT - zapisu deset novych
// DELETE - smazu vse krome tech 10 nejnovejsich ...


A je to vyreseno?
kimmy
Profil *
Mě právě tohle řešení přišlo trochu neperspektivní z toho důvodu, že ID bude za pár měsíců provozu v tisících a pak i stotisících atd..

Ale pokud by tedy toto nevadilo, je zde druhý problém, že při každé aktualizaci stránky není vždy všech 10 zpráv nových. Někdy přibyde jedna, někdy dvě, někdy žádná (záleží jak často se stránka aktualizuje). A když musím mít zobrazených vždy 10 nejaktuálnějších odkazů, mohlo by se stát, že se jich zobrazí třeba 5 (v případě, že by se načetlo 5 nových zpráv od idnes.cz a já všech 10 starších od idnes.cz v databázi vymazala)..

Proto mi přijde ten UPDATE takový rozumnější.. ale nevím. Nejde mi správně ho sestavit.
Kcko
Profil
Na co tam ty ID ... ktera slouzi pouze k ocislovani radku potrebujes tedy?
Jinak pokud si nastavis typ INT tak ti snad tento rozsah -2147483648 do +2147483647, ( nebo bez znamenka 0 až 4294967295 ) musi stacit na 50 let :)



Jinak ja bych na to sel nejak takto ...


1/ Zapisu 10 novych odkazu, nebo proste tolik kolik jich je ... ( 3, 5, ... 10) - to umis
2/ Vyberu si SQL dotazem do pole 10 nejnovejsich odkazu pro dany server cili neco jako
SELECT * FROM rss WHERE server = '$server' ORDER BY id DESC LIMIT 10
while($r = mysql_fetch_assoc())
{
 $odkazy[] = $r['id'];
}

3/ Vymazu vsecko krom tech 10 nejnovejsich
DELETE FROM rss WHERE id NOT IN implode(",", $odkazy) AND server = '$server'



Nenapsal jsem Ti presnou syntaxi, ale takhle bych to udelal ja a s nejakymi narustajicimi ID bych si hlavu nelamal ... vubec
kimmy
Profil *
DELETE FROM rss WHERE id NOT IN implode(",", $odkazy) AND server = '$server'

Tady v tom řádku mi hází error: Parse error: syntax error, unexpected ',' in C:\web\www\index.php on line 81

Nelíbí se mu ta čárka za slovem IMPLODE... Abych řekla pravdu, taky nechápu, jak jsi to s tím implode myslel. Ale i tak moc děkuju za nápad a za rady.

A s tím ID máš pravdu, je blbost starat se o to, že to narůstá... (co jiného by vlastně člověk od auto-increment měl čekat :-) ) Jinak je tam víceméně kvůli tomu, aby tabulka měla primární klíč. Dávat za primární klíč VARCHAR se mi nechtělo..

Ještě jednou díky!
Kcko
Profil
tak melo by to byt takto


mas pole idecek .. ktere chces zachovat $odkazy


a ty pote musis prevest na string oddeleny carkama aby se to dalo pouzit v klauzuli in


tak $stringOdkazy = implode(",", $odkazy);

a pak tedy ... DELETE bla bla WHERE id NOT IN ($stringOdkazy)

bezna to vec
kimmy
Profil *
Děkuju, takhle už to sebral... Ale nechápu, proč mi teď vypisuje 10 stejných zpráv pod sebou. On si vybere tu s tím nejvyšším ID daného serveru, a tu zobrazí 10x pod sebou. Přitom by měl zobrazit 10 různých zpráv.. Nerozumím tomu, protože do databáze se to naskládá pěkně (6 x 10 různých řádků)... Nevíš čím to může být?

Ten kód vypadá takhle:

for ($i=0; $i<=9; $i++) {
				$sql2 = "SELECT * FROM rss WHERE link = '".$rs['items'][$i]['title']."' AND server = '".$rs['link']."'";
				$result2 = mysql_query ($sql2);
				$row2 = mysql_fetch_array ($result2);
				
				if (!$row2) {
					$sql = "INSERT INTO rss (id, server, link) VALUES (NULL, '".$rs['link']."', '".$rs['items'][$i]['title']."')";
					$result = mysql_query ($sql);
				}
				
				$sql3 = "SELECT * FROM rss WHERE server = '".$rs['link']."' ORDER BY id DESC";
				$result3 = mysql_query ($sql3);
				$row3 = mysql_fetch_assoc ($result3);
					$pole[] = $row3;
					$smarty->assign ('pole', $pole);
					
				$stringPole = implode(",", $pole); 
				$sql4 = "DELETE FROM rss WHERE id NOT IN $stringPole AND server = '".$rs['link']."'";
				$result4 = mysql_query ($sql4);	
}
Kcko
Profil
moje ICQ je v profilu, bylo by to na dlouho, mas moznost se mi ozvat do 20,45 pak odplouvam v dali

Vaše odpověď

Mohlo by se hodit


Prosím používejte diakritiku a interpunkci.

Ochrana proti spamu. Napište prosím číslo dvě-sta čtyřicet-sedm:

0