phpundmysql.de

Archiv für Februar, 2012

NoSQL: HANDLER Statement in MariaDB

Dienstag, Februar 21st, 2012

Ende 2010 haben wir über HandlerSocket für MySQL berichtet. Mit dem Plugin lassen sich Teile der MySQL Architektur umgehen, was direkten und somit deutlich schnelleren Zugriff auf die Daten erlaubt.

MariaDB, der MySQL Fork von Monty Widenius, ist zwar immer noch so nah am Original, damit auch Handlersocket darin läuft, bietet allerdings eigene Funktionen an, um das gleiche ohne Plugin zu erreichen: HANDLER Kommandos. Darunter sind alternative SQL Kommandos zu SELECTs zu verstehen, die dem Server sagen: Ich will Datensatz xy im Index abc suchen. Der explizite Verweis auf den Index-Eintrag beschleunigt die Abfrage natürlich.

Index Scans
Im Folgenden nutzen wir die Beispieldatenbank employees-db aus dem Launchpad. Anstatt

SELECT * FROM employees WHERE emp_no=100000;

steht dann

HANDLER employees OPEN;
HANDLER employees READ unique_idx=(100000);
HANDLER employees CLOSE;

Statt einem Statement braucht ein Handler zusätzliche OPEN und CLOSE Anweisungen. Der Vorteil des Handlers wird hieraus nicht sichtbar. Das Ergebnis ist nämlich das gleiche wie im obigen SELECT: Es werden alle Spalten des Datensatzes zurückgegeben, in dem die ID gleich 100000 ist. Allerdings erlaubt der Handler, den Index zu durchwandern:

HANDLER employees OPEN;
HANDLER employees READ unique_idx=(100000);
HANDLER employees READ unique_idx NEXT;
HANDLER employees READ unique_idx PREV;
HANDLER employees READ unique_idx LAST;
HANDLER employees CLOSE;

Es lassen sich also mehrere Abfragen innerhalb des Handlers abfackeln. Vorsicht ist allerdings geboten, wenn es um den Index geht. Im obigen Beispiel wird unique_idx verwendet, der in der employees-db nicht von Vornherein angelegt ist. Wir hatten Schwierigkeiten, den Handler mit dem Primary Key zu verwenden, der auch PRIMARY heißt. Hier scheint es einen Konlikt mit dem reservierten Wort zu geben.

Table Scans
Ein Handler muss nicht zwangsläufig auf einen Index verweisen. Es lassen sich auch ganze einfache Tabellen durchlaufen. In den Statements entfallen dann logischerweise nur die Index-Zusätze, der Rest bleibt identisch:

HANDLER employees OPEN;
HANDLER employees READ FIRST;
HANDLER employees READ NEXT;
HANDLER employees READ PREV;
HANDLER employees READ LAST;
HANDLER employees CLOSE;

Pagination
Handler lassen sich wunderbar dafür einsetzen, Ergebnisse aus Datenbanktabellen seitenweise anzuzeigen. Da sie die Ordnung aus dem Index ausnutzen, können Sie in Verbindung mit LIMIT gleich große Mengen Daten z.B. für eine tabellarisch Darstellung liefern:

HANDLER employees OPEN;
HANDLER employees READ unique_idx=(100000) LIMIT 10;
HANDLER employees READ unique_idx NEXT LIMIT 10;
HANDLER employees READ unique_idx LAST LIMIT 10;
HANDLER employees CLOSE;

querySelector: Der native Griff ins DOM

Montag, Februar 6th, 2012

Sizzle ist ein Segen. Die Selector-Engine von jQuery bietet den Zugriff auf eine Menge von DOM-Knoten in einem Einzeiler:

$('h1').css('color', 'red);

Ohne das musste man früher den Umweg über getElementsByTagName() gehen:

for (var i = 0; i < document.getElementsByTagName('h1').length; i++) {
   document.getElementsByTagName('h1')[i].style.color = 'red';
}

Wie umständlich! Doch Rettung naht: querySelector() und querySelectorAll() werden von allen großen Browsern in ihren aktuellen Versionen unterstützt (siehe caniuse.com).

Der Unterschied der beiden Funktionen ist, dass querySelector() nur das jeweils erste Element zurückliefert, querySelectorAll() logischerweise alle betroffenen Elemente. Analog zu Sizzle verstehen diese beiden Funktionen alle vom Browser unterstützten CSS Selektoren, wie auch der Artikel der Blogeintrag vom Mozilla Developer Network zu zeigen versucht:

var el = document.body.querySelector("style[type='text/css'], style:not([type])");

In Anbetracht dessen, dass jQuery mittlerweile mehr als 90 Kilobyte auf die Waage bringt, fragt man sich: muss es denn immer das Framework sein!?

Partition Exchange mit MySQL 5.6

Donnerstag, Februar 2nd, 2012

Das Problem, welches durch Partition Exchange gelöst wird, sollte jedem bekannt sein, der schon einmal eine größere Datenmenge in Null-Komma-Nix in eine viel abgefragte Datenbank schaufeln musste: Zugreifende Anwender sollen von dem Ladevorgang nichts mitbekommen, solange er nicht vollständig abgeschlossen ist - weder soll die Performance der Zugriffe maßgeblich beeinträchtigt werden, noch sollen die bereits geladenen Teile in den Anfrageergebnissen auftauchen.

Das Vorgehen beim Partition Exchange ist denkbar einfach. Die Daten werden nicht gleich in die partitioinierte Zieltabelle geladen, sondern in eine strukturgleiche unabhängige Tabelle. Der Ladevorgang wird daurch von den Abfragen entkoppelt und kann ruhig mehr Zeit in Anspruch nehmen. Ist das Laden vollständig abgeschlossen, legt man eine leere Partition in der Zieltabelle an und gibt dem Server zum Schluss das Kommando, die temporäre Tabelle und die leere Partition zu tauschen.

Zur Verdeutlichung ein Beispiel: Die Tabelle umsaetze beinhaltet Käufe eines großen Einzelhandelsgeschäfts. Jeden Tag kommen im Geschäft 50.000 Transaktionen hinzu, so dass das Datenvolumen - bei unterstellten 20 Arbeitstagen - pro Monat um 1 Mio. Datensätze steigt. Die Tabelle umsaetze dient dem Reporting und wird monatlich im Batch aktualisiert, eine Partitionierung erfolgt auf Basis des Umsatztages per PARTITION BY RANGE (datum).

CREATE TABLE IF NOT EXISTS `umsaetze` (
  `kunde_id` int(11) NOT NULL,
  `datum` date NOT NULL,
  `umsatz` decimal(10,2) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=latin1
/*!50100 PARTITION BY RANGE (MONTH(datum))
(PARTITION jan VALUES LESS THAN (2) ENGINE = InnoDB,
 PARTITION feb VALUES LESS THAN (3) ENGINE = InnoDB) */;

Die Umsätze für März kommen als CSV Datei im Format

kunde_id;datum;umsatz
99141;2012-03-15;54689.4
20218;2012-03-16;38086.58
89814;2012-03-06;94034.74

Da das Format zur Umsatztabelle passt, wird nun noch eine strukturgleiche Tabelle benötigt, die sich denkbar einfach erzeugen und befüllen lässt:

CREATE TABLE maerz_umsaetze LIKE umsaetze;
ALTER TABLE maerz_umsaetze REMOVE PARTITIONING;
LOAD DATA INFILE 'mar.csv' INTO TABLE maerz_umsaetze FIELDS TERMINATED BY ';' LINES TERMINATED BY '\r\n' IGNORE 1 LINES;

Bei diesem Statement ist zu beachten, dass die Datei mar.csv im Daten-Verzeichnis der aktiven Datenbank liegen muss, ansonsten ist ein korrekter Pfad anzugeben. Da die Datei eine Kopfzeile mit Spaltennamen besitzt, wird zudem die erste Zeile ausgelassen.
Um die Daten in umsaetze zu integrieren, wird zuerst eine leere März-Partition angelegt und sofort danach mit der Tabelle maerz_umsaetze ersetzt:

ALTER TABLE umsaetze ADD PARTITION (PARTITION mar VALUES LESS THAN (4));
ALTER TABLE umsaetze EXCHANGE PARTITION mar WITH TABLE maerz_umsaetze;

Obwohl die Tabelle/Partition mehrere Tausend Datensätze umfasst, ist der Prozess beinahe sofort abgeschlossen:

Query OK, 0 rows affected (0.32 sec)

Einen Schritt voraus mit Twitter Bootstrap

Mittwoch, Februar 1st, 2012

Twitter Bootstrap steht schon länger auf der Todo-Liste für unsere kommenden Artikel. Jetzt ist uns der Kurznachrichten-Dienst aber zuvor gekommen und hat Version 2 seines Frameworks rausgebracht - und noch einmal deutlich verbessert und erweitert.

Twitter Bootstrap Responsive Webdesign

Im Grunde ist Bootstrap eine Sammlung von CSS und JavaScript Dateien, die ein ansehnliches, einheitliches Layout mit dazu passenden Funktionalitäten garantiert. Dass eine ganze Menge Inhalt drinsteckt, verrät bereits die Dateigröße: mit 77kb minified CSS und on top 21kb minified JavaScript gehört die Lösung nicht zu den Leichtgewichten. Damit erkauft man sich Ruhe an folgenden CSS-Fronten:

1 - anpassbares Grid - mit 12 Spalten
2 - Templates (und Beispielcode) für fixed und fluid Layouts
3 - Responsive Layouts via Media Queries
4 - Vorgefertigte Typographie, Buttons, Formulare, Tabellen
5 - eingebautes Iconset
6 - Navigation mit Tabs und Breadcrumbs
7 - Thumbnails
8 - Alert-Boxen
9 - Fortschrittsbalken

Hinzu kommt eine Reihe von jQuery Plugins, die das vorige CSS passend in Szene setzen:

1 - Modale Dialoge
2 - Alerts
3 - Tabs, Dropdowns und Collapses für Navigation
4 - Tooltips und Popovers
5 - ScrollSpy
6 - Autocomplete via Typeahead

Twitter bietet für alle Features und Komponenten eine hervorragende Dokumentation auf Github an. Die Features lassen sich dort im Echteinsatz ausprobieren (siehe die eingefügten Screenshots). Wer auch mit Twitter Bootstrap nicht bei Null starten will, kann auf einem der bereitgestellten Beispiele (Marketing Site, Fluid Layout, Starter Template) aufsetzen. Alle benötigten Bestandteile sind darin enthalten.

Twitter Bootstrap Buttons

Wenn sich das alles gut anhört, aber die oben genannten fast 100kb (plus jQuery) abschrecken, so wollen wir noch auf den Customizing Baukasten verweisen. Denn wer genau weiß, dass er nicht alle Features benötigt, kann sich die Bootstrap Dateien passgenau zurechtschneiden, das Grid den Bedürfnissen anpassen und weiter LESS Parameter für Farben und Breiten einstellen. Das schützt einen auch davor, im Nachhinein noch manuell im Code herumfummeln zu müssen.

Twitter Bootstrap Examples

Kategorien

Unser Buch bei Amazon

PHP 5.4 und MySQL 5.5

Social Bookmarks

Archiv