[PHP] Insert Array in table

Pagina: 1
Acties:
  • 100 views sinds 30-01-2008
  • Reageer

Onderwerpen


Acties:
  • 0 Henk 'm!

  • djack
  • Registratie: September 2002
  • Laatst online: 11-11-2024
Ik heb een beetje een klein probleem.
Ben met een project bezig om software distributie te gaan doen.

Nu om het laden van de software een beke te kunnen sturen naar welk systeem (of systemen) hij moet gestuurd worden heb ik een selectie
All ->>> Gaat dan alle systemen in de systeem table nemen
Hostgroup ->>> Hier kan je dan selecten naar welke hostgroup je wil laden (elk systeem hangt aan een hostgroup)
Hosts ->>> Hier kan je individuele hosts gaan selecteren.
JSelectedHosts[ Belgium, Nederland, TestLab] per hostgroup
oefwel JSelectedHosts[ serverA, ServerB] per host

Nu de uitkomst van de twee laatste is een array.
Kan ik deze array volledig inde db steken ??? [MYSQL] en hoe, ik krijg altijd Array weer.
Of moet ik zo iets meer doen?
<code>
$amount = count($_POST['JSelectHost']);
$i=0;
while ($i < $amount)
{
$HostT = $_POST['JSelectHost'][$i] ;
$Hosts = "$Hosts:$HostT";
$i++;
}
</code>

Met bovenstaande code moet ik dan nadien een explode doen maar daar geeft hij element 0 leeg weer, in weze geen probleem vermits ik dan nadien wel kan ingnoren maar toch.

Is er een slummere manier om dit op te lossen

Because Great minds Think alike


Acties:
  • 0 Henk 'm!

  • Kippenijzer
  • Registratie: Juni 2001
  • Laatst online: 26-08 09:08

Kippenijzer

McFallafel, nu met paardevlees

Ik meen dat de functies serialize en unserialize (zie php manual) hiervoor meestal worden aangeraden

Acties:
  • 0 Henk 'm!

Verwijderd

Ik denk dat je nog maar eens terug moet naar het eerste hoofdstuk over normaliseren. Iets als "host1:host2:host3" opslaan in een relationele database hoort gewoon niet.

Zo moet het niet:
code:
1
2
3
4
5
6
7
8
+----------------------------------+
| hostgroup                        |
+----+---------+-------------------+
| id | name    | hosts             |
+----+---------+-------------------+
|  1 | groep A | host1:host2:host3 |
|  2 | groep B | host4:host5       |
+----+---------+-------------------+

En zo wel:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+--------------+
| hostgroup    |
+----+---------+
| id | name    |
+----+---------+
|  1 | groep A |
|  2 | groep B |
+----+---------+

+-----------------------+
| host                  |
+----+----------+-------+
| id | group_id | name  |
+----+----------+-------+
|  1 |        1 | host1 |
|  2 |        1 | host2 |
|  3 |        1 | host3 |
|  4 |        2 | host4 |
|  5 |        2 | host5 |
+----+----------+-------+

Sowieso kun je ook even kijken naar de foreach construct in PHP, dat scheelt je wat gedoe met arrays. En jouw specifieke probleem ontstaat uiteraard omdat je "serialized" array altijd begint met een dubbelepunt.

Ik zou het nooit gebruiken omdat je database ontwerp niet klopt, maar je PHP code had als volgt kunnen zijn:
PHP:
1
2
3
4
5
$hosts = '';
foreach ( $_POST [ 'JSelectHost' ] as $host ) {
   $hosts .= ':' . $host;
}
$hosts = substr ( $hosts, 1 );

Acties:
  • 0 Henk 'm!

  • djack
  • Registratie: September 2002
  • Laatst online: 11-11-2024
De tabel is zoals het hoort. jou tweede voorbeeld hoor.
Ik zit met een paar denkfoutjes over hoe het op te slaan in de joblist.
In de joblist moet ik geen groepnamen opslaan maar group id's, what was i thinking :-)

Even een paar dingens herzien :-)

Because Great minds Think alike


Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

Verwijderd schreef op zaterdag 16 juli 2005 @ 11:40:
Ik denk dat je nog maar eens terug moet naar het eerste hoofdstuk over normaliseren. Iets als "host1:host2:host3" opslaan in een relationele database hoort gewoon niet.
Hangt er vanaf, als mijn 2de tabel 500.000.000 records groot zou worden dan heb ik worst aan 'normaliseren'.

PHP:
1
implode(":", myarray)

[ Voor 5% gewijzigd door TheBorg op 16-07-2005 13:45 ]


Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

TheBorg schreef op zaterdag 16 juli 2005 @ 13:44:
Hangt er vanaf, als mijn 2de tabel 500.000.000 records groot zou worden dan heb ik worst aan 'normaliseren'.

PHP:
1
implode(":", myarray)
Ja joh, dat zoekt snel. ;)

djack, zou je in het vervolg als je code post, deze tussen [code] of [code=taal]-tags willen zetten? :)

Over je probleem: je zal zelf queries in elkaar moeten knutselen, dit kan niet in één keer met een bepaalde functie ofzo. Een foreach waarbij je voor elk record een insert query doet lijkt me te doen wat je wil.

Overigens vraag ik me af waarom je die hosts aan elkaar wil zetten, en meteen daarna praat over uit elkaar halen met explode. Je hebt het toch al in een array staan? Als je eerst een implode doet, en daarna een explode, dan heb je effectief natuurlijk niets uitgehaald. Bovendien snap ik niet wat je aan waarden als host1:host2:host3:enz hebt als je databasemodel verder wel genormaliseerd is.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

Verwijderd

TheBorg schreef op zaterdag 16 juli 2005 @ 13:44:

Hangt er vanaf, als mijn 2de tabel 500.000.000 records groot zou worden dan heb ik worst aan 'normaliseren'.
En wat zou jouw oplossing dan zijn, oh machtige database goeroe? _/-\o_

Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

Verwijderd schreef op zaterdag 16 juli 2005 @ 16:16:
[...]

En wat zou jouw oplossing dan zijn, oh machtige database goeroe? _/-\o_
Ik ben verre van een database goeroe. :P

Hier bijvoorbeeld op tweakers.net heeft iedereen een 'buddy list'. Ik weet niet of er een maximum is verbonden aan het aantal buddies, maar als je ze in een tabel wil zetten dan krijg je een tabel met een enorm aantal rijen of kolommen. Gezien er geen complexe zoekmogelijkheden etc. nodig zijn is het mijns inziens performance wise wijs om ze gewoon CSV of piped (|) in één cel te gooien (bij de rest van de user info (username/password/adres/etc.)).

Acties:
  • 0 Henk 'm!

  • kmf
  • Registratie: November 2000
  • Niet online

kmf

Tijdens de laatste database-modules op de hogeschool werd me geleerd dat redundantie, verticaal of horizontaal splitsen van een tabel, en/of een stapje terug met normaliseren wel een goede prijs kan zijn voor performance.

Als die hosts-regel in dit geval maar een keer per maand of zo wordt uitgelezen en 1 op 1 uitgespuugd in een bestand of op het scherm, dan kan het best nuttig zijn om zo'n "slechte" model aan te houden.

One thing's certain: the iPad seriously increases toilet time.. tibber uitnodigingscode: bqufpqmp


Acties:
  • 0 Henk 'm!

Verwijderd

TheBorg schreef op zaterdag 16 juli 2005 @ 17:34:
Ik ben verre van een database goeroe. :P

Hier bijvoorbeeld op tweakers.net heeft iedereen een 'buddy list'. Ik weet niet of er een maximum is verbonden aan het aantal buddies, maar als je ze in een tabel wil zetten dan krijg je een tabel met een enorm aantal rijen of kolommen. Gezien er geen complexe zoekmogelijkheden etc. nodig zijn is het mijns inziens performance wise wijs om ze gewoon CSV of piped (|) in één cel te gooien (bij de rest van de user info (username/password/adres/etc.)).
Ik kan je gerust vertellen dat dat onzin is. Misschien is het voor je gevoel sneller of handiger, dat is gewoon niet het geval.
Iedere tabel die voldoet aan de minimale eisen die aan een relatie worden gesteld, is automatisch in eerste normaalvorm. Volledigheidshalve noemen we deze eisen nog eens: alle velden in de tabel moeten enkelwaardig zijn...
bron: Leerboek Databases, ISBN 90 395 0902 6, had ik nog liggen ivm. voormalige opleiding

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

athlonkmf schreef op zaterdag 16 juli 2005 @ 17:52:
Tijdens de laatste database-modules op de hogeschool werd me geleerd dat redundantie, verticaal of horizontaal splitsen van een tabel, en/of een stapje terug met normaliseren wel een goede prijs kan zijn voor performance.

Als die hosts-regel in dit geval maar een keer per maand of zo wordt uitgelezen en 1 op 1 uitgespuugd in een bestand of op het scherm, dan kan het best nuttig zijn om zo'n "slechte" model aan te houden.
In gevallen als dit is dat niet nodig. Het betreft geen complexe tabellen met veel data erin, alleen een die wat ID's aan elkaar linkt. Denormaliseren door berekenbare data toch op te slaan komt wel vaker voor; neem bijvoorbeeld je postcount hier op GoT. Die is makkelijk te berekenen met een COUNT(), maar dat is zo zwaar voor de database, dat het rendabeler is om de postcount gewoon op te slaan. :)

Ik zou in dit geval in elk geval niet denormaliseren. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • kmf
  • Registratie: November 2000
  • Niet online

kmf

-NMe- schreef op zaterdag 16 juli 2005 @ 19:19:
[...]

In gevallen als dit is dat niet nodig. Het betreft geen complexe tabellen met veel data erin, alleen een die wat ID's aan elkaar linkt. Denormaliseren door berekenbare data toch op te slaan komt wel vaker voor; neem bijvoorbeeld je postcount hier op GoT. Die is makkelijk te berekenen met een COUNT(), maar dat is zo zwaar voor de database, dat het rendabeler is om de postcount gewoon op te slaan. :)

Ik zou in dit geval in elk geval niet denormaliseren. :)
Ik heb het total views en andere stats van mijn gallery-in-ontwikkeling juist uit de tabellen weggetrokken en in een soort stats-tabel gestopt. Hoewel ik innodb gebruik, wil ik namelijk zelfs rowlevel-locks vermijden (en misschien dat ooit iemand met myisam het gaat gebruiken) :)

Maar ook de bijna nooit veranderende data zoals categories, albums (in dit geval de hosts?) redundant opslaan als een array in een cachetable en dan uitpakken is ook wel een leuke performance boost. 1 select in plaats van meerdere joins en je doet er toch niks met de data in plaats van alles uitspugen op het scherm.

De keuze van zulke dingen is inderdaad iets dat je goed moet gaan overwegen in praktijk, vandaar ook dat pas aan het einde van mijn opleiding mij dit werd aangeleerd.

:Y)

One thing's certain: the iPad seriously increases toilet time.. tibber uitnodigingscode: bqufpqmp


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

TheBorg schreef op zaterdag 16 juli 2005 @ 17:34:
Hier bijvoorbeeld op tweakers.net heeft iedereen een 'buddy list'. Ik weet niet of er een maximum is verbonden aan het aantal buddies, maar als je ze in een tabel wil zetten dan krijg je een tabel met een enorm aantal rijen of kolommen. Gezien er geen complexe zoekmogelijkheden etc. nodig zijn is het mijns inziens performance wise wijs om ze gewoon CSV of piped (|) in één cel te gooien (bij de rest van de user info (username/password/adres/etc.)).
en vervolgens per user uit die "array" een query doen om de gegevens van die user op te vragen zoals de nickname etc? Of gooi je die info er ook meteen bij, lekker makkelijk :Y)
Als dat nou geen verspilling is van ruimte weet ik het ook niet meer :o
Een database (en ja MySQL ook) heeft over het algemeen weinig tot geen problemen bij dergelijke grote tabellen, zeker niet als je indexen goed staan. Daarnaast is het eenvoudiger te beheren.

Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

Ik ga niet zeggen dat ik het beter weet, en al helemaal niet dat ik verstand heb van databases. :P
Maar ik denk gewoon even logische na:
Erkens schreef op zondag 17 juli 2005 @ 00:24:
en vervolgens per user uit die "array" een query doen om de gegevens van die user op te vragen zoals de nickname etc? Of gooi je die info er ook meteen bij, lekker makkelijk :Y)
Dat probleem heb je altijd, of je ze nou in één cel gooit of in een tabel. Of mis ik soms iets? :?
Daarbij staat er ook de tijd bij wanneer een user voor het laatst is ingelogd, dus die query heb je zowiezo nodig.
Als dat nou geen verspilling is van ruimte weet ik het ook niet meer :o
Kleiner dan in één cel gooien kan echt niet. En je hebt één query minder nodig.
Een database (en ja MySQL ook) heeft over het algemeen weinig tot geen problemen bij dergelijke grote tabellen, zeker niet als je indexen goed staan. Daarnaast is het eenvoudiger te beheren.
Das mooi natuurlijk. En het is inderdaad eenvoudiger te beheren.

Het is misschien een beetje offtoppic, maar kan iemand mijn dan vertellen wat in dit geval WEL de juiste structuur is? Of staan de beste stuurlui aan wal en is er alleen commentaar op een array in een cel douwen. ;)

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

TheBorg schreef op zondag 17 juli 2005 @ 00:48:
Dat probleem heb je altijd, of je ze nou in één cel gooit of in een tabel. Of mis ik soms iets? :?
Daarbij staat er ook de tijd bij wanneer een user voor het laatst is ingelogd, dus die query heb je zowiezo nodig.
ooit van een join gehoord :?
Kleiner dan in één cel gooien kan echt niet. En je hebt één query minder nodig.
zelfde: ooit van een join gehoord :?
Vergeet niet de hoeveelheid meuk die je in die cel gooit, en wat een overhead je krijgt als sommige users weinig of juist enorm veel "buddies" hebben.
Het is misschien een beetje offtoppic, maar kan iemand mijn dan vertellen wat in dit geval WEL de juiste structuur is? Of staan de beste stuurlui aan wal en is er alleen commentaar op een array in een cel douwen. ;)
ik zie dat er al een goed voorbeeld staat in dit topic ;)

Acties:
  • 0 Henk 'm!

  • jochemd
  • Registratie: November 2000
  • Laatst online: 24-08 12:31
TheBorg schreef op zondag 17 juli 2005 @ 00:48:

Kleiner dan in één cel gooien kan echt niet.
Dat hangt er van af wat de overhead van het datatype is. Om een extreem voorbeeld te nemen: als je je MySQL database voor de veiligheid gaat clusteren met NDB dan wordt elk veld ongeacht de inhoud minimaal 32 kB omdat het datatype die fixed size heeft.
Het is misschien een beetje offtoppic, maar kan iemand mijn dan vertellen wat in dit geval WEL de juiste structuur is? Of staan de beste stuurlui aan wal en is er alleen commentaar op een array in een cel douwen. ;)
De juiste oplossing met MySQL is al lang gegeven.

Een array in een cel duwen is overigens niet noodzakelijkerwijs absoluut fout. Maar neem dan wel eerst een database die een Array datatype heeft. Bijvoorbeeld Oracle heeft een 'nested table' datatype waar dit best mee kan (IIRC is dat geimplementeerd als een referentie naar een apart opgeslagen tabel dus de array elementen zijn alsnog afzonderlijk indexeerbaar met een normale B-tree). PostgreSQL heeft een Array datatype (dat standaard ook een echt inline datatype is maar via een GiST index alsnog indexeerbaar is). En zo zijn er vast nog wel meer databases waarin een Array beter ondersteund wordt dan in MySQL.

Acties:
  • 0 Henk 'm!

  • djluc
  • Registratie: Oktober 2002
  • Laatst online: 14:28
Als je dit dan toch doet zou ik nog eerder een cache-veld gebruiken. Je maakt dus een nette structuur zoals Cheatah heeft gedaan:
SQL:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
+--------------+
| hostgroup    |
+----+---------+
| id | name    |
+----+---------+
|  1 | groep A |
|  2 | groep B |
+----+---------+

+-----------------------+
| host                  |
+----+----------+-------+
| id | group_id | name  |
+----+----------+-------+
|  1 |        1 | host1 |
|  2 |        1 | host2 |
|  3 |        1 | host3 |
|  4 |        2 | host4 |
|  5 |        2 | host5 |
+----+----------+-------+

Alleen voeg je nu een veld cache toe aan de hostgroup tabel. Daarin zet je bijvoorbeeld serialized de array of een csv lijst in. Je zorgt er uiteraard voor dat je cache geupdate wordt bij aanpassingen. Bijvoorbeeld middels een trigger. Dan vind ik het niet erg omdat je toch alle data op correcte en doorzoekbare wijze hebt opgeslagen.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

Waarom zou je? Je wint er niets mee. Je kan je data snel genoeg (in een fractie van een seconde) ophalen wanneer je een goed datamodel gebruikt. Snelheid is hier helemaal geen issue, aangezien dit wel de meest simpele vorm van een koppeltabel ooit is. Er zal wel heel veel data in moeten staan wil dat traag worden.

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

Dat het niet netjes is om een array in een field te gooien daar ben ik het wel mee eens. Een join in de situatie van djack is nog te doen.

code:
1
$sql = mysql_query("SELECT host.id, hostgroup.name, host.name FROM host LEFT JOIN hostgroup ON host.groupid = hostgroup.id");

Maar wat als het aantal kolommen heel groot word?

Van:
code:
1
2
3
4
5
6
7
8
9
10
11
+---------------------------------+
| gebruikers                      |
+----+---------+------------------+
| id | name    | Laatste Bezoek   |
+----+---------+------------------+
|  1 | TheBorg | 26-06-2005 15:14 |
|  2 | djluc   | 17-07-2005 15:40 |
|  3 | -NMe-   | 25-06-2005 19:47 |
|  4 | Erkens  | 26-06-2005 15:14 |
|  5 | jochemd | 29-06-2005 19:47 |
+----+---------+------------------+


En:
code:
1
2
3
4
5
6
7
8
9
10
11
+------------------------------------------------+
| buddies                                        |
+----+----------+----------+----------+----------+
| id | buddy001 | buddy002 | buddyEtc | buddy100 |
+----+----------+----------+----------+----------+
|  1 |        2 |        3 |        5 |          |
|  2 |        4 |        2 |        3 |          |
|  3 |        5 |        1 |        2 |          |
|  4 |        3 |        4 |        5 |          |
|  5 |        1 |        2 |        3 |          |
+----+----------+----------+----------+----------+



Naar:
code:
1
2
3
4
5
6
7
8
9
+-----------------------------------+
| Buddies van TheBorg               |
+-----+----------+------------------+
|  id | name     | Laatste Bezoek   |
+-----+----------+------------------+
|   2 | djluc    | 17-07-2005 15:40 |
|   3 | -NMe-    | 25-06-2005 19:47 |
|   5 | jochemd  | 29-06-2005 19:47 |
+-----+----------+------------------+


Hoe doen we dat zonder een query per buddy uit te voeren?

Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

je hebt voor die buddies toch gewoon een tabel:

+--------+---------+
| UserID | BuddyID |
+--------+---------+
+     1  +      2  +
+     1  +      3  +
+     1  +      5  +
+     2  +      1  +
+     4  +      2  +
+--------+---------+


Wat gewoon met een mooie join snel uit te lezen is :)

Acties:
  • 0 Henk 'm!

  • TheBorg
  • Registratie: November 2002
  • Laatst online: 20-09 18:24

TheBorg

Resistance is futile.

Erkens schreef op zondag 17 juli 2005 @ 17:03:
je hebt voor die buddies toch gewoon een tabel:

Wat gewoon met een mooie join snel uit te lezen is :)
Je maakt dus per buddy een nieuwe rij? Dan heeft de tweakers buddy list wel miljoenen rijen.
Maar dan werkt het inderdaad.

Acties:
  • 0 Henk 'm!

  • NMe
  • Registratie: Februari 2004
  • Laatst online: 09-09 13:58

NMe

Quia Ego Sic Dico.

TheBorg schreef op zondag 17 juli 2005 @ 17:14:
Je maakt dus per buddy een nieuwe rij? Dan heeft de tweakers buddy list wel miljoenen rijen.
Maar dan werkt het inderdaad.
Miljoenen rijen lijkt me geen enkel probleem. Er staat niet veel meer dan een paar ID'tjes in. Sowieso ben je met jouw systeem gelimiteerd aan een maximaal aantal buddies, waar je met een kruistabel oneindig veel buddies kan hebben. :)

'E's fighting in there!' he stuttered, grabbing the captain's arm.
'All by himself?' said the captain.
'No, with everyone!' shouted Nobby, hopping from one foot to the other.


Acties:
  • 0 Henk 'm!

  • Erkens
  • Registratie: December 2001
  • Niet online

Erkens

Fotograaf

TheBorg schreef op zondag 17 juli 2005 @ 17:14:
[...]


Je maakt dus per buddy een nieuwe rij? Dan heeft de tweakers buddy list wel miljoenen rijen.
Maar dan werkt het inderdaad.
maar die miljoenen rijen kunnen veel sneller zijn en bovendien veel makkelijke met verwijderen en inserten. Het opvragen doe je met een simpele join wat MySQL prima kan, want je gebruikt gewoon de primary keys (op deze tabel ligt de primary key dus ook op _beide_ velden).

Acties:
  • 0 Henk 'm!

  • pjonk
  • Registratie: November 2000
  • Laatst online: 20-09 21:53
Ik had een tijd geleden een tabel voor een searchengine gemaakt. In de tabel stonden keywords die weer linken naar een DocumentID. In de tabel stonden Nederlandse en Engelse worden in totaal zo'n 40.000. Het doorzoeken van de tabel was evengoed bloed snel simpelweg doordat ik een index op het KeyWord veld had gedefineerd. Zorg er in jouw geval dus gewoon voor dat je een index heb liggen op je BuddyID kolom.

It’s nice to be important but it’s more important to be nice

Pagina: 1