<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>David Steinsland - informatikkstudent og webutvikler &#187; MySQL</title>
	<atom:link href="http://davidsteinsland.net/emner/webprogrammering/mysql/feed/" rel="self" type="application/rss+xml" />
	<link>http://davidsteinsland.net</link>
	<description>Personlig blogg om programmering og andre uinteressante emner</description>
	<lastBuildDate>Thu, 26 Apr 2012 10:49:50 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Oppgraderingsdag</title>
		<link>http://davidsteinsland.net/2010/12/oppgraderingsdag/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=oppgraderingsdag</link>
		<comments>http://davidsteinsland.net/2010/12/oppgraderingsdag/#comments</comments>
		<pubDate>Mon, 20 Dec 2010 18:40:29 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Apache]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=439</guid>
		<description><![CDATA[I disse &#171;sene&#187; juledager har jeg fått oppgradert serveren min, deriblant PHP, MySQL og Apache til aller siste versjon. Mest hyggelig er det jo med en etterlengtet MySQL-oppgradering, som såvidt har blitt oppdatert Oracle kjøpte dem opp. Anbefaler også at du gjør det samme, og da spesielt MySQL 5.5-oppgraderingen hvor InnoDB endelig er satt som [...]]]></description>
			<content:encoded><![CDATA[<p>I disse &laquo;sene&raquo; juledager har jeg fått oppgradert serveren min, deriblant PHP, MySQL og Apache til aller siste versjon. Mest hyggelig er det jo med en etterlengtet MySQL-oppgradering, som såvidt har blitt oppdatert Oracle kjøpte dem opp.</p>
<p>Anbefaler også at du gjør det samme, og da spesielt <a href="http://www.mysql.com/downloads/mysql/">MySQL 5.5</a>-oppgraderingen hvor InnoDB endelig er satt som standard og som kan skiltes som 540 % mer effektiv (Windows)!</p>
<p>Så nå kjører jeg altså PHP 5.3.4, MySQL 5.5 og Apache 2.2.17, på en Windows 7-maskin, som tok meg i underkant av 15 minutter å gjøre.</p>
<p>PS:</p>
<ul>
<li>Oppdater <a href="http://www.apachelounge.com/viewtopic.php?p=17092">eAccelerator for PHP 5.3.4</a> i samme slengden</li>
<li>Få også med deg notatet om <a href="http://dev.mysql.com/doc/refman/5.5/en/windows-upgrading.html">oppgradering av MySQL på Windows</a></li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/12/oppgraderingsdag/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Query Cache</title>
		<link>http://davidsteinsland.net/2010/12/mysql-query-cache/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mysql-query-cache</link>
		<comments>http://davidsteinsland.net/2010/12/mysql-query-cache/#comments</comments>
		<pubDate>Wed, 08 Dec 2010 00:02:25 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=428</guid>
		<description><![CDATA[Når du bygger applikasjoner for nettet, vil du komme til et punkt hvor enkelte komponenter kan dra ned ytelsen eller lastetiden. Dette kan for eksempel være krevende PHP-kode som store løkker, behandling av store mengder data, eller krevende MySQL-spørringer. Du tenker da kanskje å implementere et mellomlager. Dette kan du gjøre på applikasjonsnivå og på [...]]]></description>
			<content:encoded><![CDATA[<p>Når du bygger applikasjoner for nettet, vil du komme til et punkt hvor enkelte komponenter kan dra ned ytelsen eller lastetiden. Dette kan for eksempel være krevende PHP-kode som store løkker, behandling av store mengder data, eller krevende MySQL-spørringer.</p>
<p>Du tenker da kanskje å implementere et mellomlager. Dette kan du gjøre på applikasjonsnivå og på servernivå.</p>
<p>La oss si at du har bygget deg en RSS-leser, som henter XML-data fra nyhetsstrømmer fra nettet. Over tid vil serveren bruke mye ressurser på å laste disse ned fra nettet hele tiden, og som mottiltak kan du lagre XML-dataene på din egen server (som blir oppdatert jevnlig). På den måten har du implementert et mellomlager på applikasjonsnivå, hvor du lagrer data i en gitt periode før du oppdaterer mellomlageret med ny data (for eksempel hver 30. minutt).</p>
<p>Du kan også implementere løsninger på servernivå, som kan bedre ytelsen til PHP ved at den kompilerer koden og lagrer den på RAM. Her har du eksempler som <a href="http://www.php-accelerator.co.uk/">PHP-Accelerator</a>, <a href="http://eaccelerator.net/">eAccelerator</a> og <a href="http://www.zend.com/en/products/guard/runtime-decoders">Zend Optimizer</a>.</p>
<p>Men hva når det kommer til MySQL-spørringer?</p>
<p>Her kan du også implementere et mellomlager på applikasjonsnivå, men da må du sette opp dine egne metoder som kjører spørringer etc. Du følger da samme tankegangen som med RSS-leseren:</p>
<ul>
<li>Når spørringen blir kjørt for første gang, lagrer du resultatet som spørringen gir i en tekstfil.</li>
<li>Neste gang spørringen blir kjørt, returnerer du dataene fra tekstfilen istedenfor å kjøre spørringen på nytt.</li>
</ul>
<p>Men dette kan være uønskelig i flere tilfeller:</p>
<ul>
<li>du må sette opp egne metoder, da PHPs innebygde MySQL-bibliotek ikke støtter caching</li>
<li>dataene kan være unøyaktige, og du bør hele tiden sørge for at tekstfilene inneholder oppdatert informasjon</li>
</ul>
<p>Typisk implementering ville vært noe slik:</p>
<pre class="brush: php; title: ; notranslate">
class MySQL
{
	public function query ($query)
	{
		$cache = 'cache/' . md5 ($query) . '.mysql';

		if ( file_exists ($cache))
		{
			$data = unserialize (file_get_contents ($cache));
		}
		else
		{
			$query = mysql_query ($query);

			$data = array ();

			while ($row = mysql_fetch_assoc ($data))
			{
				$data[] = $row;
			}

			file_put_contents ($cache, $data);
		}

		return $data;
	}
}

$mysql = new MySQL ('localhost', 'user', 'pw', 'db');

$data = $mysql-&gt;query ('SELECT foo FROM bar');
</pre>
<h3>MySQL Query Cache</h3>
<p>Men en bedre løsning vil være å dra nytte av MySQLs egen <a href="http://dev.mysql.com/tech-resources/articles/mysql-query-cache.html">Query Cacher</a>. Denne returnerer mellomlagret data dersom det er forblitt uforandret, og oppdaterer så snart det er ny data. I tillegg blir spørringene utført på tilnærmet 0 sekunder. Altså en veldig grei sak, dette her!</p>
<p>I de fleste tilfeller er Cache-muligheten skrudd av som standard, og du kan sjekke dette ved å kjøre følgende kommando til MySQL:</p>
<pre class="brush: plain; title: ; notranslate">
mysql&gt; show variables like 'query%';
+------------------------------+---------+
| Variable_name                | Value   |
+------------------------------+---------+
| query_alloc_block_size       | 8192    |
| query_cache_limit            | 1048576 |
| query_cache_min_res_unit     | 4096    |
| query_cache_size             | 0       |
| query_cache_type             | ON      |
| query_cache_wlock_invalidate | OFF     |
| query_prealloc_size          | 8192    |
+------------------------------+---------+
</pre>
<p>Her ser vi at query_cache_size er satt til 0, noe som fører til at Cache-funksjonaliteten er skrudd av. For å aktivere denne, kjør følgende kommando:</p>
<pre class="brush: plain; title: ; notranslate">
mysql&gt; set global query_cache_size=50000000;
</pre>
<p>Det er i bunn og grunn alt du trenger å gjøre! Og dette fungerer flott som fjell.</p>
<p>Lykke til!</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/12/mysql-query-cache/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Daglig backup av MySQL med PHP (Windows)</title>
		<link>http://davidsteinsland.net/2010/10/daglig-backup-av-mysql-med-php-windows/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=daglig-backup-av-mysql-med-php-windows</link>
		<comments>http://davidsteinsland.net/2010/10/daglig-backup-av-mysql-med-php-windows/#comments</comments>
		<pubDate>Sat, 30 Oct 2010 22:08:35 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Guider]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programmering]]></category>
		<category><![CDATA[backup]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[windows]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=377</guid>
		<description><![CDATA[Hva er det som er så viktig med sikkerhetskopier? Hvordan kan man ta sikkerhetskopi uten noe stress? I dette innlegget viser jeg deg hvordan du kan ta sikkerhetskopi av MySQL ved å bruke PHP, og automatisere det med en planlagt oppgave i Windows.]]></description>
			<content:encoded><![CDATA[<p>Dersom du drifter din egen server eller har en utviklingsserver på PC-en din, har du nok vært i situasjoner hvor du tenker: &laquo;Hvor er sikkerhetskopien når jeg trenger den?&raquo;.</p>
<p>Jeg var der selv for omtrent en úke siden, hvor jeg ved en feiltakelse kjørte en gammel PHP-fil som overskrev hele <a href="http://davidsteinsland.net/2010/03/komplett-databasesett-over-norges-postnummer-med-koordinater/">Postnummer-databasen min</a>. Heldigvis hadde jeg mange sikkerhetskopier av databasen, så det gikk bra.</p>
<p>Men hva om jeg ikke hadde hatt kopier? Da hadde faktisk hele arbeidet mitt vært ødelagt! Mangfoldige timer bortkastet, bokstavelig talt.</p>
<p>Hver dag (midnatt) blir livredderen utført: en planlagt oppgave i Windows kjører et PHP-skript som tar backup av MySQL.</p>
<p>I mine siste artikler har jeg skrevet litt om planlagte oppgaver i Windows, og vist flere ting du kan gjøre.</p>
<h3>Teori</h3>
<p>Når du installerte MySQL, fikk du med et program som heter <a href="http://dev.mysql.com/doc/refman/5.1/en/mysqldump.html">mysqldump</a>. Programmet brukes til å ta backup av MySQL; du kan selv spesifisere én eller flere databaser, eller om du ønsker å ta backup av alle.</p>
<p>Videre kommer jeg til å ta i bruk  <a href="http://php.net/manual/en/features.commandline.php">PHP fra kommandolinjen</a>, som muliggjør at vi kan bruke PHP-tolkeren til å kjøre en bestemt PHP-fil. Dette programmet ligger i installasjonsmappen til PHP, og heter <var>php.exe</var></p>
<p>Jeg refererer til disse programmene som henholdsvis <em>mysqldump</em> og <em>php</em> fra kommandolinjen. Dette er fordi jeg har lagt til PHPs installasjonsmappe og <em>bin</em>-mappen til MySQL til miljøvariabelen PATH. Dette forteller Windows at når du skriver inn et program i CMD, skal den også leite etter det programmet i de plasseringene.</p>
<p>Dersom du ikke har gjort dette, må du spesifisere til programmene med full sti, eks: c:\php\php eller skrive inn følgende i CMD:</p>
<pre class="brush: plain; title: ; notranslate">SET PATH = %PATH%;C:\PHP;C:\MySQL\bin</pre>
<p>(jeg antar PHP og MySQL er installert i C:\).</p>
<p>Ved default ligger &laquo;.EXE&raquo; i miljøvariabelen PATHEXT, som medfører at du slipper å skrive &laquo;.exe&raquo; bak programnavnet.</p>
<h3>PHP-filen</h3>
<p>Gjør klar en PHP-fil som du navngir <em>backup.php</em> og plasser denne utenfor <em>ServerRoot</em> (altså en plass den ikke kan nåes via en nettleser).</p>
<p>ServerRoot hos meg er \www\public_html\, slik at jeg har plassert PHP-filen ett steg opp, i \www\ (Med baklengs-skråstrek foran stien, tolker Windows dette som C:\).</p>
<p>Lag så en mappe du kaller for <em>backup</em> i samme mappe hvor du har plassert PHP-filen. Dette er plassen hvor backupene våre kommer til å ligge.</p>
<p>Det første vi gjør i PHP-filen vår er å definere et par runtime-innstillinger, som databasetilkoblingen, plasseringen til backup-filene og hvordan filnavnet skal utformes.</p>
<pre class="brush: php; title: ; notranslate">
// MySQL host
define ('HOST', 'localhost');
// MySQL username
define ('USER', 'username');
// MySQL password
define ('PW', 'password');

define ('DUMP_FILENAME', date ('Y-m-d-H-i') . '.sql'); // i.e. 2010-10-30-23-00.sql

define ('SELF_DIR', __DIR__ . DIRECTORY_SEPARATOR);
define ('BACKUP_DIR', 'backup' . DIRECTORY_SEPARATOR);
</pre>
<p>Backupfilene våre får navnet sitt basert på dagens dato og tidspunktet for når filen blir kjørt.</p>
<p>Neste steg er å kalle opp <em>mysqldump</em>:</p>
<pre class="brush: php; title: ; notranslate">passthru (sprintf ('mysqldump -h %s -u %s -p%s -A -r &quot;%s&quot;', HOST, USER, PW, SELF_DIR . BACKUP_DIR . DUMP_FILENAME));</pre>
<p>Her trenger du ikke endre noe, bortsett fra stien til <em>mysqldump</em> om du ikke har endret PATH i Windows.</p>
<p>Argumentforklaring:</p>
<dl>
<dt>-h</dt>
<dd>Spesifiserer host-adressen til MySQL</dd>
<dt>-u</dt>
<dd>Brukernavnet til MySQL</dd>
<dt>-p</dt>
<dd>Passordet ditt MySQL-brukeren (-p og passordet skal ikke ha mellomrom mellom hverandre).</dd>
<dt>-A</dt>
<dd>Spesifiserer at vi skal ta backup av alle databasene. Alternativt <em>&#8211;all-databases</em>.</dd>
<dt>-r</dt>
<dd>Den fulle stien (plassering + filnavn) til hvor backupen ligger</dd>
</dl>
<p>Det neste jeg har valgt å gjøre, er å komprimere SQL-filen i et Zip-arkiv, som medfører at filstørrelsen blir endel mindre (noe som er bra!).</p>
<pre class="brush: php; title: ; notranslate">
$Zip = new ZipArchive;
$Zip-&gt;open (SELF_DIR . BACKUP_DIR . DUMP_FILENAME . '.zip', ZipArchive::CREATE);
$Zip-&gt;setArchiveComment ('This database dump was automatically taken at ' . date ('H:i, d.m.Y') . ' by a Windows Scheduled Task');
$Zip-&gt;addFile (DUMP_FILENAME, SELF_DIR . BACKUP_DIR . DUMP_FILENAME);
unlink (SELF_DIR . BACKUP_DIR . DUMP_FILENAME);
$Zip-&gt;close();
</pre>
<h3>Den planlagte oppgaven</h3>
<p>Det siste steget vårt, er å opprette oppaven som skal kjøre PHP-skriptet. Jeg har valgt å kjøre denne oppgaven hver dag ved midnatt.</p>
<p>Opprett den planlagte oppgaven ved å skrive dette inn i CMD:</p>
<pre class="brush: plain; title: ; notranslate">SCHTASKS /Create /SC DAILY /MO 1 /ST 00:00 /TN &quot;MySQL Backup&quot; /TR &quot;php \www\backup.php&quot;</pre>
<h3>Tips</h3>
<h4>Uten PHP</h4>
<p>Dersom du ikke ønsker å komprimere filene med Zip, trenger du heller ikke anvende PHP til denne jobben. Da kjører du rett og slett bare <em>mysqldump</em> direkte i oppgaven:</p>
<pre class="brush: plain; title: ; notranslate">SCHTASKS /Create /SC DAILY /MO 1 /ST 00:00 /TN &quot;MySQL Backup&quot; /TR &quot;mysqldump -h &lt;host&gt; -u &lt;brukernavn&gt; -p&lt;passord&gt; -A -r \www\backups\database_dump.sql&quot;</pre>
<p>Husk at det ikke skal være mellomrom mellom <em>-p</em> og passordet!</p>
<h4>Én eller flere databaser istedenfor alle</h4>
<p>Erstatt <em>-A</em> i mysqldump-kommandoen med:</p>
<pre class="brush: plain; title: ; notranslate">--database &lt;database&gt;</pre>
<p>eller</p>
<pre class="brush: plain; title: ; notranslate">--databases &lt;database 1&gt; &lt;database 2&gt; ... &lt;database N&gt;</pre>
<h3>Garbage Collector</h3>
<p>Det tar ikke lange tiden før backup-mappen blir full av filer; og strengt talt så trenger du ikke backups som ble tatt for måneder siden. Derfor kan det være lurt å sette opp en søppelsamler, som sletter gamle filer.<br />
Da oppretter du en planlagt oppgave som kjører for eksempel <em>\www\garbage.php</em> hver uke. Innholdet i PHP-filen er å <em>loope</em> gjennom backup-mappen, og sjekke datoen på når filene sist ble modifisert (opprettet). Slik har jeg gjort det:</p>
<pre class="brush: php; title: ; notranslate">
// How long we are keeping each file, since its creation date
// (in seconds)
define ('MAX_FILE_AGE', (60 * 60 * 24 * 7)); // 7 days

$data = glob (__DIR__ . DIRECTORY_SEPARATOR . 'backup' . DIRECTORY_SEPARATOR . '*.zip');

foreach ($data as $file)
{
	if (time() - filectime ($file) &gt; MAX_FILE_AGE)
	{
		unlink ($file);
	}
}
</pre>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/10/daglig-backup-av-mysql-med-php-windows/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Database med Norges postnummer, poststeder, fylker og kommuner (med koordinater)</title>
		<link>http://davidsteinsland.net/2010/03/komplett-databasesett-over-norges-postnummer-med-koordinater/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=komplett-databasesett-over-norges-postnummer-med-koordinater</link>
		<comments>http://davidsteinsland.net/2010/03/komplett-databasesett-over-norges-postnummer-med-koordinater/#comments</comments>
		<pubDate>Fri, 12 Mar 2010 21:49:51 +0000</pubDate>
		<dc:creator>David Steinsland</dc:creator>
				<category><![CDATA[Åpen kildekode]]></category>
		<category><![CDATA[Guider]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[adresser]]></category>
		<category><![CDATA[database]]></category>
		<category><![CDATA[fylker]]></category>
		<category><![CDATA[guide]]></category>
		<category><![CDATA[kommuner]]></category>
		<category><![CDATA[koordinater]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[opensource]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[postnummer]]></category>

		<guid isPermaLink="false">http://blog.davidsteinsland.net/?p=259</guid>
		<description><![CDATA[Behøver du en database med alle Norges postnummer? Bruker du et kart på nettsiden din? Har du behov for å sjekke hvilket sted postnummeret peker mot? Jeg har samlet alle dataene, i tillegg til koordinater til hvert eneste postnummer!]]></description>
			<content:encoded><![CDATA[<p>Her kommer det er oversikt over absolutt alle postnummer i Norge med tilhørende fylke, kommune og poststed. Hvert postnummer har også en lengde- og breddegrad tilknyttet seg. På denne måten kan du koble opp postnummeret til f.eks Google Maps.</p>
<p>Databasesettet er generert med hjelp av <a href="http://www.erikbolstad.no/geo/noreg/postnummer/">Postnummer-dugnaden</a> <a href="http://yr.no">Yr.no</a> arrangerte sommeren 2009.</p>
<p>Ved hjelp av lengde- og breddegradene kan du jo også regne deg frem til avstanden mellom to steder, eller finne nærmeste postkontor til en bruker.</p>
<p>For å få lett oversikt over alle postkoder, kjører du følgende spørring:</p>
<pre class="brush: sql; title: ; notranslate">
SELECT
 postnummer, fylkeNavn, kommuneNavn, poststedNavn, kategoriNavn, lat, lon
FROM `postnumre`
INNER JOIN poststed
USING(poststedID)
INNER JOIN kommuner
USING(kommuneID)
INNER JOIN fylker
USING(fylkeID)
INNER JOIN kategorier
USING(kategoriID)
ORDER BY
 postnummer ASC, fylkeNavn ASC, kommuneNavn ASC, poststedNavn ASC</pre>
<p>Med enhver sak kan det forekomme feil, så om dere kommer over noe som skulle vise seg til å være en bug: si i fra.<strong></strong></p>
<h3>Oppdateringer</h3>
<p><strong>Versjon 1.4<br />
</strong>- Har innført alle endringer gjort av posten pr. 1. februar 2012<br />
- Det er nye navn på tabeller og kolonner (norsk)<br />
- Koordinater er synkronisert med <a href="http://www.erikbolstad.no/geo/noreg/postnummer/">listene til Erik Bolstad</a></p>
<p><strong>Versjon 1.3</strong><br />
- Tabellene er gjort om til InnoDb med nødvendige indekser og fremmednøkler<br />
- Jan Mayen og Svalbard er nå plassert inn i to fylker (med samme navn), i henhold til ISO 3166-2:NO. På grunn av at områdene ikke har noe de facto fylke, måtte det gjøres slik.<br />
- Enkelte justeringer på koordinater<br />
- Kommunesentre for hver kommune er lagt inn</p>
<p><strong>Versjon 1.2</strong><br />
- Jan Mayen og Svalbard har klart å falle ut fra oversikten. Det er pga. områdene ikke er del av noen fylker, og det har dermed blitt opprettet et &laquo;Svalbard og Jan Mayen&raquo;-fylke.</p>
<h3>Last ned (versjon 1.4)</h3>
<p><img src="http://davidsteinsland.net/wp-content/themes/eikeland/images/download_icon.png" alt="Last ned" class="icon" /> <a href="http://davidsteinsland.net/filer/norske_postnummer_20120209.zip">Norske postnummer</a> (2183 nedlastninger) , lisensiert under <a href="http://creativecommons.org/licenses/by-sa/3.0/">Creative Commons</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://davidsteinsland.net/2010/03/komplett-databasesett-over-norges-postnummer-med-koordinater/feed/</wfw:commentRss>
		<slash:comments>16</slash:comments>
		</item>
	</channel>
</rss>

