Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [MySQL] Struktura bazy danych dla bazy utworów
@rtur
post 3.07.2014, 07:03:31
Post #1





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

Ostrzeżenie: (0%)
-----


Chcę zrobić bazę utworów które są grane w radio internetowym, z której później będę mógł pobrać informację o tym co było grane z wyszczególnieniem data_godzina|wykonawca|utwór, np. z podziałem na dni, pobrać utwory według wykonawcy, pobrać informację o tym ile razy dany utwór był zagrany. Na obecnym etapie chcę skupić się nad optymalną strukturą bazy danych, na razie wymyśliłem coś takiego:
  1. CREATE TABLE `Tracklista` (
  2. `TracklistaID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  3. `KiedyGrane` timestamp NULL DEFAULT NULL,
  4. `UtworID` int(11) NOT NULL,
  5. PRIMARY KEY (`TracklistaID`),
  6. UNIQUE KEY `KiedyGrane` (`KiedyGrane`)
  7. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;
  8.  
  9. CREATE TABLE `Utwor` (
  10. `UtworID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  11. `WykonawcaID` int(11) NOT NULL,
  12. `UtworTytul` varchar(255) COLLATE utf8_polish_ci NOT NULL,
  13. PRIMARY KEY (`UtworID`),
  14. UNIQUE KEY `UtworTytul` (`UtworTytul`),
  15. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;
  16.  
  17. CREATE TABLE `Wykonawca` (
  18. `WykonawcaID` int(10) UNSIGNED NOT NULL AUTO_INCREMENT,
  19. `WykonawcaNazwa` varchar(255) COLLATE utf8_polish_ci NOT NULL,
  20. PRIMARY KEY (`WykonawcaID`),
  21. UNIQUE KEY `WykonawcaNazwa` (`WykonawcaNazwa`)
  22. ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_polish_ci AUTO_INCREMENT=1 ;


Czy tak wyglądająca struktura bazy jest według Was w porządku, czy można by jeszcze ją bardziej zoptymalizować, coś odjąć, dodać?

W jaki sposób mając dane w postaci zmiennych $utwor, $wykonawca, $data najbardziej optymalnie wykonać takie zadanie:

Dodać zawartość zmiennej $wykonawca do tabeli 'Wykonawca' (tylko jeśli jej nie ma w tabeli), następnie z tabeli 'wykonawca' pobrać pole WykonawcaID dla rekordu zgodnego ze zmienną $wykonawca, i dodać pobraną wartość WykonawcaID i zmiennej $wykonawca do tabeli 'utwory' (tylko jeśli tego zestawu nie ma jeszcze). Na końcu pobrać z tabeli 'utwory' UtworID dla zestawu "WykonawcaID i $utwor", i wrzucić go do tabeli 'Tracklista', razem ze zmienną $data

Do powyższego zadania widzę konieczność wykonania conajmniej 5 zapytań na jeden utwór:
  1. $sqlQuery1 = INSERT IGNORE INTO 'Wykonawcy' (WykonawcaNazwa) VALUES ($wykonawca);
  2. $sqlQuery2 = SELECT 'WykonawcaID' FROM 'Wykonawcy' WHERE 'WykonawcaNazwa' LIKE '$wykonawca'; // wynik tego zapytania przypisujemy do zmiennej $WykonawcaID
  3. $sqlQuery3 = INSERT IGNORE INTO 'Utwory' (WykonawcaID, UtworTytul) VALUES (WykonawcaID, $utwor); // no właśnie, jak tu dodać tylko unikalne zestawy WykonawcaID, UtworTytul?
  4. $sqlQuery4 = SELECT 'utworID' FROM 'utwory' WHERE 'WykonawcaID'='$WykonawcaID' AND UtworTytul LIKE '$utwor' // wynik tego zapytania przypisujemy do zmiennej $UtworID
  5. $sqlQuery5 = INSERT IGNORE INTO 'Tracklista' (KiedyGrane, UtworID) VALUES ($data, $UtworID);

Biorąc pod uwagę że każde wywołanie skryptu który będzie uruchamiany cronem, to próba dodania w pętli 20 rekordów, robi się już 100 zapytań na jedno wywołanie skryptu, więc wydaje mi się to trochę nieoptymalne, nie wiem czy dobrze myślę, ale wydaje mi się że mogę wyeliminować oddzielne zapytania select wrzucając je od razu do zapytań insert, ale nie wiem czy to już najbardziej optymalne rozwiązanie?


--------------------
Artur
Go to the top of the page
+Quote Post
Pyton_000
post 3.07.2014, 07:08:41
Post #2





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


100 zapytań nieoptymalne? Ja w podobny sposób musiałem zaktualizować 700000 rekordów codziennie co nam dawało 700000*8zapytań/rekord. Trwało to 45 min, więc twoje 100 to jest pierdnięcie

Ten post edytował Pyton_000 3.07.2014, 07:10:41
Go to the top of the page
+Quote Post
mmmmmmm
post 3.07.2014, 07:59:51
Post #3





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


SELECT możesz połączyć z INSERT IGNORE w jedno zapytanie.
Unikalne pary zrobisz albo poprzez DISTINCT, albo poprzez GROUP BY. Dla ciebie to pierwsze.
W MySQL używa się ` zamiast ' - te drugioe służą do czegoś innego.
Go to the top of the page
+Quote Post
@rtur
post 3.07.2014, 08:37:41
Post #4





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

Ostrzeżenie: (0%)
-----


Wydawało mi się to mało optymalne, ale faktycznie Pyton_000, przy Twoim moje 100 to pierdnięcie smile.gif,

Nie wiem czy dobrze kombinuję, ale może zapytanie $sqlQuery1 zmienić w pętli na
  1. INSERT IGNORE INTO 'Wykonawcy' (WykonawcaNazwa) VALUES ($wykonawca[1]),($wykonawca[2]), .... , ($wykonawca[20]);
i 20 zapytań zmieni się w jedno? smile.gif

Jak mogę dodać tylko unikalne zestawy z zapytania $sqlQuery3, czy tylko poprzez dodanie wcześniej zapytania
  1. $sqlQuery4 = SELECT 'UtworID' FROM 'utwory' WHERE 'WykonawcaID'='$WykonawcaID' AND UtworTytul LIKE '$utwor'
potem jeśli 0 rekordów to wykonać zapytanie $sqlQuery3 ale już niekoniecznie z ignore?

Cytat(mmmmmmm @ 3.07.2014, 08:59:51 ) *
Unikalne pary zrobisz albo poprzez DISTINCT, albo poprzez GROUP BY. Dla ciebie to pierwsze.

Z tym sobie już chyba poradziłem dodając
  1. UNIQUE KEY `WykonawcaID_UtworTytul` (`WykonawcaID`,`UtworTytul`)
do tabeli Utwory

Ten post edytował @rtur 3.07.2014, 08:39:14


--------------------
Artur
Go to the top of the page
+Quote Post
mmmmmmm
post 3.07.2014, 09:38:00
Post #5





Grupa: Zarejestrowani
Postów: 1 421
Pomógł: 310
Dołączył: 18.04.2012

Ostrzeżenie: (0%)
-----


$sqlQuery1 = "insert ignore into `Wykonawcy` (WykonawcaNazwa) values ($wykonawca)";
Robisz query. Pobierasz mysql_insert_id() albo coś podobnego - zależy z czego korzystasz. Do zmiennej $wykonawca
Wtedy:
$sqlQuery2 = select 'WykonawcaID' from 'Wykonawcy' where 'WykonawcaNazwa' like '$wykonawca'; // wynik tego zapytania przypisujemy do zmiennej $WykonawcaID
już ci nie jest potrzebne

$sqlQuery3 = "insert ignore into `Utwory` (WykonawcaID, UtworTytul) values (WykonawcaID, '$utwor')"; // no właśnie, jak tu dodać tylko unikalne zestawy WykonawcaID, UtworTytul?
Już sobie prawie poradziłeś z unikalnością. Ale to jest bez sensu. Bo nie patrzysz, co coś już jest, tylko na chama usiłujesz dodać... Tak się nie robi.
I podobnie jak wyżej: query, insert_id. DO zmiennej $utworID
I to poniżej juz niepotrzebne.
$sqlQuery4 = select 'utworID' from 'utwory' where 'WykonawcaID'='$WykonawcaID' and UtworTytul like '$utwor' // wynik tego zapytania przypisujemy do zmiennej $UtworID

$sqlQuery5 = "insert ignore into `Tracklista` (KiedyGrane, UtworID) values ('$data', $UtworID)";

koniec
Go to the top of the page
+Quote Post
@rtur
post 3.07.2014, 11:20:08
Post #6





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

Ostrzeżenie: (0%)
-----


Cytat(mmmmmmm @ 3.07.2014, 10:38:00 ) *
$sqlQuery1 = "insert ignore into `Wykonawcy` (WykonawcaNazwa) values ($wykonawca)";
Robisz query. Pobierasz mysql_insert_id() albo coś podobnego - zależy z czego korzystasz. Do zmiennej $wykonawca

dodałem 1 rekord przeszło ok przypisało do zmiennej $UtworID prawidłowe ID, dodałem ten sam rekord raz jeszcze, (nie dodał się bo już jest) i zmienna $UtworID dostała wartość 0 więc chyba coś nie tak robię, tylko co?

Ten post edytował @rtur 3.07.2014, 11:52:38


--------------------
Artur
Go to the top of the page
+Quote Post
Pyton_000
post 3.07.2014, 11:53:33
Post #7





Grupa: Zarejestrowani
Postów: 8 068
Pomógł: 1414
Dołączył: 26.10.2005

Ostrzeżenie: (0%)
-----


Dobrze robisz, po prostu rekord nie został dodany (INSERT IGNORE) dlatego zwróciło 0.

Zapisuj sobie w tablicy ID już dodanych rekordów i dane tak aby kolejne zapytania mogły być sprawdzane w tablicy. Jak nie ma to Insert, a jak jest to weź ID z tablicy. To zredukuje ilość zapytań o ten sam rekord
Go to the top of the page
+Quote Post
@rtur
post 1.08.2014, 21:39:22
Post #8





Grupa: Zarejestrowani
Postów: 254
Pomógł: 3
Dołączył: 23.02.2006

Ostrzeżenie: (0%)
-----


Musiałem temat porzucić na chwile, ale już do niego wracam, @Pyton_000 mówisz o pobieraniu do tablicy id i danych już dodanych do tablicy podczas aktualnego odpalenia skryptu, czy ogólnie id i dane wszystkich które już są w bazie? W tej chwili w tabelach mam średnio 10 000 rekordów, a może pobierać dane poprzez where utwor like tytul1 or utwor like tytul2 itd... wynik wrzucić w tablice porównać obie tablice wrzucić w tabele to czego nie ma w pierwszej....

Ten post edytował @rtur 1.08.2014, 21:41:01


--------------------
Artur
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 31.07.2025 - 07:44