<?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>Lieber Linux &#187; Query</title>
	<atom:link href="http://www.lieber-linux.de/tag/query/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.lieber-linux.de</link>
	<description>Linux und Open Source Software im Blog</description>
	<lastBuildDate>Thu, 26 Jan 2012 17:58:46 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.2</generator>
		<item>
		<title>phpmyadmin-Update und alte Features</title>
		<link>http://www.lieber-linux.de/2009/03/phpmyadmin-update-und-alte-features/</link>
		<comments>http://www.lieber-linux.de/2009/03/phpmyadmin-update-und-alte-features/#comments</comments>
		<pubDate>Mon, 23 Mar 2009 22:06:49 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Tipp]]></category>
		<category><![CDATA[Editor]]></category>
		<category><![CDATA[Konfiguration]]></category>
		<category><![CDATA[phpmyadmin]]></category>
		<category><![CDATA[Problem]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[Update]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=371</guid>
		<description><![CDATA[Nach einem Update von phpmyadmin von 2.11.6 auf die neue 3.1.3 waren mir vertraute Features plötzlich nicht mehr sichtbar. Falls es einigen von Euch genauso ging, hier ein kleiner Tipp, wie man die alte Ansicht wiederbekommt. Man öffne die Datei config.inc.php und füge nach der Server-Konfiguration die folgenden Zeilen ein: $cfg['DefaultTabTable'] = 'tbl_structure.php'; $cfg['LeftDefaultTabTable'] = [...]]]></description>
			<content:encoded><![CDATA[<p>Nach einem <strong>Update</strong> von <strong>phpmyadmin</strong> von 2.11.6 auf die neue 3.1.3 waren mir vertraute Features plötzlich nicht mehr sichtbar. Falls es einigen von Euch genauso ging, hier ein kleiner Tipp, wie man die alte Ansicht wiederbekommt.</p>
<p>Man öffne die Datei <em>config.inc.php</em> und füge nach der Server-Konfiguration die folgenden Zeilen ein:</p>
<pre>$cfg['DefaultTabTable'] = 'tbl_structure.php';
$cfg['LeftDefaultTabTable'] = 'tbl_structure.php';
$cfg['SQLQuery']['Edit'] = TRUE;</pre>
<p>Zur Erklärung: Klickt man links in die Spaltenansicht aller Tabellen, so öffnete die alte Version standardmäßig die Tabellenstruktur, nun sind es die ersten 30 Einträge. Diese Umstellung wird durch die erste und zweite Zeile rückgängig gemacht. Sicherlich werden viele die Einträge auch gern sehen wollen. In meinem Falle benutze ich phpmyadmin nicht unbedingt zur Datenrecherche, sondern ganz oft für Arbeiten an der <strong>MySQL</strong>-Tabellenstruktur. Dafür finde ich die alte Einstiegsseite besser geeignet.</p>
<p>Die letzte Zeile korrigiert den fehlenden <em>&#8220;Bearbeiten&#8221;</em>-Link, nachdem ein Query an <strong>MySQL</strong> abgesetzt wurde. Denn häufig starte ich damit, einen ersten <strong>Query</strong>-Entwurf abzusetzen, dann mittels <em>&#8220;Bearbeiten&#8221;</em> ein Popup-Fenster zu öffnen, um dort mein <strong>Query</strong> weiter feiner zu granulieren, ohne dass ein Klick im Browserfenster mein <strong>Query</strong> verwirft.</p>
<p>Ansonsten kann ich das <strong>Update</strong> schon aus Sicherheitsgründen nur wärmstens empfehlen!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2009/03/phpmyadmin-update-und-alte-features/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>SQL im Webshop: Suche nach Modified</title>
		<link>http://www.lieber-linux.de/2008/07/sql-im-webshop-suche-nach-modified/</link>
		<comments>http://www.lieber-linux.de/2008/07/sql-im-webshop-suche-nach-modified/#comments</comments>
		<pubDate>Thu, 31 Jul 2008 14:22:57 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[MySQL]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[SQL]]></category>
		<category><![CDATA[Webshop]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=24</guid>
		<description><![CDATA[Größere Netzwerke, Suchmaschinen oder auch mal eben der kleine Statusbalken arbeiten viel besser, wenn man einen Zeitstempel zur Verfügung stellen kann à la &#8220;Dieser Artikel oder dieses Produkt wurde zuletzt geändert am &#8230;&#8221;. Das ist allerdings nicht ganz so easy, wenn sich die Daten des Satzes in verschiedenen Tabellen befinden. Also muss man die sich [...]]]></description>
			<content:encoded><![CDATA[<p>Größere Netzwerke, Suchmaschinen oder auch mal eben der kleine Statusbalken arbeiten viel besser, wenn man einen Zeitstempel zur Verfügung stellen kann à la &#8220;Dieser Artikel oder dieses Produkt wurde zuletzt geändert am &#8230;&#8221;.</p>
<p>Das ist allerdings nicht ganz so easy, wenn sich die Daten des Satzes in verschiedenen Tabellen befinden. Also muss man die sich mühevoll zusammenklauben. Bei uns im Shop sind es eigentlich nur eine Handvoll Tabellen: Der Artikeleintrag in der Warenwirtschaft, die Varianten, die Preise, Rabatte, Shop-Eintrag, Shop-Texte und Shop-Fotos.</p>
<p><span id="more-24"></span>Die Einträge wurden aus eben diese Tabellen zusammengesucht. Aus Performance-Gründen bieten sich hier Stored Procedures an:<br />
<span style="color: #ff0000;">DELIMITER &#8216;$&#8217;;<br />
CREATE FUNCTION f_getModified(&#8230;xyz&#8230;) RETURNS Datetime READS SQL DATA<br />
BEGIN<br />
DECLARE last DATETIME;<br />
DECLARE cur DATETIME;<br />
SELECT Timestamp INTO last FROM Tbl_XYZ INTO last WHERE xyz;<br />
SELECT Timestamp INTO cur FROM Tbl_XYZ cur WHERE xyz;<br />
SET last = IF(cur &gt; last, cur, last);<br />
&#8230;<br />
RETURN last;<br />
END$<br />
DELIMITER &#8216;;&#8217;$</span></p>
<p>Natürlich schrumpft die Performance bei zunehmender Fragmentierung der Produktdaten erheblich, da die Berechnungskosten linear steigen. Aus diesem Grund habe ich überlegt, die Tabellen über INNER JOINS zu verknüpfen, und die Zeitstempel zunächst in einem Ritt zu holen:<br />
<span style="color: #ff0000;">DELIMITER &#8216;$&#8217;;<br />
CREATE FUNCTION f_getModified(&#8230;xyz&#8230;) RETURNS Datetime READS SQL DATA<br />
BEGIN<br />
DECLARE last DATETIME;<br />
DECLARE cur DATETIME;<br />
SELECT a.Timestamp, b.Timestamp INTO last,cur FROM Tbl_XYZ a INNER JOIN TblXYZ b ON a.x=b.x AND a.y=b.y WHERE xyz;<br />
SET last = IF(cur &gt; last, cur, last);<br />
RETURN last;<br />
END$<br />
DELIMITER &#8216;;&#8217;$</span></p>
<p>Auf meine 7 Tabellen angewendet, gibt das immerhin einen 10%-igen Performance-Schub. Nicht unerheblich, aber trotzdem nicht der Bringer. Anfangs waren es über 50% Geschwindigkeitsvorteil, als ich mit einfachen INNER JOINS über die ersten Tabellen arbeitete. Doch da es nicht immer entsprechende Einträge geben muss, ist man hier und da gezwungen, ein paar LEFT JOIN einzusetzen, welche als OUTER JOIN natürlich langsamer sind.</p>
<p>Ein weiteres Problem ist, dass nicht alle Tabellen einen Eintrag pro Produkt bieten, d.h. an dieser Stelle sind Sub-SELECTS vonnötigen, die den Zeitstempel über MAX(Timestamp) zunächst in der Ziel-Tabelle aggregieren, bevor der INNER JOIN einsetzt.</p>
<p>Letztendlich hatte ich bei einer entsprechend aufbereiteten Seite doch eher dazu tendiert, die bereits mit dem PHP-Script ausgelesenen Timestamps und die fehlenden Stempel per Hash-Scan zu ergänzen. An dieser Stelle konnte ich die Kosten für die Zeitstempel auf 20% der Procedure-Kosten drücken &#8211; allerdings ist diese Vorgehensweise nicht an allen Stellen die beste.</p>
<p>Doch bietet eine Seite nicht auch noch mehr? FAQs? Bewertungen? Mitkaufartikel? Hat sich die Seite nicht auch deswegen geändert, weil hier und da ein Eintrag dazugekommen ist? Was passiert, wenn sich eine Seite geändert hat, weil ein Eintrag <strong>wegfiel</strong>? Gar nicht so einfach, und ich möchte gern wissen, wie das &#8220;große&#8221; Shops so machen&#8230;Wer Ideen hat, ist zum Posten gerne eingeladen!</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2008/07/sql-im-webshop-suche-nach-modified/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL vs. Postgres &#8211; never ending story?</title>
		<link>http://www.lieber-linux.de/2008/07/mysql-vs-postgres-never-ending-story/</link>
		<comments>http://www.lieber-linux.de/2008/07/mysql-vs-postgres-never-ending-story/#comments</comments>
		<pubDate>Sun, 27 Jul 2008 09:57:09 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Chemitzer Linux-Tage]]></category>
		<category><![CDATA[DBMS]]></category>
		<category><![CDATA[Performance]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[Postgresql]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[Tuning]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=23</guid>
		<description><![CDATA[Ich habe mal wieder darüber nachgedacht, ob es nicht Zeit wäre, von MySQL auf Postgres umzusteigen. Bei den diesjährigen Chemnitzer Linux-Tagen habe ich ein interessantes Gespräch mit einem der Postgres-Leute gehabt. Seitdem laufen beide Datenbanken auf meinem Laptop und warten darauf, eingehend verglichen zu werden.Allein die Aufstellung der Testaufgabe und Umgebung beeinflusst jedoch dermaßen die [...]]]></description>
			<content:encoded><![CDATA[<p>Ich habe mal wieder darüber nachgedacht, ob es nicht Zeit wäre, von <a href="http://www.mysql.com/" target="_blank">MySQL</a> auf <a href="http://www.postgresql.org/" target="_blank">Postgres</a> umzusteigen. Bei den diesjährigen <a href="http://chemnitzer.linux-tage.de/2008/info/" target="_blank">Chemnitzer Linux-Tagen</a> habe ich ein interessantes Gespräch mit einem der Postgres-Leute gehabt. Seitdem laufen beide Datenbanken auf meinem Laptop und warten darauf, eingehend verglichen zu werden.<span id="more-23"></span>Allein die Aufstellung der Testaufgabe und Umgebung beeinflusst jedoch dermaßen die Performance, dass ich davor zurückschrecke, die Geschwindigkeit mit ein paar naiven Query-Loops gegeneinanderzustellen. Aus Erfahrung mit MySQL weiß ich, dass Tuning der Datenbankparameter mehr als 50%Â  ausmachen können, geschweige denn das Tabellendesign und die richtige Wahl der Indizes &#8211; hier liegen einfach Welten drin.</p>
<p>Außerdem verwenden wir für 90% unserer Daten MyISAM-Tabellen, die sich jedoch nur schwer mit Postgres vergleichen lassen. Da sollte man schon InnoDB verwenden und auf dieselben Features zurückgreifen, zum Beispiel Transaktionen, Referentielle Integrität oder Row Level Locking, welches ich mal mit zeilenbasiertes Sperren übersetzen möchte.</p>
<p>Es gibt jedoch eine Menge <a href="http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html" target="_blank">Sites</a>, die aus ihren <a href="http://2bits.com/articles/benchmarking-postgresql-vs-mysql-performance-using-drupal-5x.html" target="_blank">eigenen Tests</a> die eine oder andere Datenbank stets als schneller evaluiert haben, zB Drupal. Man sollte da einfach mal nach &#8220;MySQL Postgres&#8221; googlen. Man kann dabei aber schnell ins religiöse Halblicht reingezogen werden. <img src='http://www.lieber-linux.de/wp-includes/images/smilies/icon_smile.gif' alt=':-)' class='wp-smiley' />  Die Tests werden meist von <a href="http://developers.slashdot.org/article.pl?sid=06/12/18/1152230&amp;from=rss" target="_blank">Advocacies und Flamewars</a> begleitet, die dann meistens die Tests selbst als ungenügend kritisieren oder alles für alte Banane abtun, da Version X.Y.4a ihres Lieblingsprodukts ja alle genannten Kritikpunkte wegsprenge.</p>
<p>Richtig ist: <a href="http://www-css.fnal.gov/dsg/external/freeware/pgsql-vs-mysql.html" target="_blank">Features und Konsistenz</a> bedürfen nun mal Rechenzeit. Je nachdem, wie gut das DBMS programmiert ist, wählt es für jede der Aufgaben den minimalen Mechanismus im Sinne der zugrundeliegenden Architektur. Daraus ergeben sich für die ein oder andere Funktion verschiedene Laufzeiten. Im großen und ganzen sollte die Summe jedoch recht ausgeglichen sein.</p>
<p>Beide Datenbanken haben in den letzten Jahren durch den Hype von Open Source Software im Business-Umfeld offensichtlich stark zugelegt. Nicht zuletzt, weil die Anzahl der Installation und damit auch Anforderungen an diese und das Bug-Reporting ordentlich anstiegen. Dass die Daten gut verpackt und fehlerfrei so rauskommen, wie man diese einmal reingeworfen hat, das kann man beiden System also ohne Zweifel voraussetzen.</p>
<p>Wichtig im Sinne eines stressfreien Einsatzes erscheinen mir daher eher solche Dinge wie Installationshandling, Rechteverwaltung, Unterstützung häufiger Datenmanipulationsaufgaben oder In- bzw. Export von Daten.Â  Für Profis eventuell noch wichtig: Replikation, Failover oder Backup. Am meisten interessiert sicherlich das Gros der Leute, ob die <a href="http://www.php.net/manual/de/ref.pgsql.php" target="_blank">PHP-Anbindung</a> sauber funktioniert und alle Aufgaben einwandfrei unterstützt werden.</p>
<p>Wenn man mehrere parallele Threads laufen hat, zB bei gleichzeitigen Zugriffen auf eine gut besuchte Webseite mit vielen Datenbankoperationen, zählen sicherlich auch nochÂ  andere Performance-Werte:</p>
<ul>
<li>Die Anzahl der konkurrierenden Zugriffe</li>
<li>der dabei entstehende Speicherbedarf (&#8220;memory footprint&#8221;)</li>
<li>das initiale Delay einer Abfrage.</li>
</ul>
<p>Allerdings sind das Sphären, in denen die meisten DBA zu Replikation greifen werden. Wenn ein Server so am Anschlag ist, dann gibt man ihm doch am besten einen Partner zur Hand.</p>
<p>Deshalb habe ich beschlossen, es vorerst bei MySQL zu belassen. Ich werde also erst einmal schauen, was InnoDB mit Row Level Locking und Referenzieller Integrität für mich noch an Vorteilen zu bieten hat. Hier allein lassen sich schon Performance-Vergleiche anstellen und deren Ergebnisse im Alltag effektiv nutzen.</p>
<p>Erst dann kommt dann Postgres dran &#8211; zunächst wird es mir ums Handling gehen und später um die Performance &#8211; und zwar genau an den auch für InnoDB geeigneten Stellen. An dieser Stelle wird davon zu lesen sein.</p>
<p>Stay tuned !</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2008/07/mysql-vs-postgres-never-ending-story/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Mysqldump</title>
		<link>http://www.lieber-linux.de/2007/05/mysqldump/</link>
		<comments>http://www.lieber-linux.de/2007/05/mysqldump/#comments</comments>
		<pubDate>Fri, 11 May 2007 08:20:44 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Backup]]></category>
		<category><![CDATA[mysqldump]]></category>
		<category><![CDATA[Query]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=11</guid>
		<description><![CDATA[Was ich heute kurz festgestellt habe: Im Gegensatz zu früheren Versionen speichern relativ junge Ausgaben von mysqldump eine komplette Tabelle in einem Insert. Das Ergebnis sieht dann etwa so aus: INSERT INTO tabelle (Feld1, Feld2, Feld3) VALUES ((val1-1, val1-2, val1-3),(val2-1, val2-2, val2-3)); Soweit so gut. Doch bei 500,000 Einträgen in einer vielleicht nicht ganz so [...]]]></description>
			<content:encoded><![CDATA[<p>Was ich heute kurz festgestellt habe: Im Gegensatz zu früheren Versionen speichern relativ junge Ausgaben von mysqldump eine komplette Tabelle in einem Insert. Das Ergebnis sieht dann etwa so aus:</p>
<p>INSERT INTO tabelle (Feld1, Feld2, Feld3) VALUES ((val1-1, val1-2, val1-3),(val2-1, val2-2, val2-3));</p>
<p>Soweit so gut. Doch bei 500,000 Einträgen in einer vielleicht nicht ganz so schmalen Tabelle stellt sich mir natürlich die Frage: Wie spielt man dann ein paar Sätze gezielt zurück, falls mal jemand aus Versehen etwas gelöscht hat?</p>
<p><span id="more-11"></span>Die Fiddelei möchte ich dann doch nicht am Bein haben. Nach etwas Ausprobierei fand ich heraus, dass man mit der Option <strong>&#8211;extended-insert=FALSE</strong> den &#8220;alten&#8221; mysqldump wieder zurückbekommt. Dann wird pro Tabelleneintrag ein INSERT-Befehl erstellt:</p>
<pre>INSERT INTO tabelle (Feld1, Feld2, Feld3) VALUES (val1-1, val1-2, val1-3);
INSERT INTO tabelle (Feld1, Feld2, Feld3) VALUES (val2-1, val2-2, val2-3);</pre>
<p>Das zweite war der Zeichensatz.  Da wir aufgrund der unumstößlichen Bindung an unser Warenwirtschaftssystem auf Windows-Basis keinen kompletten Datenumstieg auf UTF-8 machen können (zumindest nicht zur Zeit), wird bei uns alles in latin1 gespeichert. Sollten wir mal über die europäischen Grenzen hinausexpandieren, dann können wir uns das ja immer noch zur Brust nehmen (dann haben wir aber sicherlich auch nicht mehr diese Warenwirtschaft).</p>
<p>Seit ein paar Versionen speichert nun mysqldum alles per UTF-8. Für ein komplettes Dump ist das auch wieder OK, denn im erzeugten Script sind die CREATE TABLE-Befehle ja mit dem Zeichensatz versehen und mysql weiß dann (hoffentlich), was es mit den INSERT-Datensätzen zu tun hat (nämlich mal kurz konvertieren!).  Um einzelne Sätze in eine laufende Datenbank schnell per Copy&amp;Paste zurückzuspielen, ist das aber unpassend. Hier hilft die Option <strong>&#8211;default-charset=latin1</strong> weiter.</p>
<p>Mit diesen zwei kleinen Anpassungen kann ich nun die nächsten Backups in besserer Verfassung erwarten und gezielte Rückspielungen einfacher angehen. Nachdem das Raidsystem unseres jetzigen Webserver-Providers gerade krachte und wir quasi 48h ohne Online-Shop waren, weiß ich, dass Backups ihre Mühe wert sind.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2007/05/mysqldump/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>MySQL Mustersuche, nur andersherum</title>
		<link>http://www.lieber-linux.de/2007/03/mysql-mustersuche-nur-andersherum/</link>
		<comments>http://www.lieber-linux.de/2007/03/mysql-mustersuche-nur-andersherum/#comments</comments>
		<pubDate>Tue, 27 Mar 2007 08:25:46 +0000</pubDate>
		<dc:creator>Nudge</dc:creator>
				<category><![CDATA[Linux]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Query]]></category>
		<category><![CDATA[Rechteverwaltung]]></category>
		<category><![CDATA[Regular Expression]]></category>

		<guid isPermaLink="false">http://www.lieber-linux.de/?p=8</guid>
		<description><![CDATA[Gestern habe ich mich mit folgender kleiner Aufgabe beschäftigt: Lese- und &#8220;Ausführungs&#8221;-Berechtigung von Intranet-Seiten für die Mitarbeiter. Die 08/15-Lösung: Eine Tabelle, die ungefähr so aussieht: CREATE TABLE IntraBerechtigungen ( id INT NOT NULL AUTO_INCREMENT PRIMARY KEY, Mitarbeiter varchar(255) NOT NULL, Seite varchar(255) NOT NULL, Lesen char(1) DEFAULT 'N', Ausfuehren char(1) DEFAULT 'N', Timestamp timestamp ); [...]]]></description>
			<content:encoded><![CDATA[<p>Gestern habe ich mich mit folgender kleiner Aufgabe beschäftigt: Lese- und &#8220;Ausführungs&#8221;-Berechtigung von Intranet-Seiten für die Mitarbeiter. Die 08/15-Lösung: Eine Tabelle, die ungefähr so aussieht:</p>
<pre>CREATE TABLE IntraBerechtigungen (
  id INT NOT NULL AUTO_INCREMENT PRIMARY KEY,
  Mitarbeiter varchar(255) NOT NULL,
  Seite varchar(255) NOT NULL,
  Lesen char(1) DEFAULT 'N',
  Ausfuehren char(1) DEFAULT 'N',
  Timestamp timestamp
);</pre>
<p>Dann trägt man einfach seine Leute und die entsprechenden Seiten ein. Aber was passiert, wenn jemand neues hinzukommt? Wenn eine Seite hinzukommt oder wegfällt? Viel manuelle Arbeit. Mit Mustern wollte ich daher diese Mühe sparen.</p>
<p><span id="more-8"></span>Wenn man sich die mysql-System-Tabellen <strong>user</strong> oder <strong>db</strong> mal anschaut, findet man ja häufig Einträge wie &#8220;%&#8221; für den Host &#8211; d.h. hier ist der Zugriff von überall aus gestattet. Dasselbe könnte man hier auch anwenden, zB: Erlaube lesende Zugriffe für &#8220;%&#8221; auf die Seiten &#8220;CRM%.php&#8221;. Das würde die Tabelleneinträge in sinnvollem Maße begrenzen und mir erlauben, den Überblick zu behalten.</p>
<p>Der Unterschied zur normalen Mustersuche: Das Muster steckt sonst im PHP-Code, und die Strings in den Spalten der Tabellen. Hier steckt das Muster auf einmal in der Datenbank, aber die Strings im PHP-Code (zB als Benutzername irgendwo in $_SESSION). Das bedeutet leider auch, dass der herkömmliche SELECT</p>
<pre>SELECT Lesen, Ausfuehren
FROM IntraBerechtigungen
WHERE ('Heinz' LIKE Mitarbeiter) AND ('/test.php' LIKE Seite);</pre>
<p>nicht mehr funktioniert. MySQL meldet dabei, dass &#8216;Heinz&#8217; und &#8216;/test.php&#8217; keine validen Spaltennamen sind &#8211; womit es leider auch Recht hat.</p>
<p>Daher muss man die Konstruktion der Ergebnistabelle ein Stück vorziehen, indem man die Spalten zunächst konstruiert, und dann erst auswerten:</p>
<pre>SELECT SUM(Lesen), SUM(Ausfuehren), 'Heinz' AS wer, '/test.php' AS was
FROM `IntraBerechtigungen`
WHERE EXISTS (
  SELECT *
  FROM IntraBerechtigungen
  WHERE (wer LIKE Mitarbeiter) AND (was LIKE Seite)
);</pre>
<p>Damit die Überlagerung verschiedener Einträge (zB &#8220;%&#8221; darf &#8220;%.php&#8221; lesen, &#8220;Heinz&#8221; darf &#8220;%.php&#8221; lesen und ausführen) funktioniert, müssen allerdings die Felder Lesen und Ausführen auf INT(1) geändert werden. NULL oder 0 bedeutet verboten, 1 oder höher bedeutet erlaubt. Durch SUM(Lesen) kann man dann herausfinden, ob Nutzer &#8220;Heinz&#8221; in irgendeiner Form berechtigt ist, die Seite &#8220;/test.php&#8221; zu lesen oder auszuführen.</p>
<p>Auch Gruppenberechtigungen kann man damit abbilden. Dazu kann man in der Tabelle IntraBerechtigungen eine Spalte &#8216;Gruppe&#8217; einführen, und die Nutzer, zB über ein simplen assoziativen Array in PHP, in Gruppen einteilen. *</p>
<pre>$NUTZERGRUPPEN = array(
  'Heinz' =&gt; 'Sales',
  'Werner' =&gt; 'Sales',
  'Inge' =&gt; 'Verkauf'
);</pre>
<p>* Es gibt ja immer wieder Leute, die meinen, so etwas muss man auch in MySQL abbilden, am besten in der 5. Normalform: id für die Gruppe, id für den Mitarbeiter, Verknüpfungstabelle, womöglich noch die Sprachabhängigen Attribute auslagern. Ich halte eine solche Grundeinstellung hochgefährlich für den laufenden Betrieb: Nicht nur die ids können bei einem Crash flöten gehen, auch die Verknüpfungstabellen in einer solchen zerpflückten Datenbank kann keiner mehr ohne Handbuch verstehen. Und statt den 20 Chars des Namen die immerhin 8 Bytes (64-bit-sicher!) INT für die id zu verwenden, spart 12 Byte. Erst kürzlich habe ich eine Platte von 400 GB für etwa 80 Euro erworben. Was sind da 12 Byte? Man spart diese Beträge durch schnellere Bearbeitung allemal. Abgesehen davon wäre für die Auflösung der Gruppenberechtigungen in einem solchen Fall ein Cross-Join über 3 Tabellen notwendig. Direkt in PHP getippt, spart man der DB wie auch dem Benutzer am Bildschirm wertvolle Zeit, indem man auf solche Schulbuchtechniken verzichtet.</p>
]]></content:encoded>
			<wfw:commentRss>http://www.lieber-linux.de/2007/03/mysql-mustersuche-nur-andersherum/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

