Jump to content
php.lv forumi

labākā datu struktūra datubāzei vienai


hmnc

Recommended Posts

sveiki.

sorr par stulbu tēmas nosaukumu - nevarēju neko prātīgāku izdomāt... bet nu tas nav svarīgi.

 

tātad jautājums sekojošs. ir tabula ar pieņemsim cilvēkiem. viss oke, bet sākas problēmas - vajag iebakstīt katram cilvēkam klāt viņa aktivitātes (ar checkboxiem).. respektīvi ir php masīvs ar tām aktivitātēm.. un attiecīgi saglabājās tikai indexi.

un tieši tādā pašā veidā ir intereses - masīva indexi.

 

abos šajos brīnumos (aktivitātēs un interesēs) ir iespēja atķeksēt vairākus katram cilvēkam.

tagad jautājiens - kā to visu sagrūzt datubāzē, bet vēl trakāk - atrast pēc attiecīgām aktivitātēm un/vai interesēm (kaut vai tikai pēc viena aktivitāšu/interešu parametra).

 

itkā var taisīt vienu tabulu visam, attiecīgi ielikt atsevišķus laukus tiem diviem brīnumiem, insertot to visu pasākumu vienkārši stringā (kaut vai piemēram [3][6][12][19]) un tad iekš selecta ar LIKE atrast meklējamo.. bet baigais čakars manuprāt sanāks, ja meklēs piemēram no 10`000 cilvēkiem.. iebremzēs.. ne?

 

otrs variants atkal ir taisīt vēl divas papildus tabulas aktivitātēm un interesēm ( respektīvi: person_id | activity_id ) un tad ar kkādiem zamudreniem joiniem vilkt ārā pēc meklējamiem datiem... bet atkal ja padomā - būs uz 10`000 personu ierakstu... un katram tur kādas 5 - 15 intereses un tikpat aktivitātes... sanāks tādas nevājas tabulas, kur domājams joins arī varētu iebremzēt...

 

varbūt ir kāds prātīgāks risinājums... ko tauta iesaka?! :)

 

 

paldies!

Link to comment
Share on other sites

it kaa 2vas tabulas - vienā cilveki(id, ...) otrā saķeksētie chekboxi (cilveka_id, chekboxa_id)

 

un divi selecti

select * from cilveki where id in(1,2,3)
select * from checkboxi where cilveka_id in(1,2,3)

php pusee saliec kopaa, zem katra cilveka sakeksetos chekboxus.

 

imho ja ar 1 selectu un joinu, tad recordsets tiks lieki palielinats atkartojot cilveka tabulas saselektetos laukus tik reizes cik chekboxi sim salikti.

 

+ indexus saliec tabulās.

Edited by v3rb0
Link to comment
Share on other sites

otrs variants atkal ir taisīt vēl divas papildus tabulas aktivitātēm un interesēm ( respektīvi: person_id | activity_id ) un tad ar kkādiem zamudreniem joiniem vilkt ārā pēc meklējamiem datiem... bet atkal ja padomā - būs uz 10`000 personu ierakstu... un katram tur kādas 5 - 15 intereses un tikpat aktivitātes... sanāks tādas nevājas tabulas, kur domājams joins arī varētu iebremzēt...

 

Tieši šis ir vispareizākais!

- datu struktūra atbilst dzīves situācijai

- LIKE vēl vairāk iebremzēs, nekā JOIN

- SQL serveri mūsdienās ir pietiekami gudri lai nooptimizētu visu (PG,SQL,Ora)

 

Kā piemēr

 

$selectedActivities = implode( ',', $_POST['activities'] );
$selectedInterests = implode( ',', $_POST['interests'] );

select distinct A.* from PersonTable A
left join personActivities AT
 ON (...)
left join personInterests AI
 ON (...)
where AT.activityId IN ( $selectedActivities )
AND AI.interestId IN ( $selectedInterests )

Link to comment
Share on other sites

Ir jau vēl viens piegājiens kas paatrina datu atlasi bet briesmīgi sarežģī uzturēšanu (patiesībā var kombinēt ar izvēlēto variantu keshinga nolūkos) un proti ir

tabula users kur analogi no pirmā varianta ir divi lauki user_id | aktivites

 

piem:

1 | 1,4,10,14

2 | 1,3,15

 

un ir tabula aktivitātes activity_id | users

 

1 | 1,2

3 | 2

 

...

 

Attiecigi var ar vienu selectu atlasit visas usera aktivitātes un ar vienu arī tos userus kuriem ir konkrētā aktivitāte.

 

Bet pieņemu mainīt onlainā ar chekboxiem 10k useriem / apendot rewraitot varētu būt sāpīgi, taču ja iespējama datu keshoshana tad regulāri backgroundā updeitojot ar minetajiem joiniem imho var panākt labu rezultātu.

Link to comment
Share on other sites

Uhu, Roze, un kas notiks ja vajag atselektēt pēc 2 checkboxiem, ja ir tie pāsi 10k `useri`??

 

1 | 1,2,....5000 (~5000 cipari + komati)

2 | ... tas pats

 

Un vēl kaut kā `distinct user` stilā jāatgriež ;) Imho šito LIKE strādā kudi lēnāk nekā parasts join-s...

Link to comment
Share on other sites

Nu ja vajag tos jūzerus kam ir abi checkboxi tad varbūt arī neder neder (bet ja vajag uzzināt tikai userus kam ir viens vai otrs checkbox tad gan vienkārši proti resultsetā tikai divi ieraksti no db no aktivitāšu tabulas .. distinctu var panākt izmantojot explodojot tad useru virkni un array_merge un LIKE shini variantā neizmantojas)..

tapēc viennozīmīgi nevar ieteikt labāko/ātrāko risinājumu nezinot visas vajadzības, jo

 

nu pieņemsim ka ir jātlasa ( kā tu saki ) divas aktivitātes un katrai aktivitātei ir piemēram 5000 useri.

Tavā variantā sanāk no DB 2 x 5000 = 10k ieraksti un jaatrod tie useri kas ir gan vienā gan otrā aktivitātē kverija nosacijumi.. nu tjipa kaut kaa kā tā uz bujduj uzrakstot:

 

SELECT cilveka_id FROM checkboxi WHERE aktivitate = 1 AND cilveka_id IN (SELECT cilveka_id FROM checkboxi WHERE aktivitate = 2)

vai arī

SELECT t1.cilveka_id FROM checkboxi AS t1, checkboxi AS t2 WHERE t1.aktivitate = 1 AND t2.aktivitate = 2 AND t1.cilveka_id = t2.cilveka_id

 

Manā variantā sanāk atlasīt tikai divus ierakstus (SELECT useri FROM aktivitates WHERE id = 1 OR id = 2 (OR vispār ir evil)) kur useri laukā vienkārši teksta stringi tālāk tiek izpildīts:

<? array_intersect(explode(',',$row['aktivitate1_useri']),explode(',',$row['aktivitate2_useri'])); ?>

Līdz ar to kamēr neizmēģina ej nu sazini kurš aprij vairāk cpu/mem un kas vēl notiek ja vajag 3,4 vai 20 checkboxus :)

 

 

SQL variantā gan talkā nāk query cache no otras puses ja tabulas aktīvas tas vislaik resetojas un nav nekādas jēgas..

 

Bet tas tā lai dzīve interesentāka :)

Link to comment
Share on other sites

×
×
  • Create New...