<?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>Tiffany B. Brown &#187; MySQL / Databases</title>
	<atom:link href="http://tiffanybbrown.com/category/mysql-databases/feed/" rel="self" type="application/rss+xml" />
	<link>http://tiffanybbrown.com</link>
	<description>A web log about web development and internet culture with frequent detours into other stuff.</description>
	<lastBuildDate>Wed, 23 May 2012 16:23:51 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.2</generator>
		<item>
		<title>Relational database design explained … sort of</title>
		<link>http://tiffanybbrown.com/2010/09/26/relational-database-design-explained-sort-of/</link>
		<comments>http://tiffanybbrown.com/2010/09/26/relational-database-design-explained-sort-of/#comments</comments>
		<pubDate>Sun, 26 Sep 2010 19:31:10 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=4603</guid>
		<description><![CDATA[]]></description>
			<content:encoded><![CDATA[<p><a href="http://webinista.s3.amazonaws.com/images/uploads/2010/09/DB.png"><img src="http://webinista.s3.amazonaws.com/images/uploads/2010/09/DB-500x353.png" alt=" title="" width="500" height="353" class="alignnone size-medium wp-image-4604" /></a></p>
<p>Click through for a larger version. The text:</p>
<blockquote class="longquote"><p>It helps ensure data consistency and integrity. This may not seem important at first. But it becomes critical when you want to query or sort that data.</p>
<p>For example, we have three books by Toni Morrison in the database. if we stored author information in the same table, every time someone wanted to add a Toni Morrison book, they would have to type &#8220;Toni Morrison&#8221; in the author field.</p>
<p>That&#8217;s fine, as long as this person types well. But letters often get transposed, and some names are easy to misspell. If a user enters &#8220;Toni Morisson,&#8221; that book title won&#8217;t appear in a &#8220;Toni Morrison&#8221; search. We can help ensure data consistency with a separate authors table.
 </p></blockquote>
<p>For D.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2010/09/26/relational-database-design-explained-sort-of/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>Collecting e-commerce conversion data with Zen Cart and Google Analytics</title>
		<link>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/</link>
		<comments>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/#comments</comments>
		<pubDate>Thu, 19 Feb 2009 09:00:44 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Software]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[ecommerce]]></category>
		<category><![CDATA[google]]></category>
		<category><![CDATA[online shopping]]></category>
		<category><![CDATA[open source]]></category>
		<category><![CDATA[zen cart]]></category>
		<category><![CDATA[zencart]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/?p=1785</guid>
		<description><![CDATA[Google Analytics allows you to collect pretty robust data about how users move through your e-commerce site. Here&#8217;s how to make it work with Zen Cart, an open source shopping cart. For this tutorial, you will need: A Zen Cart-based shopping cart A Google Analytics account and the tracking code for both conversions and page [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://google.com/analytics">Google Analytics</a> allows you to collect pretty robust data about how users move through your e-commerce site. Here&#8217;s how to make it work with <a href="http://www.zen-cart.com/">Zen Cart</a>, an open source shopping cart.</p>
<p>For this tutorial, you will need:</p>
<ul>
<li>A Zen Cart-based shopping cart</li>
<li>A Google Analytics account and the tracking code for both conversions and page views.</li>
<li>Experience with <a href="http://www.php.net/">PHP</a> and <a href="http://dev.mysql.com/">MySQL</a> programming</li>
</ul>
<p>Also check out Google&#8217;s support article <a href="http://www.google.com/support/googleanalytics/bin/answer.py?hl=en&#038;answer=55528">How do I track e-commerce transactions?</a> and become <abbr title="best friends forever">BFF</abbr>s with the <a href="http://www.zen-cart.com/wiki/" class="ext">Zen Cart wiki</a>. </p>
<h2>Creating a custom functions file</h2>
<p>Create a file to <a href="http://www.zen-cart.com/wiki/index.php/Customisation_-_Templates#Automatically_included_files">house your custom functions</a>. Name it whatever you&#8217;d like (with a PHP extension, of course). Put it in your includes/functions/extra_functions/ directory. </p>
<p class="editors-note">A word of caution: I created these functions with my own SQL, outside of the Zen Cart framework. There may be a better way to do it.</p>
<p>In the file you created above, add the following code:</p>
<pre>
# get the product ID out of session key
function custom_get_prodId($productkey){
	$pid = explode(':',$productkey);
	return $pid[0];
}

#get the product data
function custom_get_product($prodID,$return='all'){
	global $db;
	reset($data);
	$q = sprintf("SELECT
			pd.products_name,
			pd.products_description,
			cd.categories_name, p.products_price
			FROM categories_description AS cd, products AS p, products_description AS pd
	 		WHERE  p.products_id = 183
   				AND p.master_categories_id = cd.categories_id
   				AND p.products_id = pd.products_id",$prodID);
	$res = $db->Execute($q);
	return $res->fields;
}
# get the current user's data
function custom_get_userinfo($custID){
	global $db;
	reset($data);
	$q = sprintf("SELECT
			ab.entry_street_address,
			ab.entry_postcode,
			ab.entry_city,
			ab.entry_state,
			c.countries_name,
			c.countries_iso_code_2
			FROM address_book AS ab, countries AS c
			WHERE customers_id=%d
			   AND ab.entry_country_id = c.countries_id
				  ",(int)$custID);
	$res = $db->Execute($q);
	return $res->fields;
}
</pre>
<p>Adjust the names of the tables if you have added a custom table prefix during your Zen Cart configuration. We&#8217;ll use these functions to get us the user data and product data we need. </p>
<h2>Edit the checkout success and global footer files</h2>
<p>Add the conversion tracking code &#8212; provided by Google Analytics &#8212; to the checkout success page template. It&#8217;s located in your templates directory, includes/templates/YOUR_TEMPLATE_DIR/templates/tpl_checkout_success_default.php.</p>
<p>Also add the regular Google Analytics tracking code to your footer file (found in includes/templates/YOUR_TEMPLATE_DIR/common/tpl_footer.php).</p>
<p><em>Below your Google Analytics code</em>, but also in your footer file, add the code below.</p>
<pre>
&lt;?php
# do this on the checkout success page only.
if($_GET['main_page'] == 'checkout_success'): 

$userdata = $_SESSION['cart'];
$moreud = custom_get_userinfo($_SESSION['customer_id']);
?&gt;
&lt;script type="text/javascript"&gt;
pageTracker._addTrans(
    "&lt;?=$userdata-&gt;cartID; ?&gt;",
    "www.YOURDOMAINNAME.com",
    "&lt;?=$userdata-&gt;total; ?&gt;",
    "",
    "&lt;?=$_SESSION['shipping']['cost']; ?&gt;",
    "&lt;?=$moreud['entry_city'];?&gt;",
    "&lt;?=$moreud['entry_state'];?&gt;",
    "&lt;?=$moreud['countries_name'];?&gt;"
  );
&lt;?
# for each product ID key in the userdata session
foreach($userdata-&gt;contents as $k=&gt;$v):
	/*
	the product id gets stored as an array key as xxx:funkymd5key
	ex: 183:fw920e8ktw327uio67xew9mn. custom_get_prodId extracts
	the product id part of that key.
	*/
	$pid = custom_get_prodId($k);
	$data = custom_get_product($pid,'all');
?&gt;

 pageTracker._addItem(
    "&lt;?=$userdata-&gt;cartID; ?&gt;",
    "&lt;?=getProdId($k); ?&gt;",
    "&lt;?=strip_tags($data['products_name']);?&gt;",
    "&lt;?=$data['categories_name'];?&gt;",
    "&lt;?=number_format($data['products_price'],2);?&gt;",
    "&lt;?=$v['qty']; ?&gt;"
  );
&lt;? endforeach; ?&gt;
pageTracker._trackTrans();
&lt;/script&gt;

&lt;?php endif;
} // flag_disable_footer
?&gt;
</pre>
<div class="editors-note">Providing this code with the following disclaimers: </p>
<ol>
<li>It may not work for you. </li>
<li>I&#8217;m not responsible if it does.</li>
<li>I can&#8217;t offer personalized support.</li>
</ol>
<p>In short: you&#8217;re on your own.
</p></div>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2009/02/19/zen-cart-and-google-analytics/feed/</wfw:commentRss>
		<slash:comments>9</slash:comments>
		</item>
		<item>
		<title>Review: Learning PHP Data Objects by Dennis Popel</title>
		<link>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/</link>
		<comments>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/#comments</comments>
		<pubDate>Tue, 23 Oct 2007 05:01:56 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Programming]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[pdo]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/</guid>
		<description><![CDATA[Packt Publishing graciously provided me with a copy of this book to review. PHP supports more than a dozen database setups, including the SQLite library bundled with PHP 5. That&#8217;s a lot of databases, and each one has its own connection syntax and server-specific functions. So what happens when you want to be able to [...]]]></description>
			<content:encoded><![CDATA[<p span class="editors-note">Packt Publishing graciously provided me with a copy of this book to review.</p>
<p><img src='http://tiffanybbrown.com/images/uploads/2007/10/learningpdo.jpg' alt='Learning P H P Data Objects' class="rightimg" /> PHP supports more than a dozen database setups, including the <a href="http://sqlite.org/">SQLite</a> library bundled with PHP 5. That&#8217;s a lot of databases, and each one has its own connection syntax and server-specific functions. </p>
<p>So what happens when you want to be able to swap one database for another? You turn to an abstraction library, such as <a href="http://php.net/pdo"><abbr title="PHP Data Objects">PDO</abbr></a>.
</p>
<p>In <a href="http://www.amazon.com/gp/redirect.html?ie=UTF8&#038;location=http%3A%2F%2Fwww.amazon.com%2FLearning-Data-Objects-Dennis-Poppel%2Fdp%2F1847192661%3Fie%3DUTF8%26s%3Dbooks%26qid%3D1193074907%26sr%3D8-1&#038;tag=webinista-20&#038;linkCode=ur2&#038;camp=1789&#038;creative=9325" class="book title">Learning PHP Data Objects</a><img src="http://www.assoc-amazon.com/e/ir?t=webinista-20&amp;l=ur2&amp;o=1" width="1" height="1" border="0" alt="" style="border:none !important; margin:0px !important;" />, Dennis Popel takes you through the process of building an application using <abbr class="say">PDO</abbr> with My<abbr class="say">SQL</abbr> and SQLite.</p>
<p>Aimed squarely at PHP developers who are new to <abbr class="say">PDO</abbr>, Popel covers how to make connections, handle errors, and use prepared statements with <abbr class="say">PDO</abbr>. He also discusses transactions, <a href="http://en.wikipedia.org/wiki/Model-view-controller"><abbr title="Model-View-Controller">MVC</abbr> development</a>, and the appropriateness of using PDO versus other abstraction libraries.</p>
<p>Where <span class="book title">Learning PHP Data Objects</span> shines,  however is in its code examples. They are easy to follow, and Popel smartly alerts readers to potential gotchas in developing the sample application.</p>
<p>The book assumes an understanding of <abbr title="Object-oriented P H P">OOPHP</abbr> &#8212; necessary because PDO is entirely object-oriented. To get the most out of it, you should be familiar with object-oriented principles and syntax. While Appendix A does give readers a quick overview of <abbr class="say">OOPHP</abbr>, for a more thorough treatment, you&#8217;ll need to look elsewhere.</p>
<p>It&#8217;s a solid, though not quite perfect book. For example, Popel only sort-of mentions a potentially huge gotcha: when you may need to specify a <a href="http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/">unix_socket parameter</a> in the connection string. It&#8217;s a problem I think would be common enough and confusing enough to discuss and demonstrate. I also think Popel could have been a bit clearer about when and why to use <code>PDOStatement->closeCursor()</code>.</p>
<p>Those are minor quibbles however, easily solved by consulting the documentation or doing a Google search. Overall, this book is nice introduction to the whys and hows of using PDO to develop database driven applications.</p>
<div class="quickfacts">
<h3>Quick facts</h3>
<ul>
<li class="book title">Learning PHP Data Objects</li>
<li class="book author">By Dennis Popel</li>
<li class="book publisher"><a href="http://www.packtpub.com/">Packt Publishing</a></li>
<li class="book release">September 2007</li>
<li class="book price">$39.99</li>
<li>ISBN number: <span class="ISBN">978-1-847192-66-0</span></li>
</ul>
</div>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/10/23/review-learning-php-data-objects-by-dennis-popel/feed/</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
		<item>
		<title>Solution for &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when using PDO</title>
		<link>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/</link>
		<comments>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/#comments</comments>
		<pubDate>Mon, 22 Oct 2007 14:54:34 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[pdo]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/</guid>
		<description><![CDATA[If you&#8217;re trying to get up-and-running with PDO, you may experience a &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when trying to connect to your database, even if your php.ini and my.cnf files contain a different default socket path for MySQL. It&#8217;s counterintuitive to a degree, but it&#8217;s actually expected behavior. The [...]]]></description>
			<content:encoded><![CDATA[<p>If you&#8217;re trying to get up-and-running with <abbr title="P H P Data Objects">PDO</abbr>, you may experience a &#8220;Can&#8217;t connect to local MySQL server through socket &#8216;/tmp/mysql.sock&#8217;&#8221; error when trying to connect to your database, even if your php.ini and my.cnf files contain a different default socket path for MySQL.</p>
<p>It&#8217;s counterintuitive to a degree, but it&#8217;s actually expected behavior. The good news is that <a href="http://osdir.com/ml/php.pecl.devel/2006-11/msg00019.html">the fix</a> is easy. Simply include the unix socket path in your connection string. </p>
<pre>
$connection = new PDO("mysql:host=localhost;dbname=test;unix_socket=/path/to/socket/found_in_php.ini_or_my.cnf",'username','password');
</pre>
<p><b>Related:</b> Notes from &#8220;<a href="http://tiffanybbrown.com/2006/06/16/nyphp-con-introduction-to-pdo/">Introduction to PDO</a>,&#8221; a talk by Ilia Alshanetsky at NYPHPCon 2006.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/10/22/solution-for-cant-connect-to-local-mysql-server-through-socket-tmpmysqlsock-error-when-using-pdo/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>OurIndustryIsBroken.com: Tracking site users and traffic with PHP, MySQL and ActionScript</title>
		<link>http://tiffanybbrown.com/2007/07/23/visited-links-in-flash/</link>
		<comments>http://tiffanybbrown.com/2007/07/23/visited-links-in-flash/#comments</comments>
		<pubDate>Tue, 24 Jul 2007 02:49:28 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[ActionScript, Flash & Flex]]></category>
		<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Projects]]></category>
		<category><![CDATA[Web Development & Programming]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2007/07/23/visited-links-in-flash/</guid>
		<description><![CDATA[You may remember that FletcherMartin launched OurIndustryIsBroken.com back in April. After receiving some feedback about the site, we tweaked it to enhance the user experience and allow us to track how visitors use the site. We&#8217;re using Google Analytics for high-level analysis such as referrals and search engine traffic. But we wanted to do more [...]]]></description>
			<content:encoded><![CDATA[<p>You may remember that FletcherMartin launched <a href="http://tiffanybbrown.com/2007/04/20/advertising-our-industry-is-broken/">OurIndustryIsBroken.com</a> back in April. After receiving some feedback about the site, we tweaked it to enhance the user experience and allow us to track how visitors use the site.</p>
<p>We&#8217;re using Google Analytics for high-level analysis such as referrals and search engine traffic. But we wanted to do more robust analysis. You see our conundrum, right? How do you track &#8220;pages&#8221; and visited &#8220;links&#8221; within a single Flash movie embedded in a single HTML page?</p>
<p>Simple: you build your own tracking system.</p>
<p><span id="more-1117"></span><br />
For this project, I used Flash&#8217;s <a href="http://www.adobe.com/support/flash/action_scripts/actionscript_dictionary/actionscript_dictionary427.html "><code>LoadVars()</code> object</a> to talk to a PHP middle layer that writes and retrieves data to and from a MySQL database. </p>
<p><code>LoadVars()</code> allows you to send (and receive) variables from a Flash movie to (or from) a server. You need a server-side script to process that information. Variables and values are sent to the server using either GET or POST. It&#8217;s just like submitting and processing a form &#8212; and should be treated like any other user-submitted data.</p>
<p>When you pass data from the server back to the movie, you send it as a query string, or an encoded URL (example: &#8216;car1=honda%20accord&#038;car2=chevrolet%20tahoe&#8217;). Once the variable-value pairs are loaded into the movie, you can use ActionScript to determine how the movie handles that data.</p>
<h3>The PHP scripts and the database</h3>
<p>There are two PHP scripts at work here. One collects the data from the movie, escapes it, and writes it to the database. The other retrieves data from the database, encodes, and returns it to the movie. We&#8217;re also using three separate database tables.</p>
<p>Table one contains the questions and answers contained in the movie. Each question and answer corresponds to a key. The next table tracks section visits in the aggregate. One column contains the keys from the questions and answers table. The other column keeps track of the count. I set an initial value of zero for each question-and-answer key in that column. Every time a section is visited, we update the count for that section by one. If we were using MySQL version 4.1 or later, we could have used the <a href="http://www.mysqlperformanceblog.com/2006/05/29/insert-on-duplicate-key-update-and-summary-counters/">ON DUPLICATE KEY</a> clause for INSERT.  Instead, we&#8217;re using UPDATE syntax and adding one to the value of the count column.</p>
<p>The third table is where we store per-user data. We&#8217;re using server-based sessions to track visits by user. With each click, we capture the section being visited, the current session identifier, the user&#8217;s IP address and the time of the click. Collecting this user data allows us to do a few things:</p>
<ul>
<li>Determine where our visitors are coming from.</li>
<li>Determine roughly how long people are staying on the site.</li>
<li>Determine which section(s) the user has visited (and their answers).</li>
</ul>
<p>That last portion is probably the coolest. At the end of each section of the movie, we return the user to a main menu. When that screen is loaded, a script queries the database to find which sections have been visited in that session. </p>
<p>Once MySQL returns those section keys, we build our query string. In my PHP code, I set each section variable equal to 1 (i.e. &#8216;section1=1&#038;section22=1&#8242;). We pull this query string into our Flash movie by once again using <code>LoadVars()</code>. </p>
<p>After these variables are loaded, we can use ActionScript to make the movie take a particular action. In this case, I tested to see whether the variable exists (example: <code>if(section1){scroll_mc.gotoAndPlay(23);}</code>). If it does, the movie goes to the scroll movie clip and plays from frame 23. If it doesn&#8217;t, the scroll movie clip plays from frame one. </p>
<p>All of this means we have some solid data to analyze both in terms of traffic and &#8212; because we&#8217;re tracking answers &#8212; how well our messaging is being received.</p>
<p>You can see the new tracking system in effect by <a href="http://www.ourindustryisbroken.com/">visiting the site</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2007/07/23/visited-links-in-flash/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Two Mysqli problems and their easy fixes</title>
		<link>http://tiffanybbrown.com/2006/08/11/two-mysqli-problems-and-their-easy-fixes/</link>
		<comments>http://tiffanybbrown.com/2006/08/11/two-mysqli-problems-and-their-easy-fixes/#comments</comments>
		<pubDate>Fri, 11 Aug 2006 10:00:12 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development & Programming]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/725</guid>
		<description><![CDATA[Having problems with Mysqli? Try doing these (which may or may not help you). If you&#8217;re on a shared host, you may have to talk to your hosting provider, or you may want to get a web host that offers VPS or dedicated server hosting. Set zend.ze1_compatibility_mode = Off. You&#8217;ll need access to your php.ini [...]]]></description>
			<content:encoded><![CDATA[<p>Having problems with Mysqli? Try doing these (which may or may not help you). If you&#8217;re on a shared host, you may have to talk to your hosting provider, or you may want to get a <a href="http://affiliates.westhost.com/z/6/CD298/">web host</a> that offers <a href="http://westhost.com/vps-web-hosting.html"><abbr title="Virtual Private Server">VPS</a> or dedicated server hosting.</p>
<ul>
<li><strong>Set zend.ze1_compatibility_mode = Off</strong>. You&#8217;ll need access to your php.ini file to do this. If you&#8217;re receiving a cloning error (&#8220;Trying to clone an uncloneable object of class mysqli&#8221;) when trying to create an instance of mysqli, try this.</li>
<li><strong>Check your MySQL configuration file (mysql.cnf, my.cnf, or the like) and use the socket specified there</strong>. By default, mysqli will attempt to connect through /tmp/mysql.sock. If your socket path is not /tmp/mysql.sock, the connection will fail. </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/08/11/two-mysqli-problems-and-their-easy-fixes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Link dump: August 8, 2006</title>
		<link>http://tiffanybbrown.com/2006/08/08/link-dump-august-8-2006/</link>
		<comments>http://tiffanybbrown.com/2006/08/08/link-dump-august-8-2006/#comments</comments>
		<pubDate>Tue, 08 Aug 2006 14:02:26 +0000</pubDate>
		<dc:creator></dc:creator>
				<category><![CDATA[Link dumps]]></category>
		<category><![CDATA[Mac OS X]]></category>
		<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development & Programming]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/726</guid>
		<description><![CDATA[Yahoo! Python Developer Center Yahoo adds snakes on an API (Via Jeremy Zawodny, and as you can see, I jacked his post title.) MySQL Connection Management in PHP &#8211; How (Not) To Do Things How to best use MySQL connections when developing with PHP. (Hint, only make the connection when necessary.) This post covers &#8216;lazy [...]]]></description>
			<content:encoded><![CDATA[<dl>
<dt><a href="http://developer.yahoo.com/python/">Yahoo! Python Developer Center</a></dt>
<dd>Yahoo adds <q cite="http://jeremy.zawodny.com/blog/archives/007163.html">snakes on an API</q> (Via <a href="http://jeremy.zawodny.com/blog/archives/007163.html">Jeremy Zawodny</a>, and as you can see, I jacked his post title.)</dd>
<dt><a href="http://www.jpipes.com/index.php?/archives/99-MySQL-Connection-Management-in-PHP-How-Not-To-Do-Things.html">MySQL Connection Management in PHP &#8211; How (Not) To Do Things</a></dt>
<dd>How to best use My<abbr>SQL</abbr> connections when developing with <abbr>PHP</abbr>. (Hint, only make the connection when necessary.) This post covers &#8216;lazy loading&#8217; and content caching. There&#8217;s also a patch to tweak the way <a href="http://www.wordpress.org/">WordPress</a> handles My<abbr>SQL</abbr> connections.</dd>
<dt><a href="http://www.mysqlperformanceblog.com/2006/08/08/caching-techinques/">Caching techinques</a></dt>
<dd>Methods and potential uses of four dynamically generated content caching techniques.</dd>
<dt><a href="http://adage.com/digital/article.php?article_id=110960">Welcome to the Anti-Social Club</a></dt>
<dd>Several <q cite="http://adage.com/digital/article.php?article_id=110960">major marketers are, without fanfare, running invitation-only online communities where they can bounce ideas off their best (or worst) customers, sample broad cultural attitudes and spread word-of-mouth advocacy.</q> (Via <a href="http://attentionmax.com/">Attention Max</a>)</dd>
<dt><a href="http://www.apple.com/macosx/leopard/">Leopard Sneak Peek</a></dt>
<dd>What&#8217;s coming in the next version of the Mac <abbr title="Operating System">OS</abbr>.</dd>
</dl>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/08/08/link-dump-august-8-2006/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Question re: MySQL and PRIMARY versus UNIQUE indexes</title>
		<link>http://tiffanybbrown.com/2006/07/20/question-re-mysql-and-primary-versus-unique-indexes/</link>
		<comments>http://tiffanybbrown.com/2006/07/20/question-re-mysql-and-primary-versus-unique-indexes/#comments</comments>
		<pubDate>Fri, 21 Jul 2006 01:10:55 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[Web Development & Programming]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/704</guid>
		<description><![CDATA[Any MySQL gurus in the house? I need your help. I&#8217;ve got a question: If I have an auto_incrementing id field that is a primary key, and I plan to use that key in a related table, is the primary key enough, should I make it a primary key and a unique key (thereby creating [...]]]></description>
			<content:encoded><![CDATA[<p>Any MySQL gurus in the house? I need your help. I&#8217;ve got a question: If I have an auto_incrementing id field that is a primary key, and I plan to use that key in a related table, is the primary key enough, should I make it a primary key <em>and</em> a unique key (thereby creating a larger index size and a larger overall DB), or should I just make it a unique key?  I&#8217;m using InnoDB tables.</p>
<p>What I&#8217;ve done in the past is make the id field a PRIMARY key and didn&#8217;t bother with a unique key. Now I&#8217;m wondering if making the ID a unique key makes more sense because I&#8217;ll be using it as a key in another table.</p>
<p>Thoughts? Help? </p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/07/20/question-re-mysql-and-primary-versus-unique-indexes/feed/</wfw:commentRss>
		<slash:comments>8</slash:comments>
		</item>
		<item>
		<title>NYPHP Con: &#8220;Introduction to PDO&#8221;</title>
		<link>http://tiffanybbrown.com/2006/06/16/nyphp-con-introduction-to-pdo/</link>
		<comments>http://tiffanybbrown.com/2006/06/16/nyphp-con-introduction-to-pdo/#comments</comments>
		<pubDate>Fri, 16 Jun 2006 11:00:17 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[NYPHPCon2006]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web Development & Programming]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/651</guid>
		<description><![CDATA[PDO ships with PHP 5.1. You do not need to install via PECL These are my notes from a presentation by Ilia Alshanetsky. This post may contain inaccuracies, typos, boo-boos, etc. PDO stands for &#8220;PHP Data Objects Layer&#8221;: A data-access abstraction layer. Common interface for any number of database systems PHP extension Designed to simplify [...]]]></description>
			<content:encoded><![CDATA[<p class="editors-note"><a href="http://php.net/pdo">PDO</a> ships with PHP 5.1. You do not need to install via PECL</p>
<p class="editors-note">These are my notes from a presentation by <a href="http://ilia.ws/">Ilia Alshanetsky</a>. This post may contain inaccuracies, typos, boo-boos, etc.</p>
<p>PDO stands for &#8220;PHP Data Objects Layer&#8221;: A data-access abstraction layer.</p>
<ul>
<li>Common interface for any number of database systems</li>
<li>PHP extension</li>
<li>Designed to simplify features. </li>
<li>Only available to PHP 5 or 5.1; requires a level of OOPHP that&#8217;s only available to PHP 5</li>
</ul>
<h3>Why PDO?</h3>
<ul>
<li>Consistency of development across databases; code is the same for MySQL, PostgreSQL, Oracle, etc.</li>
<li>Current APIs don&#8217;t take full advantage of new PHP&#8217;s features</li>
<li>Current APIs don&#8217;t take full advantage of all of the features available in the database </li>
</ul>
<h3>Installation</h3>
<ul>
<li>Need to install PDO, made up of the core and the drivers. </li>
<li>Can install using PECL. </li>
<li>Can install by recompiling PHP</li>
</ul>
<h3>Using PDO</h3>
<ul>
<li>Create an instance of the object.</li>
<li>PDO uses a single connection string as the lone parameter.
<ul>
<li>Connection failure handling: Instantiation failure causes an exception error. Use inside of a try&#8230;catch block to retrieve and log the error number.</li>
<li>Functions available to report errors</li>
</ul>
</li>
</ul>
<h4>Persistent Connections</h4>
<ul>
<li>Persistent connections help speed up web apps, particularly with Oracle and PostgreSQL databases</li>
<li>Create persistent connections using a class constant ATTR_PERSISTENT</li>
<li>Will need to figure out how many connections you will have at one time (MySQL makes quick connections. Don&#8217;t really need to make a persistent one, but likely won&#8217;t hurt)</li>
</ul>
<h3>Direct Query Execution using PDO</h3>
<ul>
<li>Queries that modify information use the exec() method. </li>
<li>Return value is the number of rows affected by the operation. Returns boolean FALSE on error (INSERT, UPDATE, DELETE). </li>
<li>Queries that select information use the query() method.</li>
</ul>
<h4>Problems with direct queries</h4>
<ul>
<li>Query needs to be interpreted on each execution. Can be a waste for frequently repeated queries. </li>
<li>Security issues with un-escaped user input can lead to SQL injection.</li>
<li>Escaping: quote() method. Handles special characters in PDO. Quote automatically adds single quotes to wrap the query: <code>"SELECT * FROM USERS WHERE".quote($variable)." LIMIT 0,1"</code></li>
</ul>
<h3>Prepared statements</h3>
<ul>
<li>Compile once and execute many times</li>
<li>Separation between structure and input to prevents SQL injections</li>
<li>Often faster than query()/exec() even for single runs.</li>
<li>Uses wildcards/tokens to hold variables; those variables are handled as a parameter, making injection attacks much less likely (bound parameters)</li>
</ul>
<h3>Retrieving information using PDO</h3>
<ul>
<li>Array (Numeric or associative)</li>
<li>String (for single column result sets; ex: selecting an id from a user login table)</li>
<li>Fetch into a class</li>
<li>Objects
<ul>
<li>Ability to retrieve data into an object</li>
<li>Ability to retrieve data into an exisiting object</li>
</ul>
</li>
<li>Callback Function</li>
<li>Lazy fetching</li>
<li>Iterators</li>
</ul>
<h4>Result Iteration &#8211; Fastest way of retrieving data through PDO</h4>
<pre>
$res=$db->query("select * from users",PDO::FETCH_ASSOC);
foreach($res as $row){
   // returns an associated array
}
</pre>
<h4>Lazy fetches</h4>
<ul>
<li>Lazy fetches results in a form object, but holds the populating properties until they are actually used.</li>
<li>Prevents PHP from fetching the data until you use it.</li>
</ul>
<h3>Related links</h3>
<ul>
<li><a href="http://us3.php.net/manual/en/ref.pdo.php">PDO Functions</a></li>
<li><a href="http://www.zend.com/php5/articles/php5-mysqli.php#Heading10">Prepared Statements and Bound Parameters</a> (from an article about using ext/mysqli)</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/06/16/nyphp-con-introduction-to-pdo/feed/</wfw:commentRss>
		<slash:comments>4</slash:comments>
		</item>
		<item>
		<title>NYPHP Con: &#8220;Maximum Velocity MySQL&#8221; &#8211; Benchmarking and Profiling</title>
		<link>http://tiffanybbrown.com/2006/06/14/mysql-benchmarking-profiling/</link>
		<comments>http://tiffanybbrown.com/2006/06/14/mysql-benchmarking-profiling/#comments</comments>
		<pubDate>Thu, 15 Jun 2006 02:12:13 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[NYPHPCon2006]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/647</guid>
		<description><![CDATA[Jay Pipes is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. This is part three of my notes. This post may contain inaccuracies, typos, boo-boos, etc. Jay says his slides will be available on his web site, so be sure to check [...]]]></description>
			<content:encoded><![CDATA[<p class="editors-note"><a href="http://jpipes.com/">Jay Pipes</a> is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. </p>
<p class="editors-note">This is part three of my notes. This post may contain inaccuracies, typos, boo-boos, etc. Jay says his slides will be available <a href="http://jpipes.com/">on his web site</a>, so be sure to check there as well. If you have questions, direct them to Jay or consult the <a href="http://dev.mysql.com/">MySQL documentation</a>.</p>
<h3>Benchmarking and Profiling tips</h3>
<ul>
<li>Give yourself a target</li>
<li>Record everything</li>
<li>Isolate the problem (Shut down other programs. Stop network traffic to machine.)</li>
<li>Get familiar with <a href="http://dev.mysql.com/doc/refman/4.1/en/explain.html">EXPLAIN</a> as a means to optimize queries</li>
<li>Optimize within reason. Makes more sense to speed up the 30 second query than the 1 second query.</li>
</ul>
<h3>Benchmarking Toolbox</h3>
<ul>
<li><a href="http://sysbench.sourceforge.net/">SysBench</a></li>
<li><a href="http://dev.mysql.com/doc/refman/5.1/en/mysqlslap.html">mysqlslap (MySQL version 5.1+)</a></li>
<li><a href="http://httpd.apache.org/docs/1.3/programs/ab.html">Apache bench</a></li>
<li><a href="http://www.vegan.net/tony/supersmack/">Supersmack</a></li>
<li><a href="http://jeremy.zawodny.com/mysql/mybench">MyBench</a></li>
</ul>
<h3>Profiling: Diagnosing a running system to identify performance bottlenecks</h3>
<p>Possible areas for bottlenecks: </p>
<ul>
<li>Identify performance bottlenecks</li>
<li>SQL Coding and Index Usage</li>
<li>Memory</li>
<li>CPU</li>
<li>I/O (Disk)</li>
</ul>
<p> Profiling toolbox</p>
<ul>
<li><a href="http://dev.mysql.com/show/">SHOW commands (SHOW PROCESSLIST, etc&#8230;)</a></li>
<li><a href="http://dev.mysql.com/explain/">EXPLAIN and the Slow Query Log</a></li>
<li><a href="http://jeremy.zawodny.com/mysql/mytop">MyTop</a></li>
<li>List of Linux Power tools (gprof/oprofile and vmstat.ps/top/mpstat/procinfo)</li>
<li><a href="http://pecl.php.net/package/apd/">apd for PHP developers</a> </li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/06/14/mysql-benchmarking-profiling/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NYPHP Con: &#8220;Maximum Velocity MySQL&#8221; &#8211; Optimization and coding tips</title>
		<link>http://tiffanybbrown.com/2006/06/14/mysql-optimization-and-coding-tips/</link>
		<comments>http://tiffanybbrown.com/2006/06/14/mysql-optimization-and-coding-tips/#comments</comments>
		<pubDate>Thu, 15 Jun 2006 01:38:23 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[NYPHPCon2006]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/646</guid>
		<description><![CDATA[With Jay Pipes of MySQL. Jay Pipes is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. This is part two of my notes. This post may contain inaccuracies, typos, boo-boos, etc. Jay says his slides will be available on his web site, [...]]]></description>
			<content:encoded><![CDATA[<p>With Jay Pipes of MySQL.  </p>
<p class="editors-note"><a href="http://jpipes.com/">Jay Pipes</a> is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. </p>
<p class="editors-note">This is part two of my notes. This post may contain inaccuracies, typos, boo-boos, etc. Jay says his slides will be available <a href="http://jpipes.com/">on his web site</a>, so be sure to check there as well. If you have questions, direct them to Jay or consult the <a href="http://dev.mysql.com/">MySQL documentation</a>.</p>
<h3>Developing a database schema</h3>
<ul>
<li>Use the smallest data type necessary</li>
<li><a href="http://en.wikipedia.org/wiki/Database_normalization">Normalize</a> your data; Denormalize only in extreme cases</li>
<li>&#8220;Vertical partitioning&#8221;: Send to a different database based on the range of a key.</li>
<li>Use &#8216;counter tables&#8217; to mitigate query cache issues in InnoDB tables</li>
<li>&#8220;Horizontal partitioning&#8221;: Split data into smaller tables. Put less-frequently accessed, less-frequently updated data in a separate table. Example: have separate tables for user logins and user addresses or interests.</li>
</ul>
<h3>Use indexes wisely</h3>
<ul>
<li>Should have good selectivity (relative uniqueness of the index values to each other; there&#8217;s a way to calculate this)</li>
<li>Look for &#8216;covering index&#8217; opportunities</li>
<li>On multi-column indexes, order is important</li>
<li>As database grows, examine your index. Do you need to modify it?</li>
<li>Remove redundant indexes for faster write performance. Don&#8217;t need more than one index on a field.</li>
</ul>
<h3>Coding tips</h3>
<ul>
<li>Don&#8217;t think in a procedural programming style. Think about &#8216;sets&#8217;: you have two sets of data from which you need to retrieve data. How do you do this?</li>
<li>Break queries into smaller units</li>
<li>Use stored procedures (only available in MySQL 5.x)</li>
<li>Learn to use <a href="http://dev.mysql.com/doc/refman/4.1/en/join.html" title="More about JOIN syntax in the My S Q L documentation">JOINS</a> effectively. Can often use a join instead of a subquery.</li>
<li>When you use a function on an indexed function, the index will be ignored</li>
<li>Use the ON DUPLICATE KEY UPDATE clause of the insert statement. No need to check first if the record exists then update or delete (Related: <a href="http://www.mysqlperformanceblog.com/2006/05/29/insert-on-duplicate-key-update-and-summary-counters/">INSERT ON DUPLICATE KEY UPDATE and summary counters</a>)</li>
<li>TRUNCATE TABLE is typically faster than deleting records</li>
</ul>
<h3>Bulk loading performance</h3>
<ul>
<li>Always use multi-record INSERT for mass bulk uploading</li>
<li>Use ALTER TABLE &#8230; DISABLE KEYS syntax. It disables all indexes except for unique ones</li>
<li>Use load data infile, or CSV storage engine (version 5.x only), then ALTER TABLE</li>
<li>If loading into an InnoDB table, insert into a MyISAM table, then select from there into an InnoDB table</li>
<li>To add or drop multiple indexes, use ALTER TABLE rather than multiple CREATE or DROP INDEX statements</li>
</ul>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/06/14/mysql-optimization-and-coding-tips/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>NYPHP Con: &#8220;Maximum Velocity MySQL&#8221; &#8211; Indexes and storage engines</title>
		<link>http://tiffanybbrown.com/2006/06/14/mysql-indexes-storage-engines/</link>
		<comments>http://tiffanybbrown.com/2006/06/14/mysql-indexes-storage-engines/#comments</comments>
		<pubDate>Wed, 14 Jun 2006 16:04:00 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>
		<category><![CDATA[NYPHPCon2006]]></category>
		<category><![CDATA[databases]]></category>
		<category><![CDATA[mysql]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/viewqb.php/645</guid>
		<description><![CDATA[With Jay Pipes of MySQL. Diversity stats, in case you&#8217;re wondering: Men: about 30. Women: 4. People of color: 4. Jay Pipes is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. This is part one of my notes. This post may contain [...]]]></description>
			<content:encoded><![CDATA[<p>With Jay Pipes of MySQL. Diversity stats, in case you&#8217;re wondering: Men: about 30. Women: 4. People of color: 4.</p>
<p class="editors-note"><a href="http://jpipes.com/">Jay Pipes</a> is the Community Relations Manager, North America for MySQL, Inc. This was a three-hour tutorial about ways to fine-tune your MySQL queries. </p>
<p class="editors-note">This is part one of my notes. This post may contain inaccuracies, typos, boo-boos, etc. Jay says his slides will be available <a href="http://jpipes.com/">on his web site</a>, so be sure to check there as well. If you have questions, direct them to Jay or consult the <a href="http://dev.mysql.com/">MySQL documentation</a>.</p>
<h3>Indexes</h3>
<ul>
<li>Gives you a sorted order that allows you to find things quickly. </li>
<li>Indexes speed up select or read statements. </li>
<li>Indexes slow down writing to the database because MySQL not only has to write the record, but also has to write the index.</li>
</ul>
<p>The kind of indexes available and their efficiency depends on the type of storage engine you choose. Keep your indexes slim on write-intensive applications.</p>
<h3>Types of storage engines</h3>
<p>Choose your table&#8217;s storage engine type based on the type of information it holds, and the function for which you will use the table. Can mix table types in the same database.</p>
<h4>MyISAM</h4>
<ul>
<li>Unclustered data storage</li>
<li>Good insert performance and good with concurrent inserts</li>
<li>Small foot print</li>
<li>B-tree, r-tree and FULLTEXT indexing; Can use for spatial calculations, such as ZIP codes</li>
<li>Poor concurrent update and delete performance</li>
<li>No foreign key support; You can use a foreign key, but relational integrity is not guaranteed. (Forthcoming in version 5.2)</li>
<li>No transactions available</li>
</ul>
<p>Good for warehousing data, logging data and auditing data. </p>
<h4>InnoDB</h4>
<p>Good for when you need a lot of concurrent updates and will be looking data up by ID. Good for online transaction processing.</p>
<ul>
<li>NO FULLTEXT indexing or spacial data (r-tree indexes). </li>
<li>Large memory usage and a large data footprint.</li>
<li>Full transactional support</li>
<li>Support for foreign keys</li>
<li>Be sure to set a primary key, and use the smallest possible key (INT not BIGINT). If you don&#8217;t InnoDB will create it&#8217;s own super-integer index. Because of the way InnoDB handles indexes, this <em>is not</em> desirable. </li>
</ul>
<h4>Archive</h4>
<p>Good for archiving, audit logging, and distributable media (for example, applications that you don&#8217;t want the user to be able to modify).</p>
<ul>
<li>Quick inserts and table scans</li>
<li>Read-only</li>
<li>Zlib compression</li>
<li>No indexes allowed</li>
<li>No foreign key support</li>
</ul>
<h4>Memory / HEAP</h4>
<p>Great for temporary tables, session data, calculation tables, or information that will be requested frequently.</p>
<ul>
<li>Very, very fast selects because it&#8217;s all stored in memory</li>
<li>Supports hash or b-tree indexes</li>
<li>Data is gone on reboot, but you can get around this with <code>init_file</code> or my.cnf/my.ini.</li>
<li>Limited by amount of memory available on the server</li>
</ul>
<p>Can combine engine types within the database to take advantage of each storage engine&#8217;s strengths.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2006/06/14/mysql-indexes-storage-engines/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>One more way to use COUNT(*)</title>
		<link>http://tiffanybbrown.com/2005/03/10/one_more_way_to_use_count/</link>
		<comments>http://tiffanybbrown.com/2005/03/10/one_more_way_to_use_count/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2005/03/10/one_more_way_to_use_count</guid>
		<description><![CDATA[Gavin adds a way to make your COUNT(*) query just a little bit cleaner for use in PHP: SELECT field_name, COUNT(*) AS total FROM table_name WHERE id > 3 GROUP BY field_name ORDER BY total ASC; The &#8216;AS total&#8217; bit is a big deal because now COUNT(*) will become a key named &#8216;total&#8217; in the [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://gmontague.co.uk/">Gavin</a> adds a way to make your <code>COUNT(*) </code> query just a little bit cleaner for use in PHP:</p>
<pre>
SELECT field_name, COUNT(*) <span style="color:#c00;">AS total</span>
FROM table_name WHERE id > 3
GROUP BY field_name ORDER BY total ASC;
</pre>
<p>The &#8216;AS total&#8217; bit is a big deal because now <code>COUNT(*)</code> will become a key named &#8216;total&#8217; in the array. So instead of <code>$result['COUNT(*)']</code>, you&#8217;d use <code>$result['total'];</code></p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2005/03/10/one_more_way_to_use_count/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Firefox Google searches, Gmail Atom feeds, and COUNT(*)-ing stuff in MySQL</title>
		<link>http://tiffanybbrown.com/2005/03/08/firefox_google_searches_gmail_atom_feeds_and_counting_stuff_in_mysql/</link>
		<comments>http://tiffanybbrown.com/2005/03/08/firefox_google_searches_gmail_atom_feeds_and_counting_stuff_in_mysql/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[Internet life]]></category>
		<category><![CDATA[MySQL / Databases]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2005/03/08/firefox_google_searches_gmail_atom_feeds_and_counting_stuff_in_mysql</guid>
		<description><![CDATA[I found out by accident that you can do a Google &#8220;I&#8217;m Feeling Lucky&#8221; search right from the Firefox address bar. This is not the same as the search box to the right of the address bar.I&#8217;m talking about the same place where you type a URI to visit a site. Type in your search [...]]]></description>
			<content:encoded><![CDATA[<p>I found out by accident that you can do a  <a href="http://google.com/">Google</a> &#8220;I&#8217;m Feeling Lucky&#8221; search right from the Firefox address bar. This is <strong>not</strong> the same as the search box to the right of the address bar.I&#8217;m talking about the same place where you type a <abbr title="Uniform Resource Identifier">URI</abbr> to visit a site.</p>
<p>Type in your search terms and hit Enter. The page you come to will be the first Google result  &#8212; same as if you hit the &#8220;I&#8217;m Feeling Lucky&#8221; button on the Google homepage. </p>
<h3>Wow &#8230; Gmail has Atom feeds!</h3>
<p>I just realized this today. Which is kind of funny since I use Gmail on Firefox daily. Not real observant am I? Or maybe it&#8217;s a new thing for my particular account. Anyway, you can now have an <abbr title="eXtensible Markup Language">XML</abbr> feed of your email messages stored in your Firefox live bookmarks (or what have you). </p>
<p>Now, if you <strong>still</strong> don&#8217;t have a Gmail account, I&#8217;ve got an a**-load of invites to share. Me thinks Gmail will be out beta by summer. &#8230; um, maybe fall.</p>
<h3>MySQL&#8217;s <code>COUNT(*)</code> &#8230;</h3>
<p>&#8230; function is my new best friend. It makes it easier to sort and count how many of each item exists in the database. The syntax is simple:</p>
<pre>
SELECT field_name, COUNT(*)
FROM table_name
GROUP BY field_name;
</pre>
<p>The above query will sort each record based on its result. So if, for example, you a database of dogs, and you have a field name called &#8220;breed,&#8221; the above query would count how many German shepherds, Labrador retrievers, shi-tzus and pulis are in the database.</p>
<p>Now the cool part is that you can add criteria to the <a href="http://dev.mysql.com/doc/mysql/en/group-by-functions.html"><code>COUNT(*)</code></a> query, just as you would with a regular <abbr class="say">SQL</abbr> statement. For example:</p>
<pre>
SELECT field_name, COUNT(*)
FROM table_name WHERE id > 3
GROUP BY field_name;
</pre>
<p>And you can even sort the results by <code>COUNT(*)</code> like so: </p>
<pre>
SELECT field_name, COUNT(*)
FROM table_name WHERE id > 3
GROUP BY field_name ORDER BY 'COUNT(*)' ASC;
</pre>
<p>Note that in the &#8216;order by&#8217; clause, <strong><code>COUNT(*)</code> needs to be enclosed in quotes</strong> so that <abbr title="My S Q L">MySQL</abbr> handles it as a field name, rather than a second invocation of the function.</p>
<p>When using <abbr title="My S Q L">MySQL</abbr> with <abbr class="say">PHP</abbr>, <code>COUNT(*)</code>, &#8216;COUNT(*)&#8217; becomes a key in the the array returned from a select statement.  </p>
<p>To illustrate the point:</p>
<pre>
$query="SELECT breed, COUNT(*) FROM dogs GROUP BY breed";
$doQuery=mysql_query($query);
$result=mysql_fetch_array($doQuery)
</pre>
<p>The above code returns an array called <code>$result</code>. To use the keys and values in that array, you&#8217;d use the same syntax that you would for any other array. In this case, that&#8217;s <code>$result['COUNT(*)']</code>.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2005/03/08/firefox_google_searches_gmail_atom_feeds_and_counting_stuff_in_mysql/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>My S Q L CONCAT() function</title>
		<link>http://tiffanybbrown.com/2003/10/06/my_s_q_l_concat_function/</link>
		<comments>http://tiffanybbrown.com/2003/10/06/my_s_q_l_concat_function/#comments</comments>
		<pubDate>Thu, 01 Jan 1970 00:00:00 +0000</pubDate>
		<dc:creator>tiffany</dc:creator>
				<category><![CDATA[MySQL / Databases]]></category>

		<guid isPermaLink="false">http://tiffanybbrown.com/2003/10/06/my_s_q_l_concat_function</guid>
		<description><![CDATA[I&#8217;m building the back-end for JAWS.org, which will ?¢‚Ç¨‚Äù among other things ?¢‚Ç¨‚Äù allow members to search for other members by name. I wanted users to be able to search whole names (such as &#8220;Tiffany Brown&#8221;). But I couldn&#8217;t figure out how. Here&#8217;s a query similar to the original: SELECT * FROM membership WHERE firstName [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m building the back-end for <a href="http://www.jaws.org/">JAWS.org</a>, which will ?¢‚Ç¨‚Äù among other things ?¢‚Ç¨‚Äù allow members to search for other members by name.</p>
<p>I wanted users to be able to search whole names (such as &#8220;Tiffany Brown&#8221;). But I couldn&#8217;t figure out how.</p>
<p>Here&#8217;s a query similar to the original:<br />
<code style="display:block;background:#eee;border:1px solid #ccc;margin:4px;padding:10px;color:#000;"><br />
SELECT * FROM membership WHERE firstName OR lastName LIKE '%$searchTerm%';<br />
</code><br />
Those % signs are wild card symbols in <abbr title="Server Query Language">SQL</abbr>.</p>
<p>But the above query would only allow users to search for a member&#8217;s first name <em>or</em> last name.</p>
<p><code>CONCAT()</code> to the rescue.</p>
<p>The <code><a href="http://www.mysql.com/doc/en/String_functions.html">CONCAT()</a></code> function of <abbr title="My Server Query Language">MySQL</abbr> server allows you to <em>concatenate</em> or put strings together [<a href="http://searchvb.techtarget.com/sDefinition/0,,sid8_gci214439,00.html">get a definition for 'string'</a>]. And here&#8217;s the handy part: when used in a query, <code>CONCAT()</code> will substitute the values in record for the names of the database fields.</p>
<p>That means you could use the <code>CONCAT()</code> function to do the following:</p>
<p><code style="display:block;background:#eee;border:1px solid #ccc;margin:4px;padding:10px;color:#000;"><br />
SELECT * FROM membership WHERE CONCAT(firstName,' ',lastName) LIKE '%$searchTerm%';<br />
</code></p>
<p>The above query would compare the value of <code>$searchTerm</code> to the concatenated string formed by the values for <code>firstName lastName</code>.</p>
<p>Here&#8217;s an example: let&#8217;s say you&#8217;re trying to find a member named Tina Jenkins. Running the above query would grab the string &#8220;Tina Jenkins&#8221; from the database, then compare it to the search term using the LIKE operator.</p>
<p>That means if you searched using &#8220;Tina&#8221;, &#8220;Jenkins&#8221;, &#8220;Tina Jenkins&#8221; or &#8220;Tina Jen&#8221;, you would find results for the member Tina Jenkins.</p>
<p>Thanks and shout-outs to <strong>Griff and kajakske</strong> over at <a href="http://www.sitepointforums.com/showthread.php?threadid=130754">SitePoint Forums</a> for asking and answering a similar question.</p>
]]></content:encoded>
			<wfw:commentRss>http://tiffanybbrown.com/2003/10/06/my_s_q_l_concat_function/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

