<?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>evardsson.com: stuff that w0rks &#187; Database</title>
	<atom:link href="http://www.evardsson.com/blog/tag/database/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.evardsson.com/blog</link>
	<description>tweaks and hacks, php, python, music, home and ???</description>
	<lastBuildDate>Thu, 29 Jul 2010 19:25:27 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>SPDO 1.0b Release Candidate 1</title>
		<link>http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/</link>
		<comments>http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/#comments</comments>
		<pubDate>Sun, 08 Mar 2009 20:21:37 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[SPDO]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/?p=306</guid>
		<description><![CDATA[SPDO version 1.0 beta Release Candidate 1 is out the door. This version adds the following: Three custom Exception classes: SPDOError, ConnectionFailedError and ForeignKeyViolationError. Which are used (in order) when the program encounters an unknown sql error, a failure to connect to the database, and a violation of a foreign key constraint. Which means, of [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://www.evardsson.com/wiki/SPDO">SPDO</a> version 1.0 beta Release Candidate 1 is <a href="http://www.evardsson.com/files/spdo-complete-1.0bRC-1.tar.bz2">out the door</a>. This version adds the following:</p>
<p>Three custom Exception classes: SPDOError, ConnectionFailedError and ForeignKeyViolationError. Which are used (in order) when the program encounters an unknown sql error, a failure to connect to the database, and a violation of a foreign key constraint. Which means, of course, that foreign key constraints are now part of SPDO.</p>
<p>How this was accomplished is through the use of the new DbBuilder class. The DbBuilder class takes a multi-dimensional dict (Python) or array (PHP) of table and field data to build the tables and create triggers in MySQL and SQLite and add foreign keys in PostgreSQL. As an example consider the following: </p>
<p>In Python:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ec954160">
<div class="synthi_header" style="font-weight:bold;"> Python <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ec954160').style.display='block';document.getElementById('plain_synthi_4c529ec954160').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">structure = {
    'authors':{
        'id':['primary_auto'],
        'first_name':['varchar(50)'],
        'last_name':['varchar(50)', 'NONULL', 'INDEX']
        },
    'books':{
        'id':['primary_auto'],
        'author_id':['int', &#034;FK_CASCADE('authors','id')&#034;, 'INDEX'],
        'title':['varchar(100)','NONULL', 'INDEX']
        }
    }
dbb = DbBuilder(structure)
dbb.create()
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ec954160">
<div class="synthi_header" style="font-weight:bold;"> Python <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ec954160').style.display='block';document.getElementById('styled_synthi_4c529ec954160').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="python" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">structure = <span style="color: black;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #483d8b;">&#8216;authors&#8217;</span>:<span style="color: black;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;id&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;primary_auto&#8217;</span><span style="color: black;">&#93;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;first_name&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;varchar(50)&#8217;</span><span style="color: black;">&#93;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;last_name&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;varchar(50)&#8217;</span>, <span style="color: #483d8b;">&#8216;NONULL&#8217;</span>, <span style="color: #483d8b;">&#8216;INDEX&#8217;</span><span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #483d8b;">&#8216;books&#8217;</span>:<span style="color: black;">&#123;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;id&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;primary_auto&#8217;</span><span style="color: black;">&#93;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;author_id&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;int&#8217;</span>, <span style="color: #483d8b;">&quot;FK_CASCADE(&#8216;authors&#8217;,'id&#8217;)&quot;</span>, <span style="color: #483d8b;">&#8216;INDEX&#8217;</span><span style="color: black;">&#93;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #483d8b;">&#8216;title&#8217;</span>:<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;varchar(100)&#8217;</span>,<span style="color: #483d8b;">&#8216;NONULL&#8217;</span>, <span style="color: #483d8b;">&#8216;INDEX&#8217;</span><span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: black;">&#125;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: black;">&#125;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">dbb = DbBuilder<span style="color: black;">&#40;</span>structure<span style="color: black;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">dbb.<span style="color: black;">create</span><span style="color: black;">&#40;</span><span style="color: black;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
<p>In PHP:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ec95a40f">
<div class="synthi_header" style="font-weight:bold;"> PHP <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ec95a40f').style.display='block';document.getElementById('plain_synthi_4c529ec95a40f').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">$structure = array(
        'authors'=>array(
        'id'=>array('primary_auto'),
        'first_name'=>array('varchar(50)'),
        'last_name'=>array('varchar(50)', 'NONULL', 'INDEX')
    ),
    'books'=>array(
        'id'=>array('primary_auto'),
        'author_id'=>array('int', &#034;FK_CASCADE('authors','id')&#034;, 'INDEX'),
        'title'=>array('varchar(100)','NONULL', 'INDEX')
    )
);
$dbb = DbBuilder($structure)
$dbb->create()
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ec95a40f">
<div class="synthi_header" style="font-weight:bold;"> PHP <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ec95a40f').style.display='block';document.getElementById('styled_synthi_4c529ec95a40f').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="php" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #0000ff;">$structure</span> = <a href="http://www.php.net/array"><span style="color: #000066;">array</span></a><span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;authors&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;id&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;primary_auto&#8217;</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;first_name&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;varchar(50)&#8217;</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;last_name&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;varchar(50)&#8217;</span>, <span style="color: #ff0000;">&#8216;NONULL&#8217;</span>, <span style="color: #ff0000;">&#8216;INDEX&#8217;</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #ff0000;">&#8216;books&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;id&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;primary_auto&#8217;</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;author_id&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;int&#8217;</span>, <span style="color: #ff0000;">&quot;FK_CASCADE(&#8216;authors&#8217;,'id&#8217;)&quot;</span>, <span style="color: #ff0000;">&#8216;INDEX&#8217;</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff0000;">&#8216;title&#8217;</span>=&gt;array<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;varchar(100)&#8217;</span>,<span style="color: #ff0000;">&#8216;NONULL&#8217;</span>, <span style="color: #ff0000;">&#8216;INDEX&#8217;</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #0000ff;">$dbb</span> = DbBuilder<span style="color: #66cc66;">&#40;</span><span style="color: #0000ff;">$structure</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #0000ff;">$dbb</span>-&gt;<span style="color: #006600;">create</span><span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
<p>This results in the following queries to be executed:</p>
<p>In PostgreSQL:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ec96f4aa">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ec96f4aa').style.display='block';document.getElementById('plain_synthi_4c529ec96f4aa').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">CREATE TABLE authors (
    first_name VARCHAR(50) ,
    last_name VARCHAR(50) NOT NULL,
    id SERIAL PRIMARY KEY
 );
CREATE TABLE books (
    author_id INTEGER ,
    id SERIAL PRIMARY KEY ,
    title VARCHAR(100) NOT NULL
);
CREATE INDEX authors_last_name_idx ON authors(last_name_id);
CREATE INDEX books_author_id_idx ON books(author_id);
CREATE INDEX books_title_idx ON books(title);
ALTER TABLE books ADD FOREIGN KEY (author_id) REFERENCES authors(id) ON DELETE CASCADE;</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ec96f4aa">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ec96f4aa').style.display='block';document.getElementById('styled_synthi_4c529ec96f4aa').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> authors <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; first_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> ,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; last_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id SERIAL <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> </div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp;<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; author_id INTEGER ,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id SERIAL <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span> ,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; title VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> authors_last_name_idx <span style="color: #993333; font-weight: bold;">ON</span> authors<span style="color: #66cc66;">&#40;</span>last_name_id<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> books_author_id_idx <span style="color: #993333; font-weight: bold;">ON</span> books<span style="color: #66cc66;">&#40;</span>author_id<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> books_title_idx <span style="color: #993333; font-weight: bold;">ON</span> books<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">FOREIGN</span> <span style="color: #993333; font-weight: bold;">KEY</span> <span style="color: #66cc66;">&#40;</span>author_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> authors<span style="color: #66cc66;">&#40;</span>id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #993333; font-weight: bold;">DELETE</span> CASCADE; </div>
</li>
</ol>
</div>
</div>
<p>In MySQL:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ec9770c1">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ec9770c1').style.display='block';document.getElementById('plain_synthi_4c529ec9770c1').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">CREATE TABLE authors (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50) NOT NULL
);
CREATE TABLE books (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    author_id INTEGER NOT NULL,
    title VARCHAR(100) NOT NULL
);
CREATE TABLE fk_error_msg (
    error_msg VARCHAR(100) NOT NULL PRIMARY KEY
);
INSERT INTO fk_error_msg VALUES ('Foreign Key Constraint Violated!');
ALTER TABLE authors ADD INDEX(last_name);
ALTER TABLE books ADD INDEX(author_id);
ALTER TABLE books ADD INDEX(title);
CREATE TRIGGER fki_books_author_id
    BEFORE INSERT ON books
    FOR EACH ROW BEGIN
        IF
            0 = (SELECT COUNT(*) FROM authors WHERE id=new.author_id)
        THEN
            INSERT fk_error_msg VALUES ('Foreign Key Constraint Violated!');
        END IF;
    END;
CREATE TRIGGER fku_books_author_id
    BEFORE UPDATE ON books
    FOR EACH ROW BEGIN
        IF
            0 = ( SELECT COUNT(*) FROM authors WHERE id = new.author_id )
        THEN
            INSERT INTO fk_error_msg VALUES ('Foreign Key Constraint Violated!');
        END IF ;
    END;
CREATE TRIGGER fkdc_books_author_id
    BEFORE DELETE ON authors
    FOR EACH ROW BEGIN
        DELETE FROM books WHERE author_id=old.id;
    END;
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ec9770c1">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ec9770c1').style.display='block';document.getElementById('styled_synthi_4c529ec9770c1').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> authors <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; first_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; last_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; author_id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; title VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> fk_error_msg <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; error_msg VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> fk_error_msg <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;Foreign Key Constraint Violated!&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> authors <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color: #66cc66;">&#40;</span>last_name<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color: #66cc66;">&#40;</span>author_id<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">ALTER</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #993333; font-weight: bold;">ADD</span> <span style="color: #993333; font-weight: bold;">INDEX</span><span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fki_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">ON</span> books</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">IF</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;">0</span> = <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> COUNT<span style="color: #66cc66;">&#40;</span>*<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> authors <span style="color: #993333; font-weight: bold;">WHERE</span> id=new.author_id<span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; THEN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INSERT</span> fk_error_msg <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;Foreign Key Constraint Violated!&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; END <span style="color: #993333; font-weight: bold;">IF</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; END;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fku_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">ON</span> books</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN </div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">IF</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #cc66cc;">0</span> = <span style="color: #66cc66;">&#40;</span> <span style="color: #993333; font-weight: bold;">SELECT</span> COUNT<span style="color: #66cc66;">&#40;</span>*<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">FROM</span> authors <span style="color: #993333; font-weight: bold;">WHERE</span> id = new.author_id <span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; THEN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> fk_error_msg <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;Foreign Key Constraint Violated!&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; END <span style="color: #993333; font-weight: bold;">IF</span> ;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; END;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fkdc_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">ON</span> authors</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> books <span style="color: #993333; font-weight: bold;">WHERE</span> author_id=old.id;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; END; </div>
</li>
</ol>
</div>
</div>
<p>In SQLite:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ec98a0dc">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ec98a0dc').style.display='block';document.getElementById('plain_synthi_4c529ec98a0dc').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">CREATE TABLE authors (
    id INTEGER NOT NULL PRIMARY KEY,
    first_name VARCHAR(50),
    last_name VARCHAR(50) NOT NULL
);
CREATE TABLE books (
    id INTEGER NOT NULL PRIMARY KEY,
    author_id INTEGER NOT NULL,
    title VARCHAR(100) NOT NULL
);
CREATE INDEX authors_last_name_idx ON authors(last_name);
CREATE INDEX books_author_id_idx ON books(author_id);
CREATE INDEX books_title_idx ON books(title);
CREATE TRIGGER fki_books_author_id
    BEFORE INSERT ON [books]
        FOR EACH ROW BEGIN
            SELECT RAISE(ROLLBACK, 'insert on table &#034;books&#034; violates foreign key constraint &#034;fki_books_author_id&#034;')
            WHERE NEW.author_id IS NOT NULL AND (SELECT id FROM authors WHERE id = NEW.author_id) IS NULL;
        END;
CREATE TRIGGER fku_books_author_id
    BEFORE UPDATE ON [books]
        FOR EACH ROW BEGIN
            SELECT RAISE(ROLLBACK, 'update on table &#034;books&#034; violates foreign key constraint &#034;fku_books_author_id&#034;')
            WHERE NEW.author_id IS NOT NULL AND (SELECT id FROM authors WHERE id = NEW.author_id) IS NULL;
        END;
CREATE TRIGGER fkdc_books_author_id
    BEFORE DELETE ON authors
        FOR EACH ROW BEGIN
            DELETE FROM books WHERE books.author_id = OLD.id;
        END;
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ec98a0dc">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ec98a0dc').style.display='block';document.getElementById('styled_synthi_4c529ec98a0dc').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> authors <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; first_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; last_name VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">50</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> books <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; author_id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; title VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">100</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> authors_last_name_idx <span style="color: #993333; font-weight: bold;">ON</span> authors<span style="color: #66cc66;">&#40;</span>last_name<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> books_author_id_idx <span style="color: #993333; font-weight: bold;">ON</span> books<span style="color: #66cc66;">&#40;</span>author_id<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">INDEX</span> books_title_idx <span style="color: #993333; font-weight: bold;">ON</span> books<span style="color: #66cc66;">&#40;</span>title<span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fki_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#91;</span>books<span style="color: #66cc66;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> RAISE<span style="color: #66cc66;">&#40;</span>ROLLBACK, <span style="color: #ff0000;">&#8216;insert on table &quot;books&quot; violates foreign key constraint &quot;fki_books_author_id&quot;&#8217;</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> NEW.author_id <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> authors <span style="color: #993333; font-weight: bold;">WHERE</span> id = NEW.author_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; END;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fku_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">UPDATE</span> <span style="color: #993333; font-weight: bold;">ON</span> <span style="color: #66cc66;">&#91;</span>books<span style="color: #66cc66;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">SELECT</span> RAISE<span style="color: #66cc66;">&#40;</span>ROLLBACK, <span style="color: #ff0000;">&#8216;update on table &quot;books&quot; violates foreign key constraint &quot;fku_books_author_id&quot;&#8217;</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">WHERE</span> NEW.author_id <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AND</span> <span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> id <span style="color: #993333; font-weight: bold;">FROM</span> authors <span style="color: #993333; font-weight: bold;">WHERE</span> id = NEW.author_id<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">IS</span> <span style="color: #993333; font-weight: bold;">NULL</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; END;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TRIGGER</span> fkdc_books_author_id</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; BEFORE <span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">ON</span> authors</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">FOR</span> EACH ROW BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #993333; font-weight: bold;">DELETE</span> <span style="color: #993333; font-weight: bold;">FROM</span> books <span style="color: #993333; font-weight: bold;">WHERE</span> books.author_id = OLD.id;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; END; </div>
</li>
</ol>
</div>
</div>
<p>Be sure to check out the wiki, and the source code is all readable there, or download and enjoy. There are still a few edits that need to happen in the comments (like versions need to be updated, and changelogs added and there are a few typos probably still lurking about.)</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=SPDO+1.0b+Release+Candidate+1+http://4cq2x.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;submitHeadline=SPDO+1.0b+Release+Candidate+1" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;submitHeadline=SPDO+1.0b+Release+Candidate+1" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=SPDO+1.0b+Release+Candidate+1&amp;link=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=SPDO+1.0b+Release+Candidate+1&amp;link=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/&amp;title=SPDO+1.0b+Release+Candidate+1" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2009/03/08/spdo-1b-release-candidate-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Foreign Key constraints in SPDO</title>
		<link>http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/</link>
		<comments>http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/#comments</comments>
		<pubDate>Wed, 25 Feb 2009 19:45:13 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[SPDO]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/?p=304</guid>
		<description><![CDATA[While I have long advocated for doing referential integrity in the application space I have also always made use of things like foreign key constraints in PostgreSQL. I know that MySQL has methods for enforcing foreign key constraints in InnoDB tables, but I typically don&#8217;t use InnoDB. And until recently I never thought about using [...]]]></description>
			<content:encoded><![CDATA[<p>While I have long advocated for doing referential integrity in the application space I have also always made use of things like foreign key constraints in PostgreSQL. I know that MySQL has methods for enforcing foreign key constraints in InnoDB tables, but I typically don&#8217;t use InnoDB. And until recently I never thought about using SQLite for anything really serious (you can take this to mean I am thinking about using SQLite for something serious). So I began to look into <a href="http://www.sqlite.org/cvstrac/wiki?p=ForeignKeyTriggers">triggers for SQLite to mimic foreign key constraints</a>. This got me thinking about using triggers in MySQL to do the same thing for MyISAM tables. A quick search <a href="http://dev.mysql.com/tech-resources/articles/mysql-enforcing-foreign-keys.html">turned up the answer</a>. I fully expected foreign key constraints in MySQL 6. Of course this thinking comes from the phrase on MySQL documentation for <a href="http://dev.mysql.com/doc/refman/4.1/en/ansi-diff-foreign-keys.html">4.1</a>, <a href="http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-foreign-keys.html">5.0</a>, <a href="http://dev.mysql.com/doc/refman/5.1/en/ansi-diff-foreign-keys.html">5.1</a>, and (sadly) now <a href="http://dev.mysql.com/doc/refman/6.0/en/ansi-diff-foreign-keys.html">6.0</a>:</p>
<blockquote><p>For storage engines other than <code class="literal">InnoDB</code>,           MySQL Server parses the <code class="literal">FOREIGN KEY</code> syntax           in <code class="literal">CREATE TABLE</code> statements, but           does not use or store it. In the future, the implementation           will be extended to store this information in the table           specification file so that it may be retrieved by           <strong><span><strong class="command">mysqldump</strong></span></strong> and ODBC. At a later stage,           foreign key constraints will be implemented for           <code class="literal">MyISAM</code> tables as well.</p></blockquote>
<p>Wishful thinking aside, I did get a request to add foreign key constraints to the SPDO implementation, so I think I will get started on adding the following:</p>
<ul>
<li>A SPDOException class to throw back useful information (such as foreign key constraint violation)</li>
<li>A method to create tables</li>
<li>A method to add foreign key constraints to tables created by SPDO</li>
</ul>
<p>While I don&#8217;t want to get too convoluted with the structure of SPDO, I do want a well-encapsulated and easy-to-use PDO. In that vein the table creation and addition of foreign key constraints may come about via a Table class that provides a few simple methods to do all these things. I tend to determine my data structure before I begin development and build all my tables first, however, if I am careful about how the Table class is constructed I should be able to build all the tables in whatever RDBMS I happen to be using, with the proper triggers and constraints. entirely programmatically.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Foreign+Key+constraints+in+SPDO+http://5q7ks.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;submitHeadline=Foreign+Key+constraints+in+SPDO" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;submitHeadline=Foreign+Key+constraints+in+SPDO" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Foreign+Key+constraints+in+SPDO&amp;link=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Foreign+Key+constraints+in+SPDO&amp;link=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/&amp;title=Foreign+Key+constraints+in+SPDO" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2009/02/25/foreign-key-constraints-in-spdo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Portable code</title>
		<link>http://www.evardsson.com/blog/2009/02/01/portable-code/</link>
		<comments>http://www.evardsson.com/blog/2009/02/01/portable-code/#comments</comments>
		<pubDate>Mon, 02 Feb 2009 00:57:20 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/?p=298</guid>
		<description><![CDATA[When developing applications against a single RDBMS there is no need to worry about portability. However, when you are developing with the idea that the application may be deployed against any of a range of RDBMSes then you need to start thinking about how you formulate your queries, table structures, etc. While it is common [...]]]></description>
			<content:encoded><![CDATA[<p>When developing applications against a single RDBMS there is no need to worry about portability. However, when you are developing with the idea that the application may be deployed against any of a range of RDBMSes then you need to start thinking about how you formulate your queries, table structures, etc. While it is common practice to have separate classes for working with different databases, there are some things you can do to make that even easier.</p>
<p><strong>ENUMs are EVIL</strong></p>
<p>Developers who spend a lot of time developing against MySQL get into the habit of creating ENUM fields. (I will admit a certain amount of guilt here, too). This is not only not portable, but it doesn&#8217;t work quite the way you would expect. Even though the values in the ENUM are meant to be the only values you can insert into that field, MySQL does not enforce this quite the way you might think it should.</p>
<p>As an example:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecb2536d">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecb2536d').style.display='block';document.getElementById('plain_synthi_4c529ecb2536d').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
CREATE TABLE enumevil (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    evil ENUM('foo','bar','baz') NOT NULL DEFAULT 'foo'
);
Query OK, 0 rows affected (0.01 sec)
INSERT INTO enumevil (evil) VALUES ('bip');
Query OK, 1 row affected, 1 warning (0.02 sec)
SELECT * FROM enumevil;
+----+------+
| id | evil |
+----+------+
|  1 |      |
+----+------+
1 row IN SET (0.00 sec)
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecb2536d">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecb2536d').style.display='block';document.getElementById('styled_synthi_4c529ecb2536d').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> enumevil <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; evil ENUM<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;foo&#8217;</span>,<span style="color: #ff0000;">&#8216;bar&#8217;</span>,<span style="color: #ff0000;">&#8216;baz&#8217;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">DEFAULT</span> <span style="color: #ff0000;">&#8216;foo&#8217;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">Query OK, <span style="color: #cc66cc;">0</span> rows affected <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.01</span> sec<span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> enumevil <span style="color: #66cc66;">&#40;</span>evil<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;bip&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">Query OK, <span style="color: #cc66cc;">1</span> row affected, <span style="color: #cc66cc;">1</span> warning <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.02</span> sec<span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">SELECT</span> * <span style="color: #993333; font-weight: bold;">FROM</span> enumevil;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">+<span style="color: #808080; font-style: italic;">&#8212;-+&#8212;&#8212;+</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">| id | evil |</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">+<span style="color: #808080; font-style: italic;">&#8212;-+&#8212;&#8212;+</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">|&nbsp; <span style="color: #cc66cc;">1</span> |&nbsp; &nbsp; &nbsp; | </div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">+<span style="color: #808080; font-style: italic;">&#8212;-+&#8212;&#8212;+</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #cc66cc;">1</span> row <span style="color: #993333; font-weight: bold;">IN</span> <span style="color: #993333; font-weight: bold;">SET</span> <span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">0.00</span> sec<span style="color: #66cc66;">&#41;</span> </div>
</li>
</ol>
</div>
</div>
<p>Rather than spitting back an error, it quietly sets the value of the ENUM field to the empty string. That is not in the list of allowed values nor is it the default. So you are left with checking the values in code before inserting (which you should do anyway &#8211; see the next section on referential integrity.)</p>
<p>Instead of using an ENUM field consider this:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecb2b944">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecb2b944').style.display='block';document.getElementById('plain_synthi_4c529ecb2b944').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
CREATE TABLE noevil_enum_choice (
    choice VARCHAR(3) NOT NULL PRIMARY KEY
);
INSERT INTO noevil_enum_choice VALUES ('foo');
INSERT INTO noevil_enum_choice VALUES ('bar');
INSERT INTO noevil_enum_choice VALUES ('baz');
CREATE TABLE noevil (
    id INTEGER NOT NULL AUTO_INCREMENT PRIMARY KEY,
    choice VARCHAR(3) NOT NULL REFERENCES noevil_enum_choice.choice
);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecb2b944">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecb2b944').style.display='block';document.getElementById('styled_synthi_4c529ecb2b944').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> noevil_enum_choice <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; choice VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;foo&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;bar&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;baz&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> noevil <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id INTEGER <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">AUTO_INCREMENT</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; choice VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> noevil_enum_choice.choice</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>Although MySQL does not enforce referential integrity, this is now something can be easily converted to PostgreSQL as:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecb3202d">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecb3202d').style.display='block';document.getElementById('plain_synthi_4c529ecb3202d').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
CREATE TABLE noevil_enum_choice (
    choice VARCHAR(3) NOT NULL PRIMARY KEY
);
INSERT INTO noevil_enum_choice VALUES ('foo');
INSERT INTO noevil_enum_choice VALUES ('bar');
INSERT INTO noevil_enum_choice VALUES ('baz');
CREATE TABLE noevil (
    id SERIAL PRIMARY KEY,
    choice VARCHAR(3) NOT NULL REFERENCES noevil_enum_choice(choice)
);
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecb3202d">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecb3202d').style.display='block';document.getElementById('styled_synthi_4c529ecb3202d').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> noevil_enum_choice <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; choice VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;foo&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;bar&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">INSERT</span> <span style="color: #993333; font-weight: bold;">INTO</span> noevil_enum_choice <span style="color: #993333; font-weight: bold;">VALUES</span> <span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8216;baz&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">TABLE</span> noevil <span style="color: #66cc66;">&#40;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; id SERIAL <span style="color: #993333; font-weight: bold;">PRIMARY</span> <span style="color: #993333; font-weight: bold;">KEY</span>,</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; choice VARCHAR<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">NOT</span> <span style="color: #993333; font-weight: bold;">NULL</span> <span style="color: #993333; font-weight: bold;">REFERENCES</span> noevil_enum_choice<span style="color: #66cc66;">&#40;</span>choice<span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#41;</span>; </div>
</li>
</ol>
</div>
</div>
<p>And PostgreSQL <em>does</em> enforce referential integrity. This also makes it easier to expand your choice list by just inserting a new row.</p>
<p><strong>Referential Integrity</strong></p>
<p>On the flip-side of the coin, developers who spend a good deal of time developing against PostgreSQL come to rely on the referential integrity built in to that RDBMS. While there is nothing wrong with that, your code should enforce this as well, if you want to be able to move from one RDBMS to another. In the example above we could rely on PostgreSQL&#8217;s REFERENCES statement to kick back an error whenever a bad value (like &#8216;bip&#8217;) is inserted into the choice field of the noevil table. However, as soon as you move your application to MySQL or sqlite it will happily insert anything you like into that field (with MySQL truncating it to three characters).</p>
<p>This is why it is important for your applications to take into consideration their own referential integrity. Here&#8217;s some python to illustrate:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecb384b3">
<div class="synthi_header" style="font-weight:bold;"> Python <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecb384b3').style.display='block';document.getElementById('plain_synthi_4c529ecb384b3').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
import string
from spdo import *

class noevil(object):
    __init__(self, choice):
        self.db = SPDO('test')
        self.choices = []
        mydict = self.db.select(&#034;SELECT * FROM noevil_enum_choice&#034;)
        for c in mydict:
            self.choices.append(c['choice'])
        if choice not in choices:
            ex[] = [&#034;Invalid value for choice: &#034;, choice, &#034; Valid options are: &#034;]
            for c in self.choices:
                ex.append[c]
                ex.append[&#034; &#034;]
            raise Exception(string.join(ex, ''))
        # continue with normal processing here
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecb384b3">
<div class="synthi_header" style="font-weight:bold;"> Python <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecb384b3').style.display='block';document.getElementById('styled_synthi_4c529ecb384b3').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="python" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #ff7700;font-weight:bold;">import</span> <span style="color: #dc143c;">string</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #ff7700;font-weight:bold;">from</span> spdo <span style="color: #ff7700;font-weight:bold;">import</span> *</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #ff7700;font-weight:bold;">class</span> noevil<span style="color: black;">&#40;</span><span style="color: #008000;">object</span><span style="color: black;">&#41;</span>:</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; <span style="color: #0000cd;">__init__</span><span style="color: black;">&#40;</span><span style="color: #008000;">self</span>, choice<span style="color: black;">&#41;</span>:</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">db</span> = SPDO<span style="color: black;">&#40;</span><span style="color: #483d8b;">&#8216;test&#8217;</span><span style="color: black;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">choices</span> = <span style="color: black;">&#91;</span><span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; mydict = <span style="color: #008000;">self</span>.<span style="color: black;">db</span>.<span style="color: #dc143c;">select</span><span style="color: black;">&#40;</span><span style="color: #483d8b;">&quot;SELECT * FROM noevil_enum_choice&quot;</span><span style="color: black;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> c <span style="color: #ff7700;font-weight:bold;">in</span> mydict:</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #008000;">self</span>.<span style="color: black;">choices</span>.<span style="color: black;">append</span><span style="color: black;">&#40;</span>c<span style="color: black;">&#91;</span><span style="color: #483d8b;">&#8216;choice&#8217;</span><span style="color: black;">&#93;</span><span style="color: black;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">if</span> choice <span style="color: #ff7700;font-weight:bold;">not</span> <span style="color: #ff7700;font-weight:bold;">in</span> choices:</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex<span style="color: black;">&#91;</span><span style="color: black;">&#93;</span> = <span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot;Invalid value for choice: &quot;</span>, choice, <span style="color: #483d8b;">&quot; Valid options are: &quot;</span><span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">for</span> c <span style="color: #ff7700;font-weight:bold;">in</span> <span style="color: #008000;">self</span>.<span style="color: black;">choices</span>:</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.<span style="color: black;">append</span><span style="color: black;">&#91;</span>c<span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ex.<span style="color: black;">append</span><span style="color: black;">&#91;</span><span style="color: #483d8b;">&quot; &quot;</span><span style="color: black;">&#93;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #ff7700;font-weight:bold;">raise</span> <span style="color: #008000;">Exception</span><span style="color: black;">&#40;</span><span style="color: #dc143c;">string</span>.<span style="color: black;">join</span><span style="color: black;">&#40;</span>ex, <span style="color: #483d8b;">&#8221;</span><span style="color: black;">&#41;</span><span style="color: black;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; &nbsp; &nbsp; &nbsp; <span style="color: #808080; font-style: italic;"># continue with normal processing here </span></div>
</li>
</ol>
</div>
</div>
<p>This is by no means the entirety of the topic, or even more than merest tip of the iceberg, but it is a good place to start.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Portable+code+http://zobcy.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;submitHeadline=Portable+code" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;submitHeadline=Portable+code" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Portable+code&amp;link=http://www.evardsson.com/blog/2009/02/01/portable-code/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Portable+code&amp;link=http://www.evardsson.com/blog/2009/02/01/portable-code/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/02/01/portable-code/&amp;title=Portable+code" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2009/02/01/portable-code/feed/</wfw:commentRss>
		<slash:comments>3</slash:comments>
		</item>
		<item>
		<title>UUID Why and How</title>
		<link>http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/</link>
		<comments>http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 20:21:49 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[Development]]></category>
		<category><![CDATA[PostgresQL]]></category>
		<category><![CDATA[uuid]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/?p=278</guid>
		<description><![CDATA[Seeing the post from Aaron the other day on generating UUIDs in PHP got me to thinking about UUIDs in general. The Why: So why would we want to use UUIDs? The simple answer is that they are (almost) guaranteed to be a &#8220;Universally Unique&#8221; ID. So what? Every database table has its own row [...]]]></description>
			<content:encoded><![CDATA[<p>Seeing the post from Aaron the other day on <a href="http://www.102degrees.com/blog/2009/01/14/php-and-the-uuid/">generating UUIDs in PHP</a> got me to thinking about UUIDs in general.</p>
<p>The Why:</p>
<p>So why would we want to use UUIDs? The simple answer is that they are (almost) guaranteed to be a &#8220;Universally Unique&#8221; ID. So what? Every database table has its own row ids, why do they need to be unique from other database table row ids? Here&#8217;s an example:</p>
<p>Jo has three stores X, Y and Z. Each store has a local customer database. That database contains the following table structures:</p>
<pre>persons:
  id
  name

phones:
  id
  person_id
  phone_number</pre>
<p>(I didn&#8217;t say the tables were all that useful, but they work for the sake of discussion.)</p>
<p>Jo looks at the tables from all three stores and decides that it might be a good idea to combine them into one master customer database to share with all the stores. Here is where the trouble starts. When we compare the three databases we find that we cannot simply dump the data from any one of the databases into any of the others.</p>
<table border="1">
<tr>
<th>Store X</th>
<th>Store Y</th>
<th>Store Z</th>
</tr>
<tr>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>1</td>
<td colspan="2">Sam Smith</td>
</tr>
<tr>
<td>2</td>
<td colspan="2">Terry Tyler</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>(555)555-1212</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>(555)555-1234</td>
</tr>
<tr>
<td>3</td>
<td>1</td>
<td>(555)555-4321</td>
</tr>
</table>
</td>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>1</td>
<td colspan="2">Perry Paxson</td>
</tr>
<tr>
<td>2</td>
<td colspan="2">Jeremiah Jones</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>(555)555-2121</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>(555)555-4412</td>
</tr>
</table>
</td>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>1</td>
<td colspan="2">Edie Ellerts</td>
</tr>
<tr>
<td>2</td>
<td colspan="2">Francis Fenimore</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>1</td>
<td>1</td>
<td>(555)555-3434</td>
</tr>
<tr>
<td>2</td>
<td>2</td>
<td>(555)555-7214</td>
</tr>
<tr>
<td>3</td>
<td>2</td>
<td>(555)555-9951</td>
</tr>
</table>
</td>
</tr>
</table>
<p>While this makes it simple in terms of looking up a customer&#8217;s phone number(s) on a single store, <code>SELECT * FROM persons, phones WHERE phones.person_id = persons.person_id AND persons.name = 'Sam Smith'</code>, it leaves us in a tight spot where it comes to combining the databases. We either have to pull all the data programmatically and retain the references from phones to persons and re-insert the whole mess into a new set of tables, or we need to add another field to define which store database the record comes from and change the primary key from the single value (id) to a multiple-field key (id, store_name). This means, of course, that everywhere we reference these values in our code we need to change the SQL. Not a happy solution.</p>
<p>So what if we change the id field type from an integer to a UUID (which is a char(36))? Now our tables would look like:</p>
<table border="1">
<tr>
<th>Store X</th>
</tr>
<tr>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>7d20cac1-d558-4a5c-98c0-ee332b554b29</td>
<td colspan="2">Sam Smith</td>
</tr>
<tr>
<td>5fae5033-36e0-42f8-bb50-c00449c6cab0</td>
<td colspan="2">Terry Tyler</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>82eec34b-897b-40af-9674-fa08e5537d12</td>
<td>7d20cac1-d558-4a5c-98c0-ee332b554b29</td>
<td>(555)555-1212</td>
</tr>
<tr>
<td>08400e86-9bd0-4713-bf6e-a5b8cd3e7e22</td>
<td>5fae5033-36e0-42f8-bb50-c00449c6cab0</td>
<td>(555)555-1234</td>
</tr>
<tr>
<td>ab64d8d7-0511-4b8e-ab57-9932c3c96b31</td>
<td>7d20cac1-d558-4a5c-98c0-ee332b554b29</td>
<td>(555)555-4321</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>Store Y</th>
</tr>
<tr>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>9ca534e4-2dbd-4dc3-a7b3-98ab8b89fb70</td>
<td colspan="2">Perry Paxson</td>
</tr>
<tr>
<td>4cc10585-b864-45bc-9f20-f9761af82e06</td>
<td colspan="2">Jeremiah Jones</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>85302b40-c12b-4a05-8dbb-500f6f5cb26f</td>
<td>9ca534e4-2dbd-4dc3-a7b3-98ab8b89fb70</td>
<td>(555)555-2121</td>
</tr>
<tr>
<td>106a9524-800c-4e5a-ad4a-6ac9f601b370</td>
<td>4cc10585-b864-45bc-9f20-f9761af82e06</td>
<td>(555)555-4412</td>
</tr>
</table>
</td>
</tr>
<tr>
<th>Store Z</th>
</tr>
<tr>
<td valign="top">
<table border="0">
<tr>
<th colspan="3" bgcolor="#CCCC66">persons</th>
</tr>
<tr>
<td>id</td>
<td colspan="2">name</td>
</tr>
<tr>
<td>4da59fb9-ad00-4a5b-aa00-1bb503fe9c8f</td>
<td colspan="2">Edie Ellerts</td>
</tr>
<tr>
<td>8a39f12c-94c4-4b70-ac70-3cff77be8b01</td>
<td colspan="2">Francis Fenimore</td>
</tr>
<tr>
<th colspan="3" bgcolor="#CCCC66">phones</th>
</tr>
<tr>
<td>id</td>
<td>person_id</td>
<td>phone_number</td>
</tr>
<tr>
<td>47d0c49e-02df-4366-853b-a0502edb1de6</td>
<td>4da59fb9-ad00-4a5b-aa00-1bb503fe9c8f</td>
<td>(555)555-3434</td>
</tr>
<tr>
<td>cb868eca-822f-416a-ac7f-0df12504705f</td>
<td>8a39f12c-94c4-4b70-ac70-3cff77be8b01</td>
<td>(555)555-7214</td>
</tr>
<tr>
<td>e70bea84-66e8-407f-bb6c-b164864d22b1</td>
<td>8a39f12c-94c4-4b70-ac70-3cff77be8b01</td>
<td>(555)555-9951</td>
</tr>
</table>
</td>
</tr>
</table>
<p>We now have referential data that we can safely combine into a single database, and can even dump back into all the store local database copies.</p>
<p>The How:</p>
<p>When I need to generate my own UUIDs I certainly use the exact same code as Aaron, even cribbed from the <a href="http://docs.php.net/manual/nl/function.uniqid.php#69164">exact same source</a>. Of course Python has a UUID module which means you can create a version 1, 3, 4 or 5 UUID quickly and easily. I prefer the version 4 UUIDs myself, since version 1 contains identifiable data about the source, and versions 3 and 5 require other information to generate. (In case you are wondering, there is no version 2).</p>
<p>This is simple enough, but I actually prefer things a little simpler, and when I am using PostgreSQL they do get simpler as I can let the database do the UUID generation. (I am aware of the uuid() function that is built in to MySQL 5, however, that uses version 1 UUIDs which contain system identifiable data. If that is okay with you then by all means feel free to use it.) While there are at least a couple PostgreSQL plugins I have seen for generating UUIDs I actually make use of the CREATE FUNCTION capabilities of PostgreSQL to roll my own. (NOTE: To use this function you must have the PostgreSQL cryptographic libraries installed.)</p>
<p>So first I need to see what I am trying to generate.</p>
<p>From the RFC:</p>
<blockquote><p>
<b>4.4. Algorithms for Creating a UUID from Truly Random or Pseudo-Random Numbers</b></p>
<p>   The version 4 UUID is meant for generating UUIDs from truly-random or<br />
   pseudo-random numbers.</p>
<p>   The algorithm is as follows:</p>
<ul>
<li><span style="background-color:#6699FF">Set the two most significant bits (bits 6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively.</span></li>
<li><span style="background-color:#66FF00">Set the four most significant bits (bits 12 through 15) of the time_hi_and_version field to the 4-bit version number from Section 4.1.3.</span></li>
<li>Set all the other bits to randomly (or pseudo-randomly) chosen values.</li>
</ul>
</blockquote>
<p>The format:<br />
xxxxxxxx-xxxx-<span style="background-color:#66FF00">x</span>xxx-<span style="background-color:#6699FF">x</span>xxx-xxxxxxxxxxxx</p>
<p>[For more in-depth analysis of how a UUID is constructed refer to <a href="http://tools.ietf.org/html/rfc4122">http://tools.ietf.org/html/rfc4122</a>]</p>
<p>Creating a version 4 UUID requires a bunch of random hexadecimal data, with one hexadecimal character (<span style="background-color:#66FF00">x</span>) (equivalent to a nibble &#8211; 4 bits for those of you who don&#8217;t recall) set to the value of 4 (binary 0100 from Section 4.1.3 of the RFC) and one hexadecimal character (<span style="background-color:#6699FF">x</span>) set to one of 4 values: 8, 9, a or b; which is what the first nibble of a byte is when the two most significant bits are 10. For proof of this see below:</p>
<table border="1">
<tr>
<th colspan="4" bgcolor="#CCCC66">Bit</th>
<td></td>
<td></td>
</tr>
<tr>
<th bgcolor="#CCCC66">3</th>
<th bgcolor="#CCCC66">2</th>
<th bgcolor="#CCCC66">1</th>
<th bgcolor="#CCCC66">0</th>
<th bgcolor="#CCCC66">Hex</th>
<th bgcolor="#CCCC66">Dec</th>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
<td>0</td>
<td>8</td>
<td>8</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>0</td>
<td>1</td>
<td>9</td>
<td>9</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>0</td>
<td>a</td>
<td>10</td>
</tr>
<tr>
<td>1</td>
<td>0</td>
<td>1</td>
<td>1</td>
<td>b</td>
<td>11</td>
</tr>
</table>
<p>Now let&#8217;s look at what means we have for generating random data in hexadecimal format. PostgreSQL includes a random() function which generates a double precision number between 0 and 1. We also have a to_hex() function that will convert integer or binary string data to a hexadecimal number. This is a start, but we really don&#8217;t want to be calling random() more often than we need to, so is there a way to generate a bunch of hexadecimal data at one shot? Actually, there is, if we just add a sha1 function. So let&#8217;s start there:</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecbc1c33">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecbc1c33').style.display='block';document.getElementById('plain_synthi_4c529ecbc1c33').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
CREATE OR REPLACE FUNCTION sha1(text)
  RETURNS character AS
$BODY$
BEGIN
RETURN ENCODE(DIGEST($1, 'sha1'), 'hex');
END;
$BODY$
  LANGUAGE 'plpgsql';
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecbc1c33">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecbc1c33').style.display='block';document.getElementById('styled_synthi_4c529ecbc1c33').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> sha1<span style="color: #66cc66;">&#40;</span>text<span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; RETURNS character <span style="color: #993333; font-weight: bold;">AS</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">$BODY$</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">BEGIN</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">RETURN</span> ENCODE<span style="color: #66cc66;">&#40;</span>DIGEST<span style="color: #66cc66;">&#40;</span>$<span style="color: #cc66cc;">1</span>, <span style="color: #ff0000;">&#8216;sha1&#8242;</span><span style="color: #66cc66;">&#41;</span>, <span style="color: #ff0000;">&#8216;hex&#8217;</span><span style="color: #66cc66;">&#41;</span>;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">END;</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">$BODY$</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; <span style="color: #993333; font-weight: bold;">LANGUAGE</span> <span style="color: #ff0000;">&#8216;plpgsql&#8217;</span>; </div>
</li>
</ol>
</div>
</div>
<p>Now we have a quick way to generate lots of hexadecimal characters, all we need now is to randomize, and format according to what we have stated above.</p>
<div class="synthi_code" style="display:none;" id ="plain_synthi_4c529ecbc4b63">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('styled_synthi_4c529ecbc4b63').style.display='block';document.getElementById('plain_synthi_4c529ecbc4b63').style.display='none';return false">Show Styled Code</a>]:</span></div>
<pre style="width:100%;overflow:auto;">
CREATE OR REPLACE FUNCTION uuid()
  RETURNS character AS
$BODY$
SELECT SUBSTRING(x.my_rand FROM 1 FOR 8)||'-'||SUBSTRING(x.my_rand FROM 9 FOR 4)||'-4'||SUBSTRING(x.my_rand FROM 13 FOR 3)||'-'||x.clock_1||SUBSTRING(x.my_rand FROM 16 FOR 3)||'-'||SUBSTRING(x.my_rand FROM 19 FOR 12)
FROM
(SELECT sha1(''||now()||random()) as my_rand, to_hex(8+(3*random())::int) as clock_1) as x;$BODY$
  LANGUAGE 'sql';
</pre>
</div>
<div class="synthi_code" style="display:block;" id ="styled_synthi_4c529ecbc4b63">
<div class="synthi_header" style="font-weight:bold;"> SQL <span  class="synthi_button"style="font-weight:lighter;font-size:smaller;">[<a href="#" onClick="javascript:document.getElementById('plain_synthi_4c529ecbc4b63').style.display='block';document.getElementById('styled_synthi_4c529ecbc4b63').style.display='none';return false">Show Plain Code</a>]:</span></div>
<div class="sql" style="font-family: monospace;">
<ol>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">CREATE</span> <span style="color: #993333; font-weight: bold;">OR</span> <span style="color: #993333; font-weight: bold;">REPLACE</span> <span style="color: #993333; font-weight: bold;">FUNCTION</span> uuid<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; RETURNS character <span style="color: #993333; font-weight: bold;">AS</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">$BODY$</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">SELECT</span> SUBSTRING<span style="color: #66cc66;">&#40;</span>x.my_rand <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #cc66cc;">1</span> <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">8</span><span style="color: #66cc66;">&#41;</span>||<span style="color: #ff0000;">&#8216;-&#8217;</span>||SUBSTRING<span style="color: #66cc66;">&#40;</span>x.my_rand <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #cc66cc;">9</span> <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">4</span><span style="color: #66cc66;">&#41;</span>||<span style="color: #ff0000;">&#8216;-4&#8242;</span>||SUBSTRING<span style="color: #66cc66;">&#40;</span>x.my_rand <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #cc66cc;">13</span> <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>||<span style="color: #ff0000;">&#8216;-&#8217;</span>||x.clock_1||SUBSTRING<span style="color: #66cc66;">&#40;</span>x.my_rand <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #cc66cc;">16</span> <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">3</span><span style="color: #66cc66;">&#41;</span>||<span style="color: #ff0000;">&#8216;-&#8217;</span>||SUBSTRING<span style="color: #66cc66;">&#40;</span>x.my_rand <span style="color: #993333; font-weight: bold;">FROM</span> <span style="color: #cc66cc;">19</span> <span style="color: #993333; font-weight: bold;">FOR</span> <span style="color: #cc66cc;">12</span><span style="color: #66cc66;">&#41;</span></div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #993333; font-weight: bold;">FROM</span>&nbsp; </div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;"><span style="color: #66cc66;">&#40;</span><span style="color: #993333; font-weight: bold;">SELECT</span> sha1<span style="color: #66cc66;">&#40;</span><span style="color: #ff0000;">&#8221;</span>||now<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span>||random<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> my_rand, to_hex<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">8</span>+<span style="color: #66cc66;">&#40;</span><span style="color: #cc66cc;">3</span>*random<span style="color: #66cc66;">&#40;</span><span style="color: #66cc66;">&#41;</span><span style="color: #66cc66;">&#41;</span>::int<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> clock_1<span style="color: #66cc66;">&#41;</span> <span style="color: #993333; font-weight: bold;">AS</span> x;$BODY$</div>
</li>
<li style="font-weight: bold;">
<div style="font-family: 'Courier New', Courier, monospace; font-weight: normal; font-size: 1.2em;">&nbsp; <span style="color: #993333; font-weight: bold;">LANGUAGE</span> <span style="color: #ff0000;">&#8216;sql&#8217;</span>; </div>
</li>
</ol>
</div>
</div>
<p>Notice that we are using now() to grab the current timestamp (including milliseconds), and concatenating that with the output of random to feed to sha1() to generate a hex digest. We are also generating a value of either 8, 9, a, or b for the first nibble in the clock_seq_hi field (the character highlighted in blue) by adding the value of 3 * random() cast as an integer to 8 and then returning that as a hex value. We then use SUBSTRING to pull the number of characters we need for each chunk and keep on moving left to right in the hash to grab the next values and concatenate them with dashes where needed and our version number.</p>
<p>For this and other PostgreSQL functions I use regularly you can <a href="http://www.evardsson.com/files/postgres_crypt.sql">download this SQL file</a>.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=UUID+Why+and+How+http://ztokb.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;submitHeadline=UUID+Why+and+How" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;submitHeadline=UUID+Why+and+How" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=UUID+Why+and+How&amp;link=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=UUID+Why+and+How&amp;link=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/&amp;title=UUID+Why+and+How" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2009/01/15/uuid-why-and-how/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Drizzle &#8211; Lightweight DB Based on MySQL</title>
		<link>http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/</link>
		<comments>http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/#comments</comments>
		<pubDate>Thu, 24 Jul 2008 00:12:57 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Open Source]]></category>
		<category><![CDATA[Drizzle]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/?p=237</guid>
		<description><![CDATA[Brain Acker, director of architecture for MySQL has opened the door to Drizzle, a light-weight, high-concurrency database server based on MySQL, targeted at web applications. The architectural ideas as described in the FAQ: A micro-kernel that we then extend to add what we need (all additions come through interfaces that can be compiled/loaded in as [...]]]></description>
			<content:encoded><![CDATA[<p>Brain Acker, director of architecture for <a href="http://www.mysql.com">MySQL</a> has opened the door to <a href="https://launchpad.net/drizzle">Drizzle</a>, a light-weight, high-concurrency database server based on MySQL, targeted at web applications.</p>
<p>The architectural ideas as described in the <a href="http://bazaar.launchpad.net/~drizzle-developers/drizzle/development/annotate/205?file_id=drizzle.faq-20080625052902-61bbthtf22shh0p6-4">FAQ</a>:</p>
<blockquote><p>A micro-kernel that we then extend to add what we need (all additions come through interfaces that can be compiled/loaded in as needed). The target for the project is web infrastructure backend and cloud components.</p></blockquote>
<p>The FAQ goes on explain the differences between Drizzle and MySQL which include:</p>
<blockquote><p>No modes, views, triggers, prepared statements, stored procedures, query cache, data conversion inserts, ACL. Fewer data types.  Less engines, less code. Assume the primary engine is transactional.</p></blockquote>
<p>Michael Widenius, founder and original MySQL developer, explains more about Drizzle in <a href="http://monty-says.blogspot.com/2008/07/what-if.html">this blog post</a>, including the most interesting piece (to me) &#8211; that Drizzle will always contain the most up-to-date InnoDB code, meaning you don&#8217;t need to wait around for MySQL 6 or download the plugins from Oracle each year to get the latest and greatest.</p>
<p>While Drizzle is still in development you can check out the code and try it out. Or maybe even get involved and help out. More information on how to do both is available on the <a href="http://drizzle.wikia.com/wiki/Drizzle_Wiki">wiki</a>.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL+http://5tepq.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;submitHeadline=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;submitHeadline=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL&amp;link=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL&amp;link=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/&amp;title=Drizzle+%E2%80%93+Lightweight+DB+Based+on+MySQL" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2008/07/23/drizzle-lightweight-db-based-on-mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Really BIG Databases</title>
		<link>http://www.evardsson.com/blog/2007/02/15/really-big-databases/</link>
		<comments>http://www.evardsson.com/blog/2007/02/15/really-big-databases/#comments</comments>
		<pubDate>Fri, 16 Feb 2007 07:18:20 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/2007/02/15/really-big-databases/</guid>
		<description><![CDATA[Found this article while digging this evening. It seems that topping this &#8216;Top 10&#8242; list for large databases is The World Data Center for Climate (WDCC), operated by the Max Planck Institute for Meteorology and the German Climate Computing Center. The WDCC has 220 terabytes of web-accessible data, plus another 6 petabytes of additional data. [...]]]></description>
			<content:encoded><![CDATA[<p>Found this <a href="http://www.businessintelligencelowdown.com/2007/02/top_10_largest_.html">article</a> while digging this evening.</p>
<p>It seems that topping this &#8216;Top 10&#8242; list for large databases is <a href="http://www.mad.zmaw.de/wdc-for-climate/">The World Data Center for Climate</a> (WDCC), operated by the <a href="http://www.mpimet.mpg.de/en/home.html">Max Planck Institute for Meteorology</a> and the <a href="http://www.dkrz.de/dkrz/intro_s">German Climate Computing Center</a>.</p>
<p>The WDCC has 220 terabytes of web-accessible data, plus <span style="font-style: italic;">another 6 petabytes</span> of additional data. (Three times the total information in <span style="font-style: italic;">all</span> the US academic research libraries combined.) I would hate to see how that ran on anything slower than their 35 million euro supercomputer!</p>
<p>I should also mention that in the comments section several even larger databases are mentioned in the traditional, post-top-10-anything-countdown, hey-what-about-so-and-so fest.<br /><a class="performancingtags" href="http://technorati.com/tag/database%20WDCC" rel="tag"><br /></a></p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Really+BIG+Databases+http://m6zgs.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;submitHeadline=Really+BIG+Databases" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;submitHeadline=Really+BIG+Databases" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Really+BIG+Databases&amp;link=http://www.evardsson.com/blog/2007/02/15/really-big-databases/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Really+BIG+Databases&amp;link=http://www.evardsson.com/blog/2007/02/15/really-big-databases/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2007/02/15/really-big-databases/&amp;title=Really+BIG+Databases" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2007/02/15/really-big-databases/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>A simple intro to database normalization</title>
		<link>http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/</link>
		<comments>http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/#comments</comments>
		<pubDate>Wed, 30 Aug 2006 22:45:00 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Best Practices]]></category>
		<category><![CDATA[Database]]></category>
		<category><![CDATA[MySQL]]></category>

		<guid isPermaLink="false">http://localhost/wordpress/?p=25</guid>
		<description><![CDATA[I found a very clear, well-written introductory example to database normalization on devshed. Although it is in the MySQL portion of the site, it applies equally well across the board to other RDBMSs. To get more details on normalization, the normal forms, and general good database development in general, check out Database Design for Mere [...]]]></description>
			<content:encoded><![CDATA[<p>I found a very clear, well-written introductory <a href="http://www.devshed.com/c/a/MySQL/An-Introduction-to-Database-Normalization/">example</a> to database normalization on devshed. Although it is in the MySQL portion of the site, it applies equally well across the board to other RDBMSs.</p>
<p>To get more details on normalization, the normal forms, and general good database development in general, check out <a href="http://www.amazon.com/Database-Design-Mere/dp/0201752840/sr=8-1/qid=1156966801/ref=pd_bbs_1/002-0285788-0488009?ie=UTF8">Database Design for Mere Mortals: A Hands-On Guide to Relational Database Design, Second Edition</a> by Michael J. Hernandez. Without a doubt the most useful db development book I&#8217;ve ever laid my hands on.</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=A+simple+intro+to+database+normalization+http://xpyyh.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;submitHeadline=A+simple+intro+to+database+normalization" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;submitHeadline=A+simple+intro+to+database+normalization" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=A+simple+intro+to+database+normalization&amp;link=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=A+simple+intro+to+database+normalization&amp;link=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/&amp;title=A+simple+intro+to+database+normalization" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2006/08/30/a-simple-intro-to-database-normalization/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Why PostgreSQL</title>
		<link>http://www.evardsson.com/blog/2006/03/18/why-postgresql/</link>
		<comments>http://www.evardsson.com/blog/2006/03/18/why-postgresql/#comments</comments>
		<pubDate>Sat, 18 Mar 2006 09:23:00 +0000</pubDate>
		<dc:creator>Sjan Evardsson</dc:creator>
				<category><![CDATA[Database]]></category>
		<category><![CDATA[PostgresQL]]></category>

		<guid isPermaLink="false">http://www.evardsson.com/blog/2006/03/18/why-postgresql/</guid>
		<description><![CDATA[This article about PostgreSQL answers the five most common excuses people give for not trying PostgreSQL, or for sticking with their proprietary RDBMS (such as Oracle or SQL Server). Buzz This Post Delicious Digg This Post Ping This Post Reddit Stumble This Post]]></description>
			<content:encoded><![CDATA[<p>This article about <a href="http://searchopensource.techtarget.com/originalContent/0,289142,sid39_gci1172668,00.html" target="_blank" rel="tag">PostgreSQL</a> answers the five most common excuses people give for not trying PostgreSQL, or for sticking with their proprietary RDBMS (such as Oracle or SQL Server).</p>
<p align="left"><a class="tt" href="http://twitter.com/home/?status=Why+PostgreSQL+http://i9dqi.th8.us" title="Post to Twitter"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-twitter.png" alt="Post to Twitter" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;submitHeadline=Why+PostgreSQL" title="Post to Yahoo Buzz"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-buzz.png" alt="Post to Yahoo Buzz" /></a> <a class="tt" href="http://buzz.yahoo.com/submit?submitUrl=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;submitHeadline=Why+PostgreSQL" title="Post to Yahoo Buzz">Buzz This Post</a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Delicious"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-delicious.png" alt="Post to Delicious" /></a> <a class="tt" href="http://delicious.com/post?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Delicious">Delicious</a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Digg"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-digg.png" alt="Post to Digg" /></a> <a class="tt" href="http://digg.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Digg">Digg This Post</a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Why+PostgreSQL&amp;link=http://www.evardsson.com/blog/2006/03/18/why-postgresql/" title="Post to Ping.fm"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-ping.png" alt="Post to Ping.fm" /></a> <a class="tt" href="http://ping.fm/ref/?method=microblog&amp;title=Why+PostgreSQL&amp;link=http://www.evardsson.com/blog/2006/03/18/why-postgresql/" title="Post to Ping.fm">Ping This Post</a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Reddit"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-reddit.png" alt="Post to Reddit" /></a> <a class="tt" href="http://reddit.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to Reddit">Reddit</a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to StumbleUpon"><img class="nothumb" src="http://www.evardsson.com/blog/wp-content/plugins/tweet-this/icons/tt-su.png" alt="Post to StumbleUpon" /></a> <a class="tt" href="http://stumbleupon.com/submit?url=http://www.evardsson.com/blog/2006/03/18/why-postgresql/&amp;title=Why+PostgreSQL" title="Post to StumbleUpon">Stumble This Post</a></p>]]></content:encoded>
			<wfw:commentRss>http://www.evardsson.com/blog/2006/03/18/why-postgresql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
