probleem insert / update database
ik heb een database met een tabel genaamd "pagina" die weer bestaat uit de volgende 2 velden :
- omschrijving
- titel
er is echter ook een 3de veld in de tabel pagina genaamd "combi" en deze bestaat uit omschrijving + titel.
door een domme fout heb ik heel het combi veld leeg gemaakt en aangezien de tabel bestaat uit meer dan 5000 items is het niet te doen om alles handmatig aan te passen.
Nu wil ik dit graag mbv php en mysql oplossen en ben reeds bezig geweest met een script.
het is de bedoeling dat alle velden uit de database worden gehaald en stuk voor stuk gecontroleerd, samengevoegd en geupdate worden zodat daarna automatisch het combi veld word aangemaakt.
ik hoop dat ik een beetje duidelijk ben. Dit is de code die ik gemakt heb, echter werkt hij dus niet...hij geeft geen foutmeldingen, maar geeft gewoonweg niets weer.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
<?php
if( isset($_POST['submit']) )
{
ini_set('display_errors',1);
error_reporting(E_ALL);
/* Connect to the database: */
mysql_pconnect("****","****","****")
or die("ERROR: Could not connect to database!");
mysql_select_db("****");
$res = mysql_query("SELECT * FROM page");
while ($row = mysql_fetch_assoc($res))
{
/* velden: */
$page_id = $row['page_id'];
$omschrijving = addslashes( $row['omschrijving']);
$titel = addslashes( $row['titel']);
/* haal alle woorden eruit: */
preg_match_all("/(\b[\w+]+\b)/",$omschrijving,$words1);
preg_match_all("/(\b[\w+]+\b)/",$titel,$words2);
$words = array_merge($words1, $words2);
/* doorzoek alle velden op woorden en voeg ze toe in de database: */
for ($i = 0; isset($words[$i]); $i++)
{
for ($j = 0; isset($words[$i][$j]); $j++)
{
/* bestaat het huidige woord al ? */
$cur_word = addslashes( strtolower($words[$i][$j]) );
$result = mysql_query("SELECT word_id FROM word
WHERE word_word = '$cur_word'");
$row = mysql_fetch_array($result);
if( $row['word_id'] )
{
/* zo ja, gebruik het oude word_id: */
$word_id = $row['word_id'];
}
else
{
/* zo nee,maak een nieuwe: */
mysql_query("INSERT INTO word (word_word) VALUES (\"$cur_word\")");
$word_id = mysql_insert_id();
}
/* voeg het aantal keer dat een woord voorkomt toe in de database: */
mysql_query("INSERT INTO occurrence (word_id,page_id)
VALUES ($word_id,$page_id)");
}
}
}
}
}
?>
if( isset($_POST['submit']) )
{
ini_set('display_errors',1);
error_reporting(E_ALL);
/* Connect to the database: */
mysql_pconnect("****","****","****")
or die("ERROR: Could not connect to database!");
mysql_select_db("****");
$res = mysql_query("SELECT * FROM page");
while ($row = mysql_fetch_assoc($res))
{
/* velden: */
$page_id = $row['page_id'];
$omschrijving = addslashes( $row['omschrijving']);
$titel = addslashes( $row['titel']);
/* haal alle woorden eruit: */
preg_match_all("/(\b[\w+]+\b)/",$omschrijving,$words1);
preg_match_all("/(\b[\w+]+\b)/",$titel,$words2);
$words = array_merge($words1, $words2);
/* doorzoek alle velden op woorden en voeg ze toe in de database: */
for ($i = 0; isset($words[$i]); $i++)
{
for ($j = 0; isset($words[$i][$j]); $j++)
{
/* bestaat het huidige woord al ? */
$cur_word = addslashes( strtolower($words[$i][$j]) );
$result = mysql_query("SELECT word_id FROM word
WHERE word_word = '$cur_word'");
$row = mysql_fetch_array($result);
if( $row['word_id'] )
{
/* zo ja, gebruik het oude word_id: */
$word_id = $row['word_id'];
}
else
{
/* zo nee,maak een nieuwe: */
mysql_query("INSERT INTO word (word_word) VALUES (\"$cur_word\")");
$word_id = mysql_insert_id();
}
/* voeg het aantal keer dat een woord voorkomt toe in de database: */
mysql_query("INSERT INTO occurrence (word_id,page_id)
VALUES ($word_id,$page_id)");
}
}
}
}
}
?>
het insert gedeelte etc klopt, alleen zoek ik nu dus een goede manier om elk item (id) op te halen uit de database en dus voor elke regel het combiveld te genereren en te inserten in de database.
kan dit met een while lus of moet ik dan iets totaal anders doen ?
ideeen, suggesties, tips etc zijn echt allemaal van harte welkom
je kan bij het uitlezen de velden samenvoegen, ook in SQL.
Het is dus totaal niet nodig om de data dubbel op te slaan dus..
Gewijzigd op 01/01/1970 01:00:00 door Terence Hersbach
Het is in dit geval wel degelijk noodazakelijk. Normaliter word tijdens de eerste insert berekend hoe vaak ieder woord voorkomt in de diverse velden en dit word geregistreerd op verschillende manier om zo betere resultaten te genereren voor de zoekoptie.
Het is dus van groot belang dat het 3de veld word aangemaakt. het is dus niet zo dat de waarde dubbel word opgeslagen, maar meer een berekening van deze waarden !!
maar heeft iemand tips over hoe ik elke regel kan inserten ? is bijvoorbeeld deze while lus goed of moet ik iets anders gebruiken '?
Het slaat helemaal nergens op om gegevens uit 2 verschillende kolommen, met 2 verschillende soorten data, nog eens samen in 1 kolom te gaan zetten. Je wilt ons toch niet gaan wijsmaken dat de hele wereld al zo'n 30 tot 40 jaar op een verkeerde manier aan het normaliseren is? Of wel dan?
Ga je eens verdiepen in normalisatie en sla de handleiding van MySQL er eens op na hoe je op een slimme manier de beste zoekresultaten kunt krijgen. Vervolgens gooi je jouw datamodel de deur uit en ga je een betere maken.
Veel succes!
je begrijpt het volgens mij helemaal verkeerd. Het is (in mijn ogen) helemaal geen slecht datamodel, en ik sla nergens dubbele waarden op.
ik zou de berekening inderdaad ook in php kunnen doen nadat ik de waarden uit de database haal,maar aangezien deze code op alle onderdelen van mijn site gebruikt word kost dit veels te veel ruimte terwijl het in de database maar weinig ruimte en laadtijd kost....beter, sneller en handiger dus.
voorbeeld :
omschrijving 1 bestaat uit : fiets en auto
titel 1 bestaat uit : fiets en brommer
omschrijving 2 bestaat uit : fiets en step
titel 2 bestaat uit : fiets en fiets
het volgende word dan opgeslagen :
combi (woord) :
- fiets (id+)
- auto (id+)
- brommer (id+)
- step (id+)
komt fiets dus in 3000 velden voor dan slaat hij het woord fiets maar 1x op en schrijft alleen een code weer voor de id´s zodat er bij een zoekopdracht meteen gezien word in welke id´s het word fiets voorkomt en hoe vaak deze voorkomt.
niets mis mee dus en heeft in dit geval ook niets met normaliseren te maken.
edit :
iedereen toch bedankt ondanks de opgebouwde kritiek waar ik het niet mee eens was ha ha.
het is me inmiddels zelf gelukt. er stond 1 haakje teveel in de code
Gewijzigd op 01/01/1970 01:00:00 door Robin
fulltext search uitvoeren? Die kan ook meteen sorteren op relevantie en is toch vrij snel.
Kan je voor het zoeken op woorden niet beter een Zie de oplossing van Jelmer voor de juiste aanpak.
met fulltext search geeft hij wel een score aan de resultaten, maar indien je op meerdere zoektermen zoekt is de relevantie niet 100% kloppend. ook zijn er beperkingen met bijvoorbeeld zoektermen die maar 3 letters bevatten etc.
op mijn manier word er naar alle zoektermen gekeken, en de relevantie van deze termen adhv alle velden. daarbij word aan elke veld ook een score gehangen om zo te kunnen bepalen in welk veld een zoekterm wel of niet belangrijk is. de resultaten zijn op deze manier echt stukken beter en veel vergt het niet van je database !!
ik ben met jullie eens dat de database zo wel meer belast word met code, echter heb ik dus de voor en nadelen vergeleken en dit was voor mijn database model de beste oplossing.
Het echte probleem is, en dat geeft niks, dat jouw kennis niet toereikend is om het wel op een goede manier op te lossen. Je hebt nu een werkende work-around waarmee je blijkbaar uit de voeten kunt, maar vergeet niet om hier t.z.t. nog eens naar te kijken. Wanneer je dan meer kennis en kunde in huis hebt, zul je waarschijnlijk alsnog met een betere oplossing komen.
Veel succes!