Data koppelen in mysql uit data-bestand

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Hallo!

Hier heb ik een databestand met een gigantische lijst data

De data is al volgt gestructureerd:
<woord1>|<woord2>|<woord3>

Nu wil ik dit dus in een database hebben maar er moet het volgende mee gebeuren:
woord1 krijgt een ID
en wordt gekoppeld aan woord2
maar woord2 moet ook teruggekoppeld zijn aan woord1

Dus als woord1 bijvoorbeeld sleutel is, en woord2 is bos. Dan moeten zowel sleutel als bos een ID krijgen, maar bij zowel sleutel als bos moet er een foreignkey naar het andere woord worden gelegd.

Nu zit ik een beetje te denken hoe ik dit moet doen een aanpakken. Ga ik elke keer zoeken of woord2 al in de database voortkomt en gooi dan de ID bij woord1 in. Anders voeg woord2 toe en koppel de hele handel. Is dit slim om dit zo te doen? Het gaat wel enorm veel zoekwerk in de database opleveren.

Iemand een idee?

Acties:
  • 0 Henk 'm!

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Verwijderd schreef op dinsdag 02 februari 2010 @ 11:13:
maar bij zowel sleutel als bos moet er een foreignkey naar het andere woord worden gelegd.
Dat vind ik een beetje een vreemde constructie. Waarom een FK naar elkaar?
Verder: kijk eens naar LAST_INSERT_ID() :?

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
RobIII schreef op dinsdag 02 februari 2010 @ 11:25:
[...]

Dat vind ik een beetje een vreemde constructie. Waarom een FK naar elkaar?
Verder: kijk eens naar LAST_INSERT_ID() :?
Oja sorry dat was ik vergeten te vertellen

woord1 moet naar nog meer terugkoppelen
Dus ik heb bijvoorbeeld dit in mijn databestand
sleutel|bos|woord3
sleutel|hark|woord3
sleutel|pan|woord3

dan moeten alle 3 woord2'en terug gekoppeld worden naar sleutel en naar elkaar
maar last_insert_id ken ik nog niet, zal er eens naar kijken

[ Voor 5% gewijzigd door Verwijderd op 02-02-2010 11:31 ]


Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 18-09 12:01
Gaat het om eenmalige import?

If so;
Slim importscript schrijven die per regel door dat bestand heenloopt. Als je een (nieuw) woord tegenkomt sla je deze op in de database en onthoudt je het ID in een Array, voor elk volgend woord kijk je eerst of deze in de Array voorkomt (de key is het woord en de value het ID).

pseudocode (misschien werkt het wel);
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
$words = Array();
$ids = Array();

// Lees elke regel van het bestand in als array item
// FILE_IGNORE_NEW_LINES zorgt ervoor dat laatse item geen nieuw regel karakter bevat
$lines = file('databestand.txt', FILE_IGNORE_NEW_LINES);
foreach($lines as $line) {
   // Split de regel in een array met woorden (woorden zijn gescheiden door |)
   $lineWords = explode($line, '|');

   // Onthoudt welk woord de eerste is zodat de volgende woorden daaraan gelinkt kunnen worden
   $firstWord = true;
   foreach($lineWords as $word) {

      // Kijk of woord al in de database staat, if so gebruik het ID uit de array
      if(array_key_exists($word, $words)) {
         $id = $words[$word];
      } else {
         // Gooi woord de database in
         mysql_query('INSERT INTO words SET word="'.mysql_real_escape_string($word).'"');

         // Vraag het ID van het zojuist geinserte woord op
         $id = mysql_insert_id();

         // Onthoudt het ID in een array
         $words[$word] = $id;

         // Maak een array aan waar straks de ID's van gelinkte woorden in kunnen worden opgeslagen
         $ids[$id] = Array();
      }

      if($firstWord) {
         // Bij het eerste woord onthouden we het ID in de variabele $parent_id
         $parent_id = $id;
         $firstWord = false;
      } else if(!in_array($id, $ids[$parent_id])) {
         // Als het woord nog niet is gekoppelt dan doe we dat alsnog

         // Even onthouden dat er is gekoppelt
         $ids[$parent_id][] = $id;

         // De koppeling opslaan in de database
         mysql_query('INSERT words_words SET parent_id = '.$parent_id.', child_id = '.$id);
      }
   }
}


De tabel words heeft 2 velden, id en word. De tabel words_words heeft ook 2 velden: parent_id en child_id (die samen de key vormen voor die tabel en beiden een FOREIGN_KEY hebben naar words.id).

Bovenstaande code levert je een tabel op met unieke woorden en een koppel tabel met de daar bijhorende woorden.

Als je dan bijvoorbeeld alle woorden wilt die aan het woord sleutel gelinkt zijn run je de volgende query:

SQL:
1
2
3
4
5
6
7
8
9
   SELECT 
        parentwords.word AS parentword
   ,    childwords.word AS childword
   FROM
      words AS parentwords
   INNER JOIN words_words ON words_words.parent_id = parentwords.id
   INNER JOIN words AS childwords ON childwords.id = words_words.child_id
   WHERE
      parentwords.word = 'sleutel';

[ Voor 45% gewijzigd door McVirusS op 02-02-2010 11:47 . Reden: Commentaar toegevoegd ]


Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Voordat we met voorbeeldcode gaan gokken en smijten:

Die FK naar elkaar hoeft inderdaad echt niet, of leg anders maar uit wat voor relatie er tussen woord 1 en 2 zit.

{signature}


Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 18-09 12:01
Voutloos schreef op dinsdag 02 februari 2010 @ 11:41:
Voordat we met voorbeeldcode gaan gokken en smijten:

Die FK naar elkaar hoeft inderdaad echt niet, of leg anders maar uit wat voor relatie er tussen woord 1 en 2 zit.
De FK zou in de koppeltabel gelegd kunnen worden :).

Acties:
  • 0 Henk 'm!

  • Voutloos
  • Registratie: Januari 2002
  • Niet online
Je blijft maar gokken he, ts heeft nergens echt goed expliciet gezegd dat het N:M relatie is en daarom vroeg ik daarna.

{signature}


Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 18-09 12:01
Voutloos schreef op dinsdag 02 februari 2010 @ 11:45:
Je blijft maar gokken he, ts heeft nergens echt goed expliciet gezegd dat het N:M relatie is en daarom vroeg ik daarna.
Je hebt gelijk, heb wel aannames gedaan :P. Het zou inderdaad ook nog kunnen dat als sleutel aan bos gekoppelt is dat dan de koppeling bos naar sleutel niet meer gelegd hoeft te worden.

Heb nog wel even wat commentaar toegevoegd in mijn code zodat het nog leerzaam is. Anders heeft TS er alsnog niks aan.

Acties:
  • 0 Henk 'm!

  • McVirusS
  • Registratie: Januari 2000
  • Laatst online: 18-09 12:01
Verwijderd schreef op dinsdag 02 februari 2010 @ 11:30:
[...]


Oja sorry dat was ik vergeten te vertellen

woord1 moet naar nog meer terugkoppelen
Dus ik heb bijvoorbeeld dit in mijn databestand
sleutel|bos|woord3
sleutel|hark|woord3
sleutel|pan|woord3

dan moeten alle 3 woord2'en terug gekoppeld worden naar sleutel en naar elkaar
maar last_insert_id ken ik nog niet, zal er eens naar kijken
In bovenstaand voorbeeld, moet dan bos ook aan hark gekoppeld worden? En als er een regel zou zijn die "hark|sleutel|woord3" bevat zou die dan wel of niet moeten worden opgeslagen? Met andere woorden; is het belangrijk om te weten wat het eerste woord was?

Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
McVirusS schreef op dinsdag 02 februari 2010 @ 11:49:
[...]


In bovenstaand voorbeeld, moet dan bos ook aan hark gekoppeld worden? En als er een regel zou zijn die "hark|sleutel|woord3" bevat zou die dan wel of niet moeten worden opgeslagen? Met andere woorden; is het belangrijk om te weten wat het eerste woord was?
Bedankt voor de reacties allemaal.

Alle woorden moeten aan elkaar gekoppeld worden, dus bos moet aan sleutel en hark. maar hark ook aan sleutel en bos en bos ook aan sleutel en hark.

Typ dit even snel want ik moet nu naar de studie, ga het daar allemaal verder doorlezen!
Pagina: 1