<?xml version="1.0" encoding="utf-8" ?>

<rss version="2.0" 
   xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
   xmlns:admin="http://webns.net/mvcb/"
   xmlns:dc="http://purl.org/dc/elements/1.1/"
   xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
   xmlns:wfw="http://wellformedweb.org/CommentAPI/"
   xmlns:content="http://purl.org/rss/1.0/modules/content/"
   >
<channel>
    <title>Postgres OnLine Journal - 8.3</title>
    <link>http://www.postgresonline.com/journal/</link>
    <description>an In depth look at the PostgreSQL open source database</description>
    <dc:language>en</dc:language>
    <generator>Serendipity 1.4.1 - http://www.s9y.org/</generator>
    <pubDate>Fri, 20 Jan 2012 11:09:34 GMT</pubDate>

    <image>
        <url>http://www.postgresonline.com/journal/templates/default/img/s9y_banner_small.png</url>
        <title>RSS: Postgres OnLine Journal - 8.3 - an In depth look at the PostgreSQL open source database</title>
        <link>http://www.postgresonline.com/journal/</link>
        <width>100</width>
        <height>21</height>
    </image>

<item>
    <title>Table Inheritance and the tableoid</title>
    <link>http://www.postgresonline.com/journal/archives/240-Table-Inheritance-and-the-tableoid.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>9.1</category>
            <category>9.2</category>
            <category>beginner</category>
            <category>q&amp;a</category>
    
    <comments>http://www.postgresonline.com/journal/archives/240-Table-Inheritance-and-the-tableoid.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=240</wfw:comment>

    <slash:comments>2</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=240</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;If I could name a number one feature I love most about PostgreSQL, it&#039;s the table inheritance feature which we described in &lt;a href=&quot;http://www.postgresonline.com/journal/archives/59-How-to-Inherit,-Unherit-and-Merge-Inherit.html&quot; target=&quot;_blank&quot;&gt;How to Inherit and Uninherit&lt;/a&gt;. A lot of people use it for table partitioning using &lt;a href=&quot;http://www.postgresonline.com/journal/archives/27-Reading-PgAdmin-Graphical-Explain-Plans.html&quot; target=&quot;_blank&quot;&gt;CONSTRAINT EXCLUSION&lt;/a&gt;.  Aside from that, in combination with PostgreSQL schema search_path (customizable by user and/or database) it makes for a very flexible abstraction tool.  For example, for many of our web apps that service many departments where each department/client wants to keep a high level of autonomy, we have a schema set aside for each 
that inherits from a master template schema.  Each department site uses a different set of accounts with the primary schema being that of the department/client so that they are hitting their own  tables. &lt;/p&gt;
&lt;p&gt;Inheritance allows us to keep data separate,do roll-up reports if we need to, use the same application front-end, and yet allows us the ability to add new columns in just one place (the master template schema).  It is more flexible than other approaches because for example we may have a city organization that need to share tables, like for example a system loaded list of funding source shared across the agency.  We can set aside these shared tables in a separate schema visible to all or have some have their own copy they can change if they don&#039;t want to use the shared one.&lt;/p&gt;

&lt;p&gt;Every once in a while, we find ourselves needing to query the whole hierarchy and needing to know which table the results of the query are coming from. To help
solve that issue, we employ the use of the system column &lt;b&gt;tableoid&lt;/b&gt; which all user tables have. The tableoid is the the object id of a table.  PostgreSQL has many system columns that you have to explicitly select
and can&#039;t be accessed with a SELECT * with the tableoid being one of them.  These are: tableoid, cmax,cmin, xmin,xmax,ctid which are all described in &lt;a href=&quot;http://www.postgresql.org/docs/9.1/static/ddl-system-columns.html&quot; target=&quot;_blank&quot;&gt;System Columns&lt;/a&gt;.  The &lt;a href=&quot;http://www.postgresql.org/docs/9.1/static/ddl-inherit.html&quot; target=&quot;_blank&quot;&gt;PostgreSQL docs on inheritance&lt;/a&gt; have examples of using it, but we thought it worthwile to repeat the exercise since it&#039;s not that common knowledge and is unique enough feature of PostgreSQL that others coming from other relational databases, may miss the treat.  I&#039;ve often demonstrated
it to non-PostgreSQL users who use for example SQL Server or MySQL, and they literally fall out of their chair when I show the feature to them and its endless possibilities.&lt;/p&gt;   &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/240-Table-Inheritance-and-the-tableoid.html#extended&quot;&gt;Continue reading &quot;Table Inheritance and the tableoid&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 16 Jan 2012 05:52:54 -0500</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/240-guid.html</guid>
    
</item>
<item>
    <title>Using PgAdmin PLPgSQL Debugger</title>
    <link>http://www.postgresonline.com/journal/archives/214-Using-PgAdmin-PLPgSQL-Debugger.html</link>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>9.1</category>
            <category>basics</category>
            <category>gis</category>
            <category>intermediate</category>
            <category>pgadmin</category>
            <category>plpgsql</category>
    
    <comments>http://www.postgresonline.com/journal/archives/214-Using-PgAdmin-PLPgSQL-Debugger.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=214</wfw:comment>

    <slash:comments>9</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=214</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;I&#039;m one of those old-fashioned folks that debugs with print lines and raise notices.  They&#039;re nice.
They always work, you can put clock time stops in there and don&#039;t require any fancy configuration.  
At a certain point you do have to pull out a real debugger to see what is going on.  This often
happens when your one-liners are no longer good enough and now you have to write 20 liners of plpgsql code.&lt;/p&gt;

&lt;p&gt;Such is the case with geocoding and the &lt;a href=&quot;http://www.postgis.org/documentation/manual-svn/Extras.html#Tiger_Geocoder&quot; target=&quot;_blank&quot;&gt;PostGIS tiger geocoder&lt;/a&gt; specifically.  Lots of interest has revived
on that with people submitting bug reports and we&#039;ve got paying clients in need of a fairly easy and speedy drop-in geocoder
that can be molded to handle such things as road way locations, badly mis-spelled real estate data, or just simply
to get rid of their dependency on Google, Yahoo, MapQuest, ESRI and other online or pricey geocoding tools.
So I thought I&#039;d take this opportunity to supplement our old-fashioned debugging with plpgsqldebugger goodness.
In this article, we&#039;ll show you how to configure the plpgsql debugger integrated in PgAdmin and run with it.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/214-Using-PgAdmin-PLPgSQL-Debugger.html#extended&quot;&gt;Continue reading &quot;Using PgAdmin PLPgSQL Debugger&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 27 Jun 2011 01:49:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/214-guid.html</guid>
    <category>debugging</category>
<category>pgadmin</category>

</item>
<item>
    <title>Conditional Uniqueness with Partial Indexes</title>
    <link>http://www.postgresonline.com/journal/archives/195-Conditional-Uniqueness-with-Partial-Indexes.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>9.1</category>
            <category>beginner</category>
            <category>postgresql versions</category>
            <category>q&amp;a</category>
            <category>sql server</category>
    
    <comments>http://www.postgresonline.com/journal/archives/195-Conditional-Uniqueness-with-Partial-Indexes.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=195</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=195</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;b&gt;Question&lt;/b&gt;&lt;p&gt;You have a system of products and categories and you want a product to be allowed to be in multiple categories, but you want a product to only be allowed to be in one main category.
How do you enforce this rule in the database?&lt;/p&gt;

&lt;p&gt;Some people will say -- why can&#039;t you just deal with this in your application logic. Our general reason is that much of our updating doesn&#039;t happen at our application level. We like enforcing rules at the database
level because it saves us from ourselves. We are in the business of massaging data.  For this particular kind of example we wanted to make sure the database would provide us a nice safety net so that 
we wouldn&#039;t accidentally assign a product in two main categories.&lt;/p&gt;

&lt;b&gt;Answer&lt;/b&gt;
&lt;p&gt;There are two approaches we thought of.  One is the obvious have a primary category column and a bridge table that has secondary categories.  That is an ugly solution because when you do a query you have to do a union
and always treat the secondary categories as different from the main.  For most use-cases we don&#039;t usually care about distinguisihing primary from secondary category.&lt;/p&gt;

&lt;p&gt;The solution we finally settled on was to have one bridge table with a boolean field for if its the main category.  We enforce the only one main category requirement using a partial index.  Now not all databases support partial indexes
This is one major value of using PostgreSQL that you have so many more options for implementing logic.  &lt;/p&gt;

&lt;div style=&quot;background-color:yellow&quot;&gt;As some people noted in the comments and the reddit entry.  SQL Server 2008 has a similar feature called Filtered Indexes.  Though PostgreSQL has had partial indexes for as far back as I can remember.  This brings up an interesting point which I have observed -- if you were using PostgreSQL before, you would already know how to use the Filtered Indexes, Multi row inserts introduced in SQL Server 2008, and the SEQUENCES feature coming in SQL Server 2010. So we should all use PostgreSQL, because it teaches us how to use the newer versions of SQL Server before they come out. :)&lt;/div&gt;

&lt;p&gt;So how does the partial index solution look:  NOTE for simplicity, we are leaving out all the complimentary tables and the foreign key constraints that we also have in place.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax0&quot;&gt;&lt;span class=&quot;syntax-KEYWORD1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;TABLE&lt;/span&gt; products_categories
&lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;
  category_id &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NULL&lt;/span&gt;,
  product_id &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NULL&lt;/span&gt;,
  main boolean &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;DEFAULT&lt;/span&gt; false,
  orderby &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;integer&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NOT&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;NULL&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;DEFAULT&lt;/span&gt; &lt;span class=&quot;syntax-DIGIT&quot;&gt;0&lt;/span&gt;,
  &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;CONSTRAINT&lt;/span&gt; products_categories_pkey &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;PRIMARY&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;KEY&lt;/span&gt; &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;category_id, product_id&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;;

&lt;span class=&quot;syntax-KEYWORD1&quot;&gt;CREATE&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;UNIQUE&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;INDEX&lt;/span&gt; idx_products_categories_primary
  &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;ON&lt;/span&gt; products_categories
  USING btree
  &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;product_id&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;WHERE&lt;/span&gt; main &lt;span class=&quot;syntax-OPERATOR&quot;&gt;=&lt;/span&gt; true;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Testing it out.  It saves us and gives us a nice informative message to boot.&lt;/p&gt;
&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;syntax0&quot;&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;now&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;we&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;test&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;our&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;safety&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;net&lt;/span&gt;
&lt;span class=&quot;syntax-KEYWORD1&quot;&gt;INSERT&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;INTO&lt;/span&gt; &lt;span class=&quot;syntax-FUNCTION&quot;&gt;products_categories&lt;/span&gt;&lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;category_id, product_id, main&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;syntax-KEYWORD1&quot;&gt;VALUES&lt;/span&gt; &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-DIGIT&quot;&gt;1&lt;/span&gt;,&lt;span class=&quot;syntax-DIGIT&quot;&gt;2&lt;/span&gt;,true&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-DIGIT&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;syntax-DIGIT&quot;&gt;2&lt;/span&gt;,false&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-DIGIT&quot;&gt;3&lt;/span&gt;,&lt;span class=&quot;syntax-DIGIT&quot;&gt;3&lt;/span&gt;,true&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;, &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-DIGIT&quot;&gt;4&lt;/span&gt;,&lt;span class=&quot;syntax-DIGIT&quot;&gt;2&lt;/span&gt;,true&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;;


&lt;span class=&quot;syntax-COMMENT1&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;which&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;gives&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;us&lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt; &lt;/span&gt;&lt;span class=&quot;syntax-COMMENT1&quot;&gt;error&lt;/span&gt;
&lt;span class=&quot;syntax-LABEL&quot;&gt;ERROR&lt;/span&gt;&lt;span class=&quot;syntax-LABEL&quot;&gt;:&lt;/span&gt;  duplicate &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;key&lt;/span&gt; value violates &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;unique&lt;/span&gt; &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;constraint&lt;/span&gt; &lt;span class=&quot;syntax-LITERAL1&quot;&gt;&amp;quot;&lt;/span&gt;&lt;span class=&quot;syntax-LITERAL1&quot;&gt;idx_products_categories_primary&lt;/span&gt;&lt;span class=&quot;syntax-LITERAL1&quot;&gt;&amp;quot;&lt;/span&gt;
&lt;span class=&quot;syntax-LABEL&quot;&gt;DETAIL&lt;/span&gt;&lt;span class=&quot;syntax-LABEL&quot;&gt;:&lt;/span&gt;  &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;Key&lt;/span&gt; &lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;product_id&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;syntax-OPERATOR&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;syntax-OPERATOR&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;syntax-DIGIT&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;syntax-OPERATOR&quot;&gt;)&lt;/span&gt; already &lt;span class=&quot;syntax-KEYWORD1&quot;&gt;exists&lt;/span&gt;.
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt; 
    </content:encoded>

    <pubDate>Sat, 19 Feb 2011 23:12:00 -0500</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/195-guid.html</guid>
    
</item>
<item>
    <title>PostgreSQL 9 High Performance Book Review</title>
    <link>http://www.postgresonline.com/journal/archives/192-PostgreSQL-9-High-Performance-Book-Review.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>postgresql versions</category>
            <category>product showcase</category>
    
    <comments>http://www.postgresonline.com/journal/archives/192-PostgreSQL-9-High-Performance-Book-Review.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=192</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=192</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;&lt;a href=&quot;/store.php?asin=184951030X&quot; &gt;&lt;img src=&quot;/images/affiliate/PostgreSQL9.0HighPerformance_large.jpg&quot; border=&quot;0&quot; alt=&quot;PostgreSQL 9.0 High Performance&quot; style=&quot;float:left;padding:10px&quot;/&gt;&lt;/a&gt;
In a prior article we did a review of &lt;a href=&quot;http://www.postgresonline.com/journal/archives/182-postgrsql90admincookbook.html&quot; target=&quot;_blank&quot;&gt;PostgreSQL 9 Admin Cookbook&lt;/a&gt;, by Simon Riggs and Hannu Krosing.  In this article
we&#039;ll take a look at the companion book &lt;a href=&quot;/store.php?asin=184951030X&quot; target=&quot;_blank&quot;&gt;PostgreSQL 9 High Performance&lt;/a&gt; by Greg Smith.&lt;/p&gt;
&lt;p&gt;Both books are published by Packt Publishing and can be &lt;a href=&quot;http://link.packtpub.com/2NCM0g&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;bought directly from Packt Publishing&lt;/b&gt;&lt;/a&gt; or via Amazon. Packt is currently running a 50% off sale if you
buy both books (&lt;b&gt;e-Book version&lt;/b&gt;) directly from Packt. In addition Packt offers &lt;a href=&quot;http://www.packtpub.com/Shippingpolicy&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;free shipping for US, UK, Europe and select Asian countries&lt;/b&gt;&lt;/a&gt;.  &lt;/p&gt;
&lt;p&gt;For starters: The PostgreSQL 9 High Performance book is a more advanced book than the PostgreSQL 9 Admin Cookbook and is more of a sit-down book. At about 450 pages, it&#039;s a bit longer than the PostgreSQL Admin Cookbook.  Unlike the PostgreSQL 9 Admin Cookbook, it is more a concepts book and much less of a cookbook. 
It&#039;s not a book you would pick up if you are new to databases and trying to feel your way thru PostgreSQL, however if you feel comfortable with databases in general, not specific
to PostgreSQL and are trying to eek out the most performance you can it&#039;s a handy book.  What surprised me most about this book was how much of it is not specific to PostgreSQL, but in fact hardware considerations that are pertinent to most relational databases.  
In fact Greg Smith, starts the book off with a fairly 
shocking statement in the section entitled &lt;b&gt;PostgreSQL or another database?&lt;/b&gt; &lt;em&gt;There are certainly situations where other database solutions will perform better&lt;/em&gt;.  Those are words you will rarely hear from die-hard PostgreSQL users, bent on defending their database
of choice against all criticism and framing PostgreSQL as the tool that will solve famine, bring world peace, and cure cancer if only everyone would stop using that other thing and use PostgreSQL instead:). 
That in my mind, made this book more of a trustworthy reference if you came from some other DBMS, and wanted to know if PostgreSQL could meet your needs comparably or better than what you were using before.&lt;/p&gt;
&lt;p&gt;In a nutshell, if I were to contrast and compare the PostgreSQL 9 Admin Cookbook vs. PostgreSQL High Performance, I would say the Cookbook is a much lighter read focused on getting familiar with and getting the most out of the software (PostgreSQL), and PostgreSQL High Perofrmance is focused
on getting the most out of your hardware and pushing your hardware to its limits to work with PostgreSQL.  There is very little overlap of content between the two and as you take on more sophisticated projects, you&#039;ll definitely want both books on your shelf.  The PostgreSQL 9 High Perofrmance book isn&#039;t going to teach you 
too much about writing better queries,day to day management, or how to load data etc, but it will tell you how to determine when your database is under stress or your hardware is about to kick the bucket and what is causing that stress.  It&#039;s definitely a book you want to have if you plan to run large PostgreSQL databases or a high traffic
site with PostgreSQL.&lt;/p&gt;


&lt;p&gt;PostgreSQL 9 High Performance is roughly about 25% hardware and how to choose the best hardware for your budget, 40% in-depth details about how PostgreSQL works with your hardware and trade-offs made by PostgreSQL developers to get a healthy balance of performance vs. reliability, and another 35% about various useful monitoring 
tools for PostgreSQL performance and general hardware performance. Its focus is mostly on Linux/Unix, which is not surprising since most production PostgreSQL installs are on Linux/Unix.  That said there is some coverage of windows
such as FAT32/NTFS discussion and considerations when deploying terabyte size databases on Windows and issues with shared memory on Windows.&lt;/p&gt;

&lt;p&gt;&lt;b&gt;Full disclosure:&lt;/b&gt;  I got a free e-Book copy of this book just as I did with PostgreSQL 9 Admin Cookbook.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/192-PostgreSQL-9-High-Performance-Book-Review.html#extended&quot;&gt;Continue reading &quot;PostgreSQL 9 High Performance Book Review&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Tue, 28 Dec 2010 15:59:00 -0500</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/192-guid.html</guid>
    <category>book review</category>
<category>book writing</category>

</item>
<item>
    <title>String Aggregation in PostgreSQL, SQL Server, and MySQL</title>
    <link>http://www.postgresonline.com/journal/archives/191-String-Aggregation-in-PostgreSQL,-SQL-Server,-and-MySQL.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>cte</category>
            <category>db2</category>
            <category>intermediate</category>
            <category>mysql</category>
            <category>oracle</category>
            <category>postgresql versions</category>
            <category>q&amp;a</category>
            <category>sql server</category>
            <category>window functions</category>
    
    <comments>http://www.postgresonline.com/journal/archives/191-String-Aggregation-in-PostgreSQL,-SQL-Server,-and-MySQL.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=191</wfw:comment>

    <slash:comments>14</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=191</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;&lt;b&gt;Question:&lt;/b&gt; You have a table of people and a table that specifies the activities each person is involved
in.  You want to return a result that has one record per person and a column that has a listing of activities for each person
separated by semicolons and alphabetically sorted by activity. You also want the whole set alphabetically sorted by person&#039;s name. &lt;/p&gt;

&lt;p&gt;This is a question we are always asked and since we mentor on various flavors of databases, 
we need to be able to switch gears and provide an answer that works on the client&#039;s database. Most
often the additional requirement is that you can&#039;t install new functions in the database. This means that
for PostgreSQL/SQL Server that both support defining custom aggregates, that is out as an option.&lt;/p&gt;

&lt;p&gt;Normally we try to come up with an answer that works in most databases, but sadly the only solution that works in 
most is to push the problem off to the client front end and throw up your hands and proclaim -- &amp;quot;This ain&#039;t something that should be 
done in the database and is a reporting problem.&amp;quot;  That is in fact what many database purists do, and all I can say to them is wake up and smell the coffee before you are out of a job.  
We feel that data 
transformation is an important function of a database, and if your database is incapable of massaging the data into a format
your various client apps can easily digest, WELL THAT&#039;s A PROBLEM.&lt;/p&gt;

&lt;p&gt;We shall now document this answer rather than trying to answer for the nteenth time. For starter&#039;s
PostgreSQL has a lot of answers to this question, probably more so than any other, though some are easier to execute than others
and many depend on the version of PostgreSQL you are using.  SQL Server has 2 classes of answers neither of which is terribly appealing,
but we&#039;ll go over the ones that don&#039;t require you to be able to install .NET stored functions in your database since we said that is often a requirement.  
MySQL has a fairly
simple, elegant and very portable way that it has had for a really long time.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/191-String-Aggregation-in-PostgreSQL,-SQL-Server,-and-MySQL.html#extended&quot;&gt;Continue reading &quot;String Aggregation in PostgreSQL, SQL Server, and MySQL&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Fri, 24 Dec 2010 11:24:00 -0500</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/191-guid.html</guid>
    <category>common table expressions</category>
<category>mysql</category>
<category>oracle</category>
<category>postgresql 9.0</category>
<category>sql server</category>
<category>string concatenation</category>
<category>window functions</category>

</item>
<item>
    <title>Universal Unique Identifiers PostgreSQL SQL Server Compare</title>
    <link>http://www.postgresonline.com/journal/archives/179-Universal-Unique-Identifiers-PostgreSQL-SQL-Server-Compare.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>beginner</category>
            <category>contrib spotlight</category>
            <category>ms access</category>
            <category>postgresql versions</category>
            <category>sql server</category>
            <category>uuid_osp</category>
    
    <comments>http://www.postgresonline.com/journal/archives/179-Universal-Unique-Identifiers-PostgreSQL-SQL-Server-Compare.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=179</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=179</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;&lt;a href=&quot;http://en.wikipedia.org/wiki/Universally_Unique_Identifier&quot; target=&quot;_blank&quot;&gt;Universal Unique Identifiers&lt;/a&gt; are 16-byte / 32-hexadecimal digit (with 4 -s for separation) 
identifiers standardized by the &lt;a href=&quot;http://en.wikipedia.org/wiki/Open_Software_Foundation&quot; target=&quot;_blank&quot;&gt;Open Software Foundation&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt; 
The main use as far as databases go is to ensure uniqueness of keys across databases. This is important if you have multiple servers or disperate systems that need to replicate or share
data and each can generate data on its own end. You want some non-centralized mechanism to ensure the ids generated from each server will never overlap.  
There are various open standards
for generating these ids and each standard will tie the id based on some unique identifier of the computer or a namespace or just a purely random generator algorithm not tied to anything.
Since this is a question often asked by users coming from Microsoft SQL Server, we will demonstrate in this article the same concept in Microsoft SQL Server and how you would achieve similar functionality in PostgreSQL.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/179-Universal-Unique-Identifiers-PostgreSQL-SQL-Server-Compare.html#extended&quot;&gt;Continue reading &quot;Universal Unique Identifiers PostgreSQL SQL Server Compare&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 07 Oct 2010 18:55:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/179-guid.html</guid>
    <category>global unique identifier</category>
<category>guid</category>
<category>universal unique identifier</category>
<category>uuid</category>

</item>
<item>
    <title>PostGIS 1.5.2 coming soon</title>
    <link>http://www.postgresonline.com/journal/archives/175-PostGIS-1.5.2-coming-soon.html</link>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>editor note</category>
            <category>postgis</category>
    
    <comments>http://www.postgresonline.com/journal/archives/175-PostGIS-1.5.2-coming-soon.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=175</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=175</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;Over the past two weeks, the PostGIS development team has been working hard to get out PostGIS 1.5.2 in time for the PostgreSQL 9.0 release.  This release contains fixes allowing PostGIS to compile against 9.0.  Due to an unfortunate turn of events, we missed the cut by a couple of days and are currently
experiencing technical difficulties with the postgis.org website.  These should be resolved soon and barring no further difficulties, we should have the final PostGIS 1.5.2 ready late this week.&lt;/p&gt;
&lt;p&gt;On the plus side, we do have a PostGIS 1.5.2 rc1 available for download from our &lt;a href=&quot;http://trac.osgeo.org/postgis/wiki/RCDownloads&quot; target=&quot;_blank&quot;&gt;PostGIS Wiki Release Candidate Downloads&lt;/a&gt; section.  Please feel free to test these
out so that we have a smooth release.&lt;/p&gt;  

&lt;p&gt;Paul&#039;s related post is &lt;a href=&quot;http://blog.cleverelephant.ca/2010/09/postgis-152rc1.html&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;Here are the details of what is fixed: 
&lt;pre&gt;
 - This is a bug fix release, addressing issues that have been
   filed since the 1.5.1 release.

 - Bug Fixes
   - Loader: fix handling of empty (0-verticed) geometries in shapefiles.
     (Sandro Santilli)
   - #536, Geography ST_Intersects, ST_Covers, ST_CoveredBy and
     Geometry ST_Equals not using spatial index (Regina Obe, Nicklas Aven)
   - #573, Improvement to ST_Contains geography
   - Loader: Add support for command-q shutdown in Mac GTK build (Paul Ramsey)
   - #393, Loader: Add temporary patch for large DBF files 
     (Maxime Guillaud, Paul Ramsey)  
   - #507, Fix wrong OGC URN in GeoJSON and GML output (Olivier Courtin)
   - spatial_ref_sys.sql Add datum conversion for projection SRID 3021
     (Paul Ramsey)
   - Geography - remove crash for case when all geographies are out of
     the estimate (Paul Ramsey)
   - #469, Fix for array_aggregation error (Greg Stark, Paul Ramsey)
   - #532, Temporary geography tables showing up in other user sessions
     (Paul Ramsey)
   - #562, ST_Dwithin errors for large geographies (Paul Ramsey)
   - #513, shape loading GUI tries to make spatial index when loading DBF only
     mode (Paul Ramsey)
   - #527, shape loading GUI should always append log messages 
     (Mark Cave-Ayland)
   - #504 shp2pgsql should rename xmin/xmax fields (Sandro Santilli)
   - #458 postgis_comments being installed in contrib instead of 
     version folder (Mark Cave-Ayland)
   - #474 Analyzing a table with geography column crashes server
     (Paul Ramsey)
   - #581 LWGEOM-expand produces inconsistent results
     (Mark Cave-Ayland)
   - #471 DocBook dtd errors (Olivier Courtin)
   - Fix further build issues against PostgreSQL 9.0 
     (Mark Cave-Ayland)
   - #572 Password whitespace for Shape File to PostGIS 
     Import not supported (Mark Cave-Ayland)
   - #603 shp2pgsql: &quot;-w&quot; produces invalid WKT for MULTI* objects.
     (Mark Cave-Ayland)
 - Enhancement
   - #513 Add dbf filter to shp2pgsql-gui and allow uploading dbf only
     (Paul Ramsey)
&lt;/pre&gt;
&lt;/p&gt;

&lt;p&gt;We should have windows binaries available a short time after release.  Unfortunately we do not have the 64-bit windows build ready yet, so you still have to use the 32-bit version of PostgreSQL 9.0 if you need PostGIS on windows.&lt;/p&gt; 
    </content:encoded>

    <pubDate>Mon, 20 Sep 2010 15:35:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/175-guid.html</guid>
    
</item>
<item>
    <title>Using LTree to Represent and Query Hierarchy and Tree Structures</title>
    <link>http://www.postgresonline.com/journal/archives/173-Using-LTree-to-Represent-and-Query-Hierarchy-and-Tree-Structures.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>contrib spotlight</category>
            <category>db2</category>
            <category>firebird</category>
            <category>intermediate</category>
            <category>ltree</category>
            <category>oracle</category>
            <category>postgresql versions</category>
            <category>sql server</category>
    
    <comments>http://www.postgresonline.com/journal/archives/173-Using-LTree-to-Represent-and-Query-Hierarchy-and-Tree-Structures.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=173</wfw:comment>

    <slash:comments>5</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=173</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;PostgreSQL offers several options for displaying and querying tree like structures.  
In &lt;a href=&quot;http://www.postgresonline.com/journal/archives/131-Using-Recursive-Common-table-expressions-to-represent-Tree-structures.html&quot; target=&quot;_blank&quot;&gt;Using Recursive Common Table Expressions (CTE) to represent tree structures&lt;/a&gt;
we demonstrated how to use common table expressions to display a tree like structure.  Common Table Expressions required PostgreSQL 8.4 and above but  was fairly ANSI standards compliant. In addition to that 
approach you have the option of using recursive functions.  There is yet another common approach for this which is specific to PostgreSQL.  This is using the &lt;a href=&quot;http://www.postgresql.org/docs/current/static/ltree.html&quot; target=&quot;_blank&quot;&gt;ltree contrib datatype&lt;/a&gt;
that has been supported for sometime in PostgreSQL.  For one of our recent projects, we chose ltree over the other approaches because the performance is much better when you need to do ad-hoc queries over the tree since it can take advantage of btree and gist indexes
and also has built-in tree query expressions that make ad-hoc queries simpler to do; similar in concept to the tsearch query syntax for querying text. &lt;/p&gt;

&lt;p&gt;In this article we&#039;ll demonstrate how to use ltree and along the way also show the PostgreSQL 9.0 new features &lt;b&gt;conditional triggers&lt;/b&gt; and &lt;b&gt;ordered aggregates&lt;/b&gt;.&lt;/p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/173-Using-LTree-to-Represent-and-Query-Hierarchy-and-Tree-Structures.html#extended&quot;&gt;Continue reading &quot;Using LTree to Represent and Query Hierarchy and Tree Structures&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Sun, 22 Aug 2010 01:15:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/173-guid.html</guid>
    <category>ansi sql</category>
<category>common table expressions</category>
<category>firebird</category>
<category>ibm db2</category>
<category>oracle</category>
<category>postgresql 9.0</category>
<category>sql server</category>
<category>triggers</category>

</item>
<item>
    <title>Starting PostgreSQL in windows without install</title>
    <link>http://www.postgresonline.com/journal/archives/172-Starting-PostgreSQL-in-windows-without-install.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>beginner</category>
            <category>q&amp;a</category>
    
    <comments>http://www.postgresonline.com/journal/archives/172-Starting-PostgreSQL-in-windows-without-install.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=172</wfw:comment>

    <slash:comments>20</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=172</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;This is a question that comes up quite often by windows users, so thought we would share how we normally do it.  The question is can you run a PostgreSQL server on your windows desktop/server box without having to install anything?
The answer is yes and quite easily.  Why would you need to do this.  There are a couple of cases -- one you are developing a single user app that you want users to be able to run from anywhere without having to install it first.
The other common reason is, you aren&#039;t allowed to install anything on a user&#039;s pc and you also want to package along a database you already have created.&lt;/p&gt;
&lt;p&gt;For our purposes, many of our developers develop on portable WAMP like things, and for some of our applications, they need to work in both MySQL and PostgreSQL, so we need an easy way during development to swap one out for the other.&lt;/p&gt;

 &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/172-Starting-PostgreSQL-in-windows-without-install.html#extended&quot;&gt;Continue reading &quot;Starting PostgreSQL in windows without install&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Thu, 12 Aug 2010 19:25:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/172-guid.html</guid>
    
</item>
<item>
    <title>Of Camels and People: Converting back and forth from Camel Case, Pascal Case to  underscore lower case</title>
    <link>http://www.postgresonline.com/journal/archives/170-Of-Camels-and-People-Converting-back-and-forth-from-Camel-Case,-Pascal-Case-to-underscore-lower-case.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>beginner</category>
            <category>mysql</category>
            <category>oracle</category>
            <category>postgresql versions</category>
            <category>q&amp;a</category>
            <category>sql server</category>
    
    <comments>http://www.postgresonline.com/journal/archives/170-Of-Camels-and-People-Converting-back-and-forth-from-Camel-Case,-Pascal-Case-to-underscore-lower-case.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=170</wfw:comment>

    <slash:comments>4</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=170</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;When it comes to naming things in databases and languages, there are various common standards. For many languages the 
    &lt;a href=&quot;http://en.wikipedia.org/wiki/CamelCase&quot; target=&quot;_blank&quot;&gt;camel family of namings&lt;/a&gt; is very popular. For unix based databases
    usually UPPER or lower _ is the choice and for databases such as SQL Server and MySQL which allow you to name your columns with mixed casing
    but couldn&#039;t care less what case you express them in selects, you get a mish mush of styles depending on what camp the database user originated from.&lt;/p&gt;
&lt;p&gt;So to summarize the key styles and the family of people &lt;/p&gt;
&lt;UL&gt;&lt;LI&gt;camelCase : lastName  - employed by SmallTalk, Java, Flex, C++ and various C derivative languages.&lt;/LI&gt;
    &lt;LI&gt;Pascal Case: (a variant of Camel Case) -- LastName which is employed by C#, VB.NET, Pascal (and Delphi), and SQL Server (and some MySQL windows converts). Also often used for class names by languages that use standard camelCase for function names.&lt;/LI&gt;
    &lt;LI&gt;lower case _ last_name :  often found in C, a favorite among PostgreSQL database users. (some MySQL)&lt;/LI&gt;
    &lt;LI&gt;upper case _ LAST_NAME :  a favorite among Oracle Users (some MySQL  Oracle defectors)&lt;/LI&gt;
&lt;/UL&gt;

&lt;p&gt;Being at the cross roads of all the above, we often have to deal with the various above as well as having internal schizophrenic strife and external fights.  
The internal turmoil is the worst and is worse than an ambidextrous person trying to figure out which hand to use in battle.  For these exercises, we&#039;ll demonstrate one way how to convert between the various conventions.  These 
are the first thoughts that came to our mind, so may not be the most elegant.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/170-Of-Camels-and-People-Converting-back-and-forth-from-Camel-Case,-Pascal-Case-to-underscore-lower-case.html#extended&quot;&gt;Continue reading &quot;Of Camels and People: Converting back and forth from Camel Case, Pascal Case to  underscore lower case&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Fri, 23 Jul 2010 17:17:17 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/170-guid.html</guid>
    <category>regex</category>
<category>regular expressions</category>
<category>string matching</category>
<category>string parsing</category>

</item>
<item>
    <title>Fuzzy string matching with Trigram and Trigraphs</title>
    <link>http://www.postgresonline.com/journal/archives/169-Fuzzy-string-matching-with-Trigram-and-Trigraphs.html</link>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>contrib spotlight</category>
            <category>fuzzystrmatch</category>
            <category>intermediate</category>
            <category>pgtrgm</category>
            <category>postgresql versions</category>
    
    <comments>http://www.postgresonline.com/journal/archives/169-Fuzzy-string-matching-with-Trigram-and-Trigraphs.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=169</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=169</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;In an earlier article &lt;a href=&quot;http://www.postgresonline.com/journal/archives/158-Where-is-soundex-and-other-warm-and-fuzzy-string-things.html&quot; target=&quot;_blank&quot;&gt;Where is Soundex and other Fuzzy string things&lt;/a&gt; we covered the PostgreSQL contrib module fuzzstrmatch which contains the very popular function
soundex that is found in other popular relational databases. We also covered  the more powerful levenshtein distance, metaphone and 
dmetaphone functions included in fuzzstrmatch, but rarely found in other relational databases.&lt;/p&gt;

&lt;p&gt;As far as fuzzy string matching goes, PostgreSQL has other functions up its sleeves.  This time we will cover
the contrib module &lt;a href=&quot;http://www.postgresql.org/docs/8.4/interactive/pgtrgm.html&quot; target=&quot;_blank&quot;&gt;pg_trgm&lt;/a&gt; which was introduced in PostgreSQL 8.3.  pgtrgm uses a concept called trigrams  for doing string comparisons. The pg_trgm module has several functions and gist/gin operators.  
Like other contrib modules, you just need to run the &lt;b&gt;/share/contrib/pg_trgm.sql&lt;/b&gt; file packaged in your PostgreSQL install to enable it in your database. 
&lt;/p&gt;
&lt;p&gt;For this set of exercises, we&#039;ll use trigrams to compare words using the same set of data we tested 
with soundex and metaphones. For the next set of exercises, we will be using the places dataset we created in &lt;a href=&quot;http://www.postgresonline.com/journal/archives/157-Import-fixed-width-data-into-PostgreSQL-with-just-PSQL.html&quot; target=&quot;_blank&quot;&gt;Importing Fixed width data into PostgreSQL with just PSQL&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt; The most useful are the &lt;B&gt;similarity&lt;/B&gt; function and the
% operator.  The &lt;b&gt;%&lt;/b&gt; operator allows for using a GIST/GIN index and the similarity function allows for narrowing your filter similar to what
levenshtein did for us in fuzzstrmatch.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/169-Fuzzy-string-matching-with-Trigram-and-Trigraphs.html#extended&quot;&gt;Continue reading &quot;Fuzzy string matching with Trigram and Trigraphs&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Wed, 21 Jul 2010 18:20:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/169-guid.html</guid>
    <category>string matching</category>
<category>trigram</category>
<category>trigraph</category>

</item>
<item>
    <title>Encrypting data with pgcrypto</title>
    <link>http://www.postgresonline.com/journal/archives/165-Encrypting-data-with-pgcrypto.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>contrib spotlight</category>
            <category>pgcrypto</category>
            <category>postgresql versions</category>
    
    <comments>http://www.postgresonline.com/journal/archives/165-Encrypting-data-with-pgcrypto.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=165</wfw:comment>

    <slash:comments>6</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=165</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;PostgreSQL has various levels of encryption to choose from.  In this article we&#039;ll go over the basics built-in and the more advanced provided by the contrib module &lt;a href=&quot;http://www.postgresql.org/docs/8.4/interactive/pgcrypto.html&quot; target=&quot;_blank&quot;&gt;pgcrypto&lt;/a&gt;. When encrypting data, as a general rule the harder you make it to
keep people out of your data, the easier it is for you to lock yourself out of your data. Not only does encryption make it difficult to read data, it
also takes more resources to query and decrypt. With those rules of thumb, its important to pick your encryption strategies based on the sensitivity of your data.  &lt;/p&gt;
&lt;p&gt;There are two basic kinds of encryption, one way and two way.  In one way you don&#039;t ever care about decrypting the data into readable form, but you just want to verify the user knows what the underlying secret text is.  This is normally used for passwords.  In two way encryption, you want the ability to encrypt data as well as allow authorized users to decrypt it into a meaningful form.  Data such as credit cards and SSNs would fall in this category.&lt;/p&gt;
&lt;h4&gt;One way encryption&lt;/h4&gt;
&lt;p&gt;Normally when people want one way encryption and just want a basic simple level of encryption, they use the md5 function which is built into PostgreSQL by default.  The md5 function is equivalent to using the PASSWORD function in MySQL. If you want anything beyond that, you&#039;ll want to install
the pgcrypto contrib module.&lt;/p&gt;
&lt;p&gt;pgcrypto comes packaged with most PostgreSQL installs including windows, and can be installed into a database by running the script in &lt;b&gt;share/contrib/pgcrypto.sql&lt;/b&gt; of your PostgreSQL install.  For PostgreSQL 8.4+, this adds 34 someodd functions to your list of options.  For maintainability we like to install it in a
separate schema say crypto, and add this schema to our database search path.&lt;/p&gt;

&lt;p&gt;For one way encryption, the crypt function packaged in pgcrypto provides an added level of security above the md5 way.  The reason is that with md5, you can tell who has the same password because there is no &lt;a href=&quot;http://en.wikipedia.org/wiki/Salt_%28cryptography%29&quot; target=&quot;_blank&quot;&gt;&lt;b&gt;salt&lt;/b&gt;&lt;/a&gt; so all people with the same password will have the same encoded md5 string.
With crypt, they will be different.  To demonstrate lets create a table with two users who have happened to have chosen the same password. &lt;p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/165-Encrypting-data-with-pgcrypto.html#extended&quot;&gt;Continue reading &quot;Encrypting data with pgcrypto&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Wed, 16 Jun 2010 06:26:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/165-guid.html</guid>
    <category>contrib</category>
<category>pgcrypto</category>

</item>
<item>
    <title>STRICT on SQL Function Breaks In-lining Gotcha</title>
    <link>http://www.postgresonline.com/journal/archives/163-STRICT-on-SQL-Function-Breaks-In-lining-Gotcha.html</link>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>basics</category>
            <category>intermediate</category>
            <category>mysql</category>
            <category>oracle</category>
            <category>postgis</category>
            <category>postgresql versions</category>
            <category>sql functions</category>
            <category>sql server</category>
    
    <comments>http://www.postgresonline.com/journal/archives/163-STRICT-on-SQL-Function-Breaks-In-lining-Gotcha.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=163</wfw:comment>

    <slash:comments>3</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=163</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;One of the coolest features of PostgreSQL is the ability to write functions using plain old
SQL.  This feature it has had for a long time.  Even before PostgreSQL 8.2. No other database to our knowledge has this feature.  By SQL we mean sans procedural mumbo jumbo like
loops and what not.  This is cool for two reasons:&lt;/p&gt;

&lt;UL&gt;
	&lt;LI&gt;Plain old SQL is the simplest to write and most anyone can write one and is just what the doctor ordered in many cases. PostgreSQL even allows you to write
		aggregate functions with plain old SQL. Try to write an &lt;a href=&quot;http://msdn.microsoft.com/en-us/library/ms131056(v=SQL.105).aspx&quot; target=&quot;_blank&quot;&gt;aggregate function in SQL Server&lt;/a&gt;
		you&#039;ve got to pull out your Visual Studio this and that and do some compiling and loading and you better know C# or VB.NET.  Try in &lt;a href=&quot;http://www.codeproject.com/KB/database/MySQL_UDFs.aspx&quot; target=&quot;_blank&quot;&gt;MySQL and you better learn C&lt;/a&gt;.
			Do the same in PostgreSQL (you have a large choice of languages &lt;a href=&quot;http://www.postgresonline.com/journal/archives/68-More-Aggregate-Fun-Whos-on-First-and-Whos-on-Last.html&quot; target=&quot;_blank&quot;&gt;including SQL&lt;/a&gt;) and the code is simple to write.  Nevermind
			with MySQL and SQL Server, you aren&#039;t even allowed to do those type of things on a shared server or a server where the IT department is paranoid.  The closest 
				with this much ease would be  &lt;a href=&quot;http://www.oracle.com/technology/oramag/oracle/06-jul/o46sql.html&quot; target=&quot;_blank&quot;&gt;Oracle, which is unnecessarily verbose&lt;/a&gt;. &lt;/LI&gt;
	&lt;LI&gt;Most importantly -- since it is just SQL, for simple user-defined functions, a PostgreSQL sql function can often be in-lined into the overall query plan since
		it only uses what is legal in plain old SQL.&lt;/LI&gt;
&lt;/UL&gt;

&lt;p&gt;This inlining feature is part of the secret sauce that makes PostGIS fast and easy to use.
So instead of writing geom1 &amp;&amp;amp; geom2 AND Intersects(geom1,geom2)  -- a user can write
ST_Intersects(geom1,geom2) .  The short-hand is even more striking when you think of the ST_DWithin function.
&lt;/p&gt;

&lt;p&gt;With an inlined function, the planner has visibility into the function and breaks apart the 
spatial index short-circuit test &amp;amp;&amp;amp;  from the more exhaustive absolute test Intersects(geom1,geom2)
and has great flexibility in reordering the clauses in the plan.
&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/163-STRICT-on-SQL-Function-Breaks-In-lining-Gotcha.html#extended&quot;&gt;Continue reading &quot;STRICT on SQL Function Breaks In-lining Gotcha&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Wed, 02 Jun 2010 05:06:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/163-guid.html</guid>
    
</item>
<item>
    <title>Where is soundex and other warm and fuzzy string things</title>
    <link>http://www.postgresonline.com/journal/archives/158-Where-is-soundex-and-other-warm-and-fuzzy-string-things.html</link>
            <category>8.2</category>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>beginner</category>
            <category>contrib spotlight</category>
            <category>fuzzystrmatch</category>
            <category>mysql</category>
            <category>oracle</category>
            <category>postgresql versions</category>
            <category>sql server</category>
    
    <comments>http://www.postgresonline.com/journal/archives/158-Where-is-soundex-and-other-warm-and-fuzzy-string-things.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=158</wfw:comment>

    <slash:comments>1</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=158</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;For those people coming from Oracle, SQL Server and MySQL or other databases that have soundex functionality, 
you may be puzzled, or even frustrated when you try to do 
something like &lt;br /&gt;&lt;code&gt;WHERE soundex(&#039;Wushington&#039;) = soundex(&#039;Washington&#039;)&lt;/code&gt; 
&lt;br /&gt; in PostgreSQL and get a function does not exist error.&lt;/p&gt;

&lt;p&gt;Well it does so happen that there is a soundex function in PostgreSQL, and yes it is 
also called &lt;b&gt;soundex&lt;/b&gt;, but is offered as a contrib module and not installed by default. It also has other fuzzy  string matching functions in addition to soundex. 
One of my favorites, the &lt;b&gt;levenshenstein&lt;/b&gt; distance function is included as well.  In this article
we&#039;ll be covering the contrib module packaged as &lt;b&gt;fuzzystrmatch.sql&lt;/b&gt;. Details of the module can be found in &lt;a href=&quot;http://www.postgresql.org/docs/8.4/static/fuzzystrmatch.html&quot; target=&quot;_blank&quot;&gt;FuzzyStrMatch&lt;/a&gt;.
The contrib module has been around for sometime, but has changed slightly from PostgreSQL version to PostgreSQL version.  We are covering the 8.4 version in this article.&lt;/p&gt;

&lt;p&gt;For those unfamiliar with soundex, its a basic approach developed by the US Census in the 1930s as a way of sorting
names by pronounciation.  Read &lt;a href=&quot;http://www.fcgsc.org/forms/CensusAndSoundex.pdf&quot; target=&quot;_blank&quot;&gt;Census and Soundex&lt;/a&gt; for more gory history details.&lt;/p&gt;
&lt;p&gt;Given that it is an approach designed primarily for the English alphabet, it sort of makes sense why its not built-in to PostgreSQL,
which has more of a diverse international concern. For example if you used it to compare two words in Japanese or Chinese,
don&#039;t think it would fair too well in any of the database platforms that support this function.&lt;/p&gt;
&lt;p&gt;The original soundex algorithm has been improved over the years.  Though its still the most common used today, newer variants 
exist called &lt;a href=&quot;http://en.wikipedia.org/wiki/Metaphone&quot; target=&quot;_blank&quot;&gt;MetaPhone&lt;/a&gt; developed in the 1990s and &lt;a href=&quot;http://en.wikipedia.org/wiki/Double_Metaphone&quot; target=&quot;_blank&quot;&gt;Double Metaphone (DMetaPhone)&lt;/a&gt; developed in 2000 that support additional
consonants in other languages such as Slavic, Celtic, Italian, Spanish etc.  
These two variants are also included in the fuzzystrmatch contrib library.  The soundex function still seems to be 
the most popularly used at least for U.S. This is perhaps because most of the other databases (Oracle, SQL Server, MySQL) have soundex built-in but not the metaphone variants.
So in a sense soundex is a more portable function.  The other reason is that metaphone and dmetaphone take up a bit more space and
are also more processor intensive to compute than soundex. We&#039;ll demonstrate some differences between them in this article.&lt;/p&gt;

&lt;p&gt;To enable soundex and the other fuzzy string matching functions included, just run the 
&lt;b&gt;share/contrib/fuzzystrmatch.sql&lt;/b&gt; located in your PostgreSQL install folder.  This library is an important piece of arsenal for geocoding and genealogy tracking particularly
the U.S. streets and surnames data sets.  I come from a long line of Minors, Miners, Burnettes and Burnets.&lt;/p&gt;

&lt;p&gt;For the next set of exercises, we will be using the places dataset we created in &lt;a href=&quot;http://www.postgresonline.com/journal/archives/157-Import-fixed-width-data-into-PostgreSQL-with-just-PSQL.html&quot; target=&quot;_blank&quot;&gt;Importing Fixed width data into PostgreSQL with just PSQL&lt;/a&gt;.&lt;/p&gt;
 &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/158-Where-is-soundex-and-other-warm-and-fuzzy-string-things.html#extended&quot;&gt;Continue reading &quot;Where is soundex and other warm and fuzzy string things&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Mon, 17 May 2010 16:53:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/158-guid.html</guid>
    <category>contrib</category>
<category>levenshtein</category>
<category>mysql</category>
<category>oracle</category>
<category>soundex</category>
<category>sql server</category>
<category>string matching</category>

</item>
<item>
    <title>PostGIS Raster its on: 10 things you can do NOW with raster</title>
    <link>http://www.postgresonline.com/journal/archives/156-PostGIS-Raster-its-on-10-things-you-can-do-NOW-with-raster.html</link>
            <category>8.3</category>
            <category>8.4</category>
            <category>9.0</category>
            <category>contrib spotlight</category>
            <category>gis</category>
            <category>postgis</category>
    
    <comments>http://www.postgresonline.com/journal/archives/156-PostGIS-Raster-its-on-10-things-you-can-do-NOW-with-raster.html#comments</comments>
    <wfw:comment>http://www.postgresonline.com/journal/wfwcomment.php?cid=156</wfw:comment>

    <slash:comments>0</slash:comments>
    <wfw:commentRss>http://www.postgresonline.com/journal/rss.php?version=2.0&amp;type=comments&amp;cid=156</wfw:commentRss>
    

    <author>nospam@example.com (Leo Hsu and Regina Obe)</author>
    <content:encoded>
    &lt;p&gt;We just finished the first draft of the last chapter of our book: &lt;a href=&quot;http://www.postgis.us/chapter_13&quot;&gt;First look at PostGIS WKT Raster&lt;/a&gt;.  This completes our hard-core writing and now on to more drafting,
polishing all the chapters.
In Chapter 13 we demonstrate how to use PostGIS WKT Raster functions by example and cross breed with PostGIS geometry functionality. I was pleasantly surprised to see how nicely the raster and geometry functions play together.&lt;/p&gt;
&lt;p&gt;We had intended this chapter to be short about 20 pages in length, because how much can one say about pixels and pictures. As it turns out, a lot. 
Rasters are more versatile than their picture portrayal on a screen. Rasters are a class of structured storage suitable for representing any numeric, 
cell based data where each cell has one or more numeric properties (the bands). This covers quite a bit of data you collect with remote sensing and other electronic instrumentation.  We had to stretch to over 30 pages; even then we felt we were missing some critical examples. &lt;/p&gt;
&lt;p&gt;There is a lot of useful functionality in PostGIS WKT Raster 
already and should make a lot of people looking for raster support in PostgreSQL very happy. Although the chapter may portray some scenes of violence and torture inflicted on elephants, you can rest assured
that it is pure illusion and no real elephants or blue elephant dolls were harmed in the making of this chapter.&lt;/p&gt;

&lt;p&gt;As a side note -- our book is now listed on &lt;a href=&quot;http://www.amazon.com/PostGIS-Action-Regina/dp/1935182269/ref=sr_1_3?ie=UTF8&amp;s=books&amp;qid=1271471649&amp;sr=8-3&quot; target=&quot;_blank&quot;&gt;Amazon PostGIS in Action&lt;/a&gt;. 
It is not available in hard-copy yet,but you can pre-order and of course you can order from &lt;a href=&quot;http://www.manning.com/obe/&quot; target=&quot;_blank&quot;&gt;PostGIS in Action from Manning directly&lt;/a&gt; 
to get the chapter drafts we have posted, updates as we polish them, and the final book when it comes out in hard print.&lt;/p&gt;
&lt;p&gt;The Amazon listing would have been so much more exciting, had they not stripped me of my last name or had Leo married to himself.  &lt;br /&gt;
&lt;span style=&quot;color:green&quot;&gt;UPDATE: It appears I now have a last name again&lt;/span&gt;
&lt;br /&gt;
In hind sight, I suppose OBE is more commonly seen as a title of honor rather than a last
name, so its only fitting that I should be stripped of mine and &lt;a href=&quot;http://www.knowledgerush.com/kr/encyclopedia/Tim_Berners-Lee/&quot; target=&quot;_blank&quot;&gt;Tim Berners-Lee&lt;/a&gt; gets it tacked on at the end of his name.&lt;/p&gt;

&lt;p&gt; To find out more about PostGIS WKT Raster, we encourage you to check out these links. 
&lt;UL&gt;&lt;LI&gt;&lt;a href=&quot;http://trac.osgeo.org/postgis/wiki/WKTRaster&quot; target=&quot;_blank&quot;&gt;PostGIS WKT Raster Home Page&lt;/a&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;a href=&quot;http://www.postgis.org/documentation/manual-svn/RT_FAQ.html&quot; target=&quot;_blank&quot;&gt;PostGIS WKT Raster Frequently asked questions&lt;/a&gt;&lt;/LI&gt;
&lt;LI&gt;&lt;a href=&quot;http://www.postgis.org/documentation/manual-svn/RT_reference.html&quot; target=&quot;_blank&quot;&gt;WKT Raster Reference&lt;/a&gt;&lt;/LI&gt;
&lt;/UL&gt;
&lt;/p&gt;
&lt;p&gt;Now we&#039;ll itemize 10 things you can do now with PostGIS WKT Raster. In order to use PostGIS WKT Raster, you need PostGIS 1.3.5 or above.  Preferably 1.4 or 1.5 or 2.0 alpha.&lt;/p&gt;
&lt;p&gt;PostGIS WKT Raster is currently packaged as a separate library and we have &lt;a href=&quot;http://postgis.net/windows_downloads#wktraster&quot; target=&quot;_blank&quot;&gt;windows binaries available&lt;/a&gt;.&lt;/p&gt; &lt;br /&gt;&lt;a href=&quot;http://www.postgresonline.com/journal/archives/156-PostGIS-Raster-its-on-10-things-you-can-do-NOW-with-raster.html#extended&quot;&gt;Continue reading &quot;PostGIS Raster its on: 10 things you can do NOW with raster&quot;&lt;/a&gt;
    </content:encoded>

    <pubDate>Sat, 17 Apr 2010 17:08:00 -0400</pubDate>
    <guid isPermaLink="false">http://www.postgresonline.com/journal/archives/156-guid.html</guid>
    <category>book writing</category>
<category>postgis</category>
<category>raster</category>

</item>

</channel>
</rss>