Code's vervangen woorden
Ik heb een systeem gemaakt die hulpdiensten meldingen opslaat. Nu komt er uit de informatiebron (feed) de zgn capcode mee (een nummer) nu wil ik dat nummer aanpassen voor een woord. Ik heb een lijst met de nummers en de namen waarvoor die veranderd moeten worden (http://p2000.bommel.net/cap2csv.php).
Nu wil ik graag weten wat een rekenarme methode is om dit te doen. Het moet niet veel rekencapaciteit vergen aangezien er soms nogal veel data moet worden verwerkt (veel meldingen, veel gebruikers) en het dan erg zonde zou zijn als hier veel tijd aan verloren gaat. De hierboven aangegeven csv ga ik opslaan in een db tabel met daarin de row "capcode" en "naam"
Alvast bedankt
En dat staat ook in een database?
Ja dat klopt ;)
Gewijzigd op 05/12/2012 21:10:50 door Zie Foto
Data word ingelezen uit rss -> word gecheckt of niet al bestaat -> worden wat andere checks en aanpassingen uitgevoerd -> 070025 (bijv) word aangepast in "monitorcode" -> melding word in database gezet.
Niemand een idee?
$codes = array('070025' => 'monitorcode', '070026' => 'anderecode', '070042' => 'etc');
Vervolgens kun je de omschrijving opvragen als:
$code = '070025';
$desc = isset($codes[$code]) ? $codes[$code] : 'onbekend';
Uit de rss haal je dan de capcode op (die noemen we voor het gemak even $rss_capcode) en vervolgens doe je een select op de database:
"SELECT description FROM capcodes WHERE capcode = " . $rss_capcode;
Als je een resultaat krijgt dan weet je wat de description is. Als je geen resultaat krijgt, staat de capcode blijkbaar niet in de database, en dan maak je er "onbekend" van. (Ik zou overigens niet de waarde "onbekend" bij het betreffende nieuwsbericht opslaan. Je kunt beter gewoon de capcode opslaan. Op het moment dat je dan de description op het scherm toont, controleer je eerst of deze niet numeriek is. Indien dit het geval is, toon je gewoon de omschrijving. Indien de description wel numeriek is, dan toon je "onbekend". Op deze manier zorg je ervoor dat je alle capcodes opslaat in de database. Eventueel onbekende capcodes zou je dan naderhand nog kunnen wijzigen in de juiste description.)
Dat is inderdaad het idee. Maar bij het ophalen van 1 melding komen iets van 5 capcodes mee. En als ik dan bv. 5 gebruikers hebben waarvan op dat moment iedereen 1 melding binnen komt houd dat in dat er 5*5=25 keer een SELECT word uitgevoerd, word het systeem daar niet erg sloom van? Of is dit de snelste methode om het te doen.
Zijn ze wel echt in de tekst verwerkt dan kan het nog steeds, maar wordt het iets bewerkelijker. Bijvoorbeeld je kan bij het invoeren alle codes via een regex selecteren en een linktabel maken tussen de melding en codes. Voor elke code die je hebt geselecteerd maak je een linkrecord aan in die linktabel. Bij het ophalen van je data neem je die links mee (inclusief de melding tekst) en bij het tonen van het record vervang je de code door de melding. Dit kan op dat moment dan met een simpele str_replace, daar heb je dan geen regex meer voor nodig.
Bij het invoeren heb je dan 1 redelijk eenvoudige regex nodig en twee insert queries (een voor de melding, een voor de links), bij het uitlezen heb je een query nodig met twee joins en een paar str_replace functies.
Ze staan in een apart veld. Maar als je ze bij het ophalen pas gaat verwerken word de laadtijd toch een heel stuk slomer, als dat dan over 30 meldingen (bijv.) moet worden gedaan?
Als ze in een apart veld staan dan zou ik er niet eens meer over nadenken. Gewoon opslaan in een apart veld in je database en de tekst van de meldingen erbij joinen. Dat is waar een relationele database voor gebouwd is en met de juiste indices is het ophalen van 30 meldingen echt peanuts.
Gewijzigd op 07/12/2012 12:29:01 door Matthijs Vos
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
CREATE TABLE meldingen(
melding_code VARCHAR(6),
melding_tekst TEXT
);
CREATE TABLE codes(
code VARCHAR(6),
code_tekst VARCHAR(100)
);
melding_code VARCHAR(6),
melding_tekst TEXT
);
CREATE TABLE codes(
code VARCHAR(6),
code_tekst VARCHAR(100)
);
Dan zou je met de volgende query alle meldingen met de juiste code tekst kunnen krijgen:
Dus... bericht komt via RSS binnen. Iemand bezoekt de site... het RSS bericht wordt omgezet in het juiste bericht en opgeslagen in de database. Bezoeker 2 komt... hé, het bericht staat al in de database dus ik toon het bericht uit de database in plaats van het RSS bericht.
Toevoeging op 09/12/2012 15:46:56:
Ik ben de left join methode aan het proberen. Ik heb de volgende Query:
Code (php)
Nu krijg ik een error. Als ik hem in mijn SQL draai binnen PHPMYADMIN krijg ik "#1064 - You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'LEFT JOIN capcodes ON brandweer.capcodes = capcodes.capcode' at line 6" en als ik dan die lijn even weghaal krijg ik "#1054 - Unknown column 'capcodes.capcode' in 'field list'" Maar in de table cacpodes bestaat het veld capcode wel..
Wie weet wat ik verkeer doe?
De join staat verkeerd, dit is een onderdeel van from clause dus moet voor de where, order by en limit.
Code (php)
Nu krijg ik bij het uitvoeren in de SQL de error: "#1066 - Not unique table/alias: 'capcodes' "
Gewijzigd op 09/12/2012 16:37:05 door Matthijs Vos
Omdat je nu een impliciete join en een expliciete join maakt op dezelfde tabel in een statement. Dat zou theoretisch wel kunnen, maar is niet wat je wilt (en zo kan het niet). Haal dus capcodes weg uit het FROM statement.
Code (php)
1
2
3
4
5
6
2
3
4
5
6
SELECT brandweer.id, brandweer.time, brandweer.melding, brandweer.capcodes, capcodes.capcode, capcodes.description
FROM brandweer
LEFT JOIN capcodes ON brandweer.capcodes = capcodes.capcode;
WHERE site = 10
ORDER BY time DESC
LIMIT 0, 10
FROM brandweer
LEFT JOIN capcodes ON brandweer.capcodes = capcodes.capcode;
WHERE site = 10
ORDER BY time DESC
LIMIT 0, 10
Je hebt 2 opties om te joinen:
Dit noemt men een impliciete join, en is in MySQL altijd een INNER JOIN
Een expliciete join is zoals in de eerste query
ORDER BY ' at line 1 "
Dus dan zit er nog een fout in de LEFT JOIN lijn of niet?