<?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>Christoph Bünte &nbsp;&raquo; Software Entwicklung Berlin</title>
	<atom:link href="http://www.christophbuente.de/tag/counter_cache/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.christophbuente.de</link>
	<description>Software Entwicklung</description>
	<lastBuildDate>Tue, 07 Dec 2010 11:30:07 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.5</generator>
		<item>
		<title>Objekte und Beziehungen</title>
		<link>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/</link>
		<comments>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/#comments</comments>
		<pubDate>Sun, 05 Aug 2007 10:05:20 +0000</pubDate>
		<dc:creator>Christoph Bünte</dc:creator>
				<category><![CDATA[Datenbanken]]></category>
		<category><![CDATA[Ruby on Rails]]></category>
		<category><![CDATA[anzahl der kinder]]></category>
		<category><![CDATA[counter_cache]]></category>
		<category><![CDATA[parent id]]></category>
		<category><![CDATA[sql]]></category>

		<guid isPermaLink="false">http://www.christophbuente.de/2007/08/05/objekte-und-beziehungen/</guid>
		<description><![CDATA[Wie im täglichen Leben stehen auch bei der programmatischen Nachbildung der Wirklichkeit Objekte oft in einer bestimmten Beziehung zu einander. Dabei unterscheidet man zwischen 1:1, 1:n und m:n Beziehungen. Neulich wollte ich in einer kleinen Rails Web-Applikation (siehe aktuelle Literatur) eine Ansicht einer 1:n Beziehung zweier Objekte in Listenform erstellen. Die Anforderung war allerdings, die [...]]]></description>
			<content:encoded><![CDATA[<p>Wie im täglichen Leben stehen auch bei der programmatischen Nachbildung der Wirklichkeit Objekte oft in einer bestimmten Beziehung zu einander. Dabei unterscheidet man zwischen 1:1,  1:n und m:n Beziehungen.</p>
<p>Neulich wollte ich in einer kleinen Rails Web-Applikation (siehe aktuelle Literatur) eine Ansicht einer 1:n Beziehung zweier Objekte in Listenform erstellen. Die Anforderung war allerdings, die Liste nach der Anzahl der Kinder zu sortieren und dabei die Objekte zuerst anzuzeigen, die keine Kinder haben.</p>
<p><span id="more-11"></span></p>
<p>[ad#vert-banner]</p>
<p>Damit die Ergebnismenge des SELECT Statements auch die Eltern Objekte enthält, die keine Kinder besitzen, muss ein LEFT JOIN verwendet werden. Grundsätzlich ist das zwar etwas mehr Aufwand für die Datenbank, aber dennoch schaffbar, ohne eine Ewigkeit warten zu müssen. Mit Hilfe von Indizierungen lässt sich die ganze Sache auch hinreichend beschleunigen. Das folgende SQL Statement erfüllt diese erste Anforderung:</p>
<pre lang="sql">
SELECT p.name, c.name
FROM parents AS p
LEFT JOIN children AS c
ON p.id=c.parent_id</pre>
<p>Allerdings fehlt hier die Sortierung. Das zweite Problem ist, dass das Feld <code>c.name</code> für alle kinderlosen Eltern NULL ist, und somit nicht gezählt werden kann. Folgendes Statement behebt zwar das Problem, aber die Ausführung braucht bei großen Tabellen Jahre.</p>
<pre lang="sql">
SELECT IF(c.id IS NULL,0,COUNT(*)) AS kids, p.name
FROM parents AS p
LEFT JOIN children AS c ON p.id=c.parent_id
ORDER BY kids
GROUP BY p.id</pre>
<p>Die lange Ausführungsdauer hat vor allem einen Grund: Die Sortierung geschieht auf einer Spalte, die effektiv nicht existiert, sondern erst zur Laufzeit mit Hilfe der Count Funktion erzeugt wird. Das heißt es muss erst ein kompletter Join über beide Tabellen durchgeführt werden, ehe eine Sortierung stattfinden kann. Auch eine Limitierung der Ergebnisliste mit Hilfe von LIMIT ändert daran nichts, denn die würde erst nach der Sortierung durchgeführt.</p>
<p>Um diese lange Wartezeiten zu vermeiden, habe ich mir folgendes überlegt: Man baut in die Tabelle der Elternklasse eine Spalte ein, die die Anzahl der Kinder speichert. Nun muss &#8220;nur noch&#8221; beim hinzufügen und löschen eines Kindes diese Spalte gepflegt werden. Das heißt, meine Applikation ist für die Datenintegrität zuständig.</p>
<p>Zurück zu Rails, denn da ist dieses Funktionalität bereits an Board. Getreu dem Motto &#8220;Konvention über Konfiguration&#8221;, erzeugt man lediglich die Spalte in der Tabelle der Elternklasse. Diese trägt den sprechenden Namen &lt;kindertabelle&gt;_count also in diesem falls children_count. In der Kinderklasse wird nun noch deklariert, dass der Zähler automatisch aktualisiert wird.</p>
<pre lang="ruby">
class Child < ActiveRecord::Base
  belongs_to :parent, :counter_cache => true
end</pre>
<p>Und siehe da, nun lässt sich eine normaler Finder verwenden, um den View aufzubauen. Komplett ohne JOIN!</p>
<pre lang="ruby">@parents = Parent.find(
  :all,
  :limit => 20,
  <img src='http://www.christophbuente.de/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> ffset => @parent_pages.current.to_sql[1],
  <img src='http://www.christophbuente.de/wp-includes/images/smilies/icon_surprised.gif' alt=':o' class='wp-smiley' /> rder => "children_count ASC, parent ASC")</pre>
<p>Da jetzt nur noch real existierende Spalten für die Sortierung verwendet werden und eine effektive Limitierung der Ergebnismenge möglich ist, dauert die Anfrage nur noch wenige ms.</p>
<p>Thx Rails!</p>
<div id="crp_related"><h3>Ähnliche Beiträge:</h3><ul><li><a href="http://www.christophbuente.de/2007-10-05-frei-nehmen-um-zu-lernen/" rel="bookmark" class="crp_title">Rails tutorial &#8211;  Eine Woche lang Agile Webentwicklung</a></li><li><a href="http://www.christophbuente.de/2008-07-01-mysql-myisam-index-oder-nicht/" rel="bookmark" class="crp_title">MySQL MyISAM &#8211; Index oder nicht?</a></li><li><a href="http://www.christophbuente.de/2007-06-19-performance-tests/" rel="bookmark" class="crp_title">Performance Tests</a></li><li><a href="http://www.christophbuente.de/2007-11-24-advancing-rails-ein-workshop-mit-david-a-black/" rel="bookmark" class="crp_title">Advancing Rails &#8211; Ein Workshop mit David A. Black</a></li><li><a href="http://www.christophbuente.de/2008-01-24-stripes-framework-tests-fur-actionbeans-im-wizard-modus/" rel="bookmark" class="crp_title">Stripes Framework &#8211; Tests für ActionBeans im Wizard Modus</a></li></ul></div>]]></content:encoded>
			<wfw:commentRss>http://www.christophbuente.de/2007-08-05-objekte-und-beziehungen/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

<!-- Performance optimized by W3 Total Cache. Learn more: http://www.w3-edge.com/wordpress-plugins/

Minified using memcached (Feed is rejected)
Page Caching using memcached
Database Caching 2/18 queries in 0.011 seconds using memcached
Object Caching 462/487 objects using memcached

Served from: www.christophbuente.de @ 2012-02-08 09:48:51 -->
