Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.

Sinhronizacija MySQL baze

[es] :: MySQL :: Sinhronizacija MySQL baze

[ Pregleda: 2028 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Autor

Pretraga teme: Traži
Markiranje Štampanje RSS

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 871
*.teol.net.



+148 Profil

icon Sinhronizacija MySQL baze03.06.2010. u 19:01 - pre 168 meseci
Pitanje koje cu postaviti zalazi u vise podforuma, ali mi se za konkretan problem ovaj podforum ucinio najpogodniji.

Potrebno je da redovno (svaka 2-3 dana) vrsim sinhronizaciju 4 tabele u MySQL bazi. Od ove 4 tabele, jedna je primarna, a druge 3 su povezane sa njom preko id-a. Mislim da je za samu sustinu stvari nebitno koji su konkretno podaci u tabelama, ono sto je bitno je da postoji zavisnost izmedju tabela.
Podatke koje sinhronizujem dobijam u obliku XML fajla. Svaki XML fajl koji dobijem sadrzi sve informacije (a ne samo promjene, sto bi bilo idealno).
Inicijalno sam napravio PHP skriptu koja cita XML fajl i za svaki unos pravi odgovarajucu INSERT sintaksu za SQL, a zatim ovako generisan fajl pokrenuo kroz MySQL CLI. Kako su sve tabele inicijalno bile prazne, id-ovi su isli sukcesivno od nule, te nije bilo problema prilikom povezivanja preko id-a.

Sada se, kao sto sam napomenuo, javio zahtjev da se tabele moraju redovno sinhronizovati. Ovo ce opet vrsiti neka PHP skripta koju ce redovno pozivati CRON, ili ce se mozda cak i rucno pokretati (zbog nekih problema koji nisu povezani sa temom), uglavnom potrebno je sto je moguce vise automatizovati ovaj proces.

Takodje, jedan od pozeljnih zahteva bi bio da sam PHP kod koji treba da updejtuje bazu ne vrsi nikakvu interakciju sa bazom, vec samo proizvodi rezultujuci SQL kod koji ce kasnije biti importovan kroz Command Line Interface. Tj. PHP kod nema nikakve povratne informacije od baze (kao sto su broj trenutnog id-a u glavnoj tabeli i slicno) i jedini ulaz mu je XML. Razlog za ovo je sto ce se kasnije ova php skripta integrisati u jedan drugi sistem.

Konkretno pitanje je koji bi bio najoptimalniji pristup za sinhronizaciju baze?

Jedino rjesenje koje ja vidim je prilikom svakog novog primanja XML fajla, obrisati sve iz ove 4 tabele i odraditi import od nule. Ovo mi se nikako ne cini optimalno, jer ulazni XML fajl moze imati i po par desetina MB, a glavna tabela trenutno ima oko 30000 redova.

Razmisljao sam i o koristenju UPDATE sintakse, medjutim prilikom nekih testova pokazalo se da ona radi veoma sporo na ovolikom broju redova. Takodje, problem sa UPDATE je da rekordi koji ne postoje u update XML fajlu nece biti uklonjeni iz trenutne baze.

Ako nisam dao dovoljno informacija, to je zato sto sam pokusao da ne idem previse u sirinu.

Hvala na odgovorima






 
Odgovor na temu

stevs986
Nikolic Sladjan
Senior Software Developer
Alterset d.o.o
Beograd

Član broj: 121154
Poruke: 140
*.dynamic.sbb.rs.



+4 Profil

icon Re: Sinhronizacija MySQL baze03.06.2010. u 19:28 - pre 168 meseci
Ne znam zasto bezis od toga da php ima interakciju sa bazom.

Jedina komunikacija bi ti bila da izvuces samo id -eve iz te cetiri tabele. Ostalo je na PHP - u, for,foreach,parsiranje XML -a....

Napravis insert skriptove samo za one kojih nema u bazi...



Ne znam kakva je arhitektura, ali postoji li nacin da xml fajlovi koje dobijas budu vec "pripremljeni" za insert... U smisli, da bi generisao te fajlove mora postojati neki upit nad tim tabelama. Zasto nekom logikom( neka tabela u bazi) ne pamtiti max exportovane id-eve te cetiri tabele i onda kasnije exportovati, generisati... samo od tih pa do kraja.... ?



 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 871
*.teol.net.



+148 Profil

icon Re: Sinhronizacija MySQL baze03.06.2010. u 19:48 - pre 168 meseci
Interakciju sa bazom izbjegavam upravo zbog razloga arhitekture, jer ce se skripta kasnije integrisati sa Joolma komponentom, koja koristi svoje klase za interakciju sa bazom, medjutim ako ne bude drugog nacina mozda i odustanem od ovog zahtjeva. Na kraju krajeva, ako je dobitak veliki, mozda napisem i neku medjuklasu koja ce apstrahovati interakciju sa bazom, ili samo prepravim kod.

XML fajl koji dobijam je statican u smislu da predstavlja dump cijele baze sa kojom se sinhronizujem i ne mogu uticati na njegovo kreiranje, vec ga koristim takvog kakav je.

Ukoliko i primjenim interakciju PHP-a sa bazom, to bi izgledalo nekako ovako:

1. Povucem sve ID-ove iz glavne tabele (oni su jedini referentni)
2. Odradim INSERT za sve ID-ove koji se nalaze u XML fajlu, a ne nalaze u bazi (to su novi podaci)
3. Odradim REMOVE za sve ID-ove koji se nalaze u bazi, ali se ne nalaze u XML fajlu
4. Odradim UPDATE za sve ostale (tj. ID-ove koji se nalaze i u bazi i u XML-u)

Broj 4 iz razloga sto se informacije za vec postojece rekorde mogu mijenjati (jedna od njih je npr. cijena, glavni razlog zasto je i potrebno redovno updejtovanje).

Upravo ovaj broj 4 je problematican, jer UPDATE na ovolikom broju rekorda uzima dosta vremena i resursa na serveru. UPDATE sintaksa koju sam probao ide ovako nekako:
Code:
UPDATE table_name SET col1=$val1, col2=$val2 ... coln=$valn WHERE id = $id
I zatim ima 30000 ovakvih UPDATE naredbi u jednom SQL fajlu. Trebam li pominjati da je ovo veeeomaaa sporo? Postoji li nacin da se ovo dalje optimizuje?

Uporedjivanje postojecih redova sa onim iz XML fajla, pa pravljenje UPDATE sintakse za one koji se razlikuju bi samo prebacilo vecinu posla na PHP, a ne znam da li bi se ista dobilo na performansama.



 
Odgovor na temu

bogdan.kecman
Bogdan Kecman
"specialist"
Oracle
srbistan

Član broj: 201406
Poruke: 15887
*.31.24.217.adsl2.beograd.com.

Sajt: mysql.rs


+2377 Profil

icon Re: Sinhronizacija MySQL baze03.06.2010. u 20:13 - pre 168 meseci
ako ti xml fajl koji dobijas
- uvek sadrzi SVE podatke
- ne sadrzi nikakav unique identifier za svaki slog

najbrze resenje ti je bas to koje si spomenuo, obrises sve i insertujes tih 30K slogova ... to ce da traje par minuta i u svakom slucaju je brze nego da ti "trazis" za svaki slog iz xml-a odgovarajuci u bazi pa ga onda updateujes...

ako XML SADRZI nekakav unique identifier, onda taj identifier treba da koristis kao primarni kljuc (a ne auto increment polje) i onda dalje zavisi od podataka
- ako se podaci "menjaju" - dakle ako slog koji postoji u bazi sada ima neke nove vrednosti - opet ti je brze da odradis drop i rekreiras sve ispocetka
- ako se postojeci podaci ne menjaju nego samo postoje novi - onda mozes da koristis INSERT IGNORE sintaksu i insertujes sve podatke a mysql ce izignorisati one sa vec postojecim unique poljem

obrati paznju da ako radis ovaj insert
1. povecas BULK INSERT BUFFER na mysql-u
2. insertujes podatke BULK a ne jedan po jedan (dakle radis "insert into t1 values (1,1,1,1), (2,2,2,2), (3,3,3,3), (4,4,4,4);" a NE "insert into t1 values (1,1,1,1); insert into t1 values (2,2,2,2); insert into t1 values (3,3,3,3); insert into t1 values (4,4,4,4);" - obrati paznju na max package size ..


 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 871
*.teol.net.



+148 Profil

icon Re: Sinhronizacija MySQL baze03.06.2010. u 23:06 - pre 168 meseci
Imam jedinstveno polje koje mogu koristiti kao primarni kljuc i to ce sigurno olaksati povezivanje ove 4 tabele.

Medjutim, kako se postojeci podaci mogu mijenjati, izgleda da je ipak najefikasnije uraditi clean import svaki put.

Hvala na odgovorima jos jednom.

Pozdrav

 
Odgovor na temu

peromalosutra
Ivan Rajkovic
Software engineer
Luxoft
Berlin

Član broj: 54774
Poruke: 871
*.teol.net.



+148 Profil

icon Re: Sinhronizacija MySQL baze14.06.2010. u 18:24 - pre 168 meseci
Samo mali update nakon sto je vec sve gotovo. :)

Kao sto sam pomenuo u postu iznad, odlucio sam se za clean update i performanse su sasvim zadovoljavajuce. PHP skripta parsira ulazne XML fajlove i generise SQL fajl od nekih 80-ak MB, koji se zatim importuje kroz MySQL CLI.

Fajl je sastavljen od bulk INSERT naredbi, za sad sam stavio da se unosi 10 redova po INSERT naredbi, ali ovo je potpuno konfigurabilno u skripti i moze se postaviti na bilo koju vrijednost. Sam proces updejtovanja MySQL baze traje ispod 10 sekundi, sto mi se cini sasvim zadovoljavajuce. PHP skripta uzima malo vise vremena da isparsira podatke, ali i to nije mnogo (nisam mjerio, ali nije vise od 30-ak sekundi).

Napisao sam ovaj post cisto da otklonim sumnje vezano za vrijeme trajanja, jer sam licno ocekivao da ce to trajati mnogo duze.

edit:

Evo i pravih rezultata mjerenja

Code:
-bash-3.2$ time php parser.php
1567 properties addded from input/c****.xml to out/update.sql
8595 properties addded from input/l***.xml to out/update.sql
1257 properties addded from input/m***.xml to out/update.sql
17873 properties addded from input/r***.xml to out/update.sql

Parsing complete. Total number of parsed rows: 29292.
Use MySQL CLI to import .sql file to database.

real    0m22.996s
user    0m21.010s
sys     0m1.250s






 
Odgovor na temu

[es] :: MySQL :: Sinhronizacija MySQL baze

[ Pregleda: 2028 | Odgovora: 5 ] > FB > Twit

Postavi temu Odgovori

Navigacija
Lista poslednjih: 16, 32, 64, 128 poruka.