SSD billiger als magnetische Festplatten?

In der vergangenen Woche war ein interessanter Vortrag bei der Elastic Search User Group in Zürich, vom Gründer der Firma und des Projekts

Eine Bemerkung war, dass es in typischen Elastic-Search-Anwendungen billiger sein kann, SSDs als magnetische Festplatten einzubauen. Magnetische Festplatten sind natürlich für das gespeicherte Byte viel billiger, aber wenn man Durchsatz in Bytes/sec braucht, seien SSDs billiger.

Ein interessanter Gedanke, erst einmal verwirrend.

Aber man baut letztlich eine Serverfarm auf, um die nötige Leistung zu erbringen. Wenn nun die Hauptaufgabe dieser Server in geschickten Lesezugriffen auf ihren Daten besteht, dann braucht man mit vollständiger Verwendung von SSDs weniger Server. Das könnte kostengünstiger sein. Und gerade für überwiegendes Lesen sind SSDs unumstritten gut.

Share Button

Frankfurter DB-Tage

Ein bisschen Weiterbildung muss wohl immer wieder mal sein und so schaue ich mir jetzt ein oder zweimal im Jahr eine Konferenz von innen an.

Da es ja hier um Speicherung, Verarbeitung und Übermittlung von Informationen geht, habe ich mich etwas eingehender über die Themen im Zusammenhnag mit der Speicherung interessiert und die Frankfurter Datenbanktage besucht. Wie üblich gab es jeweils noch ein paar Stände, an denen man sich im Rest der 15-min-Pausen noch unterhalten konnte.

Interessante Themen waren „BigData“ und dessen Abgrenzung, die Frage, für welche Zwecke man klassische transaktionale relationale SQL-Datenbanken einsetzt und für welche Zwecke man sich für die vielfältige Welt der „NoSQL“-Datenbanken interessiert und vielleicht für die Lösung fündig wird und wie die Anbieter der klassischen Datenbanken versuchen, auch diesen Bereich abzudecken. Bekommt DB2 eine MongoDB-kompatible Schnittstelle, so dass man für Mongo-DB entwickelte Software mit DB2 statt MongoDB betreiben kann? Oder wie integriert man die verschiedenen Welten miteinander, wenn eine Aufgabenteilung sinnvoll ist?

Datenbank-Security ist ein interessantes Thema gewesen, sowohl in Vorträgen als auch bei Ausstellern. Welche Wege bestehen für Angreifer, die Daten zu lesen oder gar zu verändern und wie kann man das unterbinden oder doch zumindest so weit erschweren, dass das Risiko sehr klein wird?

Wie sieht es mit Clustering aus? Wie kann man die Performance optimieren, wo sind die Grenzen? Das können alle „großen“ Datenbanken, auch mySQL und mariaDB. Aber es gibt verschiedene Wege. Was sind die neuen Features der Datenbanken? Oracle hat zum Beispiel so etwas wie Virtualisierung vorgesehen, was es endlich ermöglichen soll, mit vertretbarem Ressourcen-Aufwand mehrere Datenbankinstanzen zu haben, indem diese als eine Art virtuelle Instanzen in einer Masterinstanz laufen.

Wie nutzt man heutige Hardware optimal oder wie investiert man in Hardware am sinnvollsten, um performante DB-Infrastruktur zu erhalten?

Es war also recht interessant…

Share Button

neo4j

Da ich in dieser Woche einen Vortrag darüber gehört habe, schreibe ich mal einen kurzen Beitrag dazu.

Sicher haben viele schon von „NoSQL“-Datenbanken gehört.

In den guten alten Zeiten kam so etwa alle 10 Jahre ein neues Datenbank-Paradigma auf, bis die relationalen Datenbanken kamen. So etwa Mitte der 90er Jahre wäre nach diesem 10-Jahres-Rhytmus wieder etwas neues fällig gewesen und die objektorientierten Datenbanken waren ein recht offensichtlicher Kandidat. Letztlich blieben sie aber Nischenprodukte, ebenso wie einige andere Ideen, wie XML-Datenbanken.

Die relationalen Datenbanken und vor allem SQL waren zu gut oder zu gut etabliert und zu gut verstanden und statt objektorientierte Datenbanken einzusetzen verliebte man sich in verschiedene Technologien, um objektorientierte Software mit relationalen Datenbanken zu verbinden, zum Beispiel OR-Mapping wie Hibernate, JDO oder Eclipselink in der Java-Welt oder ActiveRecord in der Ruby-Welt. Diese Technologien, ihre Vor- und Nachteile und auch die grundsätzlichen konzeptionellen Fragen dazu sind sicher noch Stoff für viele Blog-Artikel in der Zukunft…

Letztlich scheint jetzt das Thema „NoSQL“-Datenbanken neben den weiterhin starken relationalen Datenbanken seinen Platz einzunehmen. Dabei steht „NoSQL“ angeblich für „not only SQL“. Letztlich sind es aber zwei Aspekte, an denen man schraubt. Die gängigen SQL-Datenbanken sind relational (oder zumindest unterstützen sie das relationale Modell) und transaktional. Das Thema Transaktionen ist sicher auch interessant genug für viele Blog-Beiträge und man kann problemlos allein darüber ein Buch von mehreren 100 Seiten schreiben, das nicht langweilig wird, wenn man sich mit verteilten Transaktionen und der Implementierung dieser Konzepte und der theoretischen und praktischen Zuverlässigkeit solcher Implementierungen gemessen an den Ansprüchen beschäftigt. Es gibt gegen Einwurf vieler großer Münzen mehrere gute Monographien dazu im Buchhandel.

Eine wichtige Motivation für die Entwicklung und Verbreitung der noSQL-Datenbanken war „Big Data“, also die Verarbeitung riesiger Datenmengen, die den Rahmen traditioneller relationaler transaktionaler Datenbanken wie Oracle, DB2, PostgreQL u.s.w. sprengen. Solche Fragestellungen findet man unter anderem bei Webapplikationen wie sie Google oder Facebook betreiben. Es gibt aber auch Fragestellungen mit Datenmengen, die noch gut für relationale Datenbanken handhabbar sind, die sich aber von ihrer Struktur nicht so gut für das relationale Modell eignen.

Nun muß eine SQL-Datenbank nicht transaktional sein. Zum Beispiel war es mySQL lange Zeit nicht und heute ist die für Data-Warhouses spezialisierte Datenbank Teradata unterstützt Transaktionen nur eingeschränkt.

NoSQL-Datenbanken weichen aber das relationale Prinzip auf und je nach Einzelfall eventuell außerdem die Transaktionalität. Es gibt verschiedene Arten von NoSQL-Datenbanken, zum Beispiel Key-Value-Stores wie Riak oder dokumentenorientierte Datenbanken wie MongoDB oder CouchDB, die sich eignen, wenn man eine gewisse Struktur der Daten kennt, aber die einzelnen Datensätze doch von Zeile zu Zeile (oder hier von Dokument zu Dokument) zu stark varieren oder zu stark strukturiert sind, um gut in eine normalisierte relationale Datenbank zu passen.

Graphendatenbanken speichern Daten in der Struktur eines Graphen. Man hat also Knoten mit gewissen Eigenschaften (Daten) und Verbindungen zwischen diesen Knoten mit gewissen Eigenschaften. Ein Beispiel ist eine IT-Landschaft, in der man Hardware, virtuelle Server, Basis-Software, Applikationen, Businessprozesse u.s.w. hat, zwischen denen verschiedene Arten von Abhängigkeiten bestehen können. Das war das Beispiel, das in dem Vortrag gebracht wurde. Das läßt sich eigentlich gut im relationalen Modell abbilden, ist aber in der Praxis sehr schwerfällig zu gebrauchen, weil die Queries um einen Teilgraphen zu laden, sehr schwerfällig sind und weil man letztlich durch fortgesetztes Verfolgen von Abhängigkeiten sehr schnell einen großen Teil des Systems im Speicher hat. Mit einer Graphendatenbank kann man diese Struktur allerdings ganz natürlich und direkt modellieren. neo4j ist zum Beispiel eine solche Graphendatenbank, die als Opensource-Software verfügbar ist. Sie enthält auch praktischerweise gleich noch Implementierungen einiger gängiger Graphenalgorithmen, die man direkt auf dem gespeicherten Graphen operieren lassen kann. So lassen sich gewisse Aufgabenstellungen sehr elegant lösen, die mit einer relationalen Datenbank zwar theoretisch korrekt, aber nicht praxistauglich umsetzbar sind, sobald der zu speichernde Graph eine gewisse Größe und Komplexität erreicht. Zur Aufweichung des Transaktionsprinzip ist noch zu sagen, daß neo4j transaktional ist.

Share Button

Boolean in Datenbanken

Gemäß SQL-Standard SQL:1999 ist ein Boolean-Typ in Datenbanken vorgesehen, aber dieses Feature ist optional und auch im Jahr 2012 von vielen vorhandenen Datenbanken nicht implementiert. PostgreSQL ist wohl eine Ausnahme.

Nun ist dieser Boolean-Typ sehr trivial nachzubilden. Ich habe zum Beispiel die folgenden Varianten gesehen:

  • VARCHAR(1) oder VARCHAR2(1) oder CHAR(1) mit ‚0‘ und ‚1‘
  • VARCHAR(1) oder VARCHAR2(1) oder CHAR(1) mit ‚N‘ und ‚Y‘
  • VARCHAR(1) oder VARCHAR2(1) oder CHAR(1) mit ‚T‘ und ‚F‘
  • INTEGER oder NUMBER(1,0) mit 0 und 1

Oder so absurde Varianten wie:

  • VARCHAR(5) oder VARCHAR2(5) mit ‚true‘ und ‚false‘

Gerade die Tatsache, daß hier nicht eine Lösung sich durchgesetzt hat, ist schon ein Nachteil, denn in größeren Applikationen hat man dann oft noch verschiedene Varianten gleichzeitig. In SQL muß man immer noch die Extra-Runde drehen und den Boolean-Wert konvertieren, vor allem in den WHERE-Bedingungen.

Letztlich kann man mit dieser Einschränkung leben, solange man sich auf eine Variante einigt. Vielleicht kann mir auch jemand sagen, welches die „richtige“ Lösung ist, auf die sich die meisten DBAs geeinigt haben.

Share Button

Fehler in Oracle-Datenbanken mit leeren Zeichenketten

English

Es scheint so, dass alle gängigen Oracle-Datenbanken leere Zeichenketten und null nicht unterscheiden. Das widerspricht der SQL-Spezifikation und ist damit ein Fehler.

Leider wäre es für Oracle nicht einmal einfach, den zu entfernen, weil zu viele Applikationen seit Jahrzehnten Oracle benutzen und sich auf dieses Verhalten eingestellt haben.

Entscheidend ist also erst einmal, diesen Fehler zu kennen und bei der Verwendung von Oracle-Datenbanken zu berücksichtigen. Solange man explizit mit SQL, also SQL*Plus, JDBC, DBI, Pro*C u.ä. auf die Datenbank zugreift, ist es noch einfacher, das zu berücksichtigen, aber heikel wird es bei der Verwendung von Frameworks wie Hibernate, wo man merkwürdige Fehler findet. Wenn man zum Beispiel eine Entität (engl. Entity) hat, die persistiert wird, und dort ein Attribut eine Zeichenkette ist, kann man legitimerweise dort die leere Zeichenkette zuweisen. Sobald dieses Objekt durch Hibernate wandert und persistiert wird, hat man plötzlich stattdessen null dort stehen und bekommt unerwartete NullPointerExceptions. Oder das Attribut ist in der Datenbank mit dem NOT-NULL-Constraint versehen und man bekommt beim Schreiben Oracle-Fehler. Außerdem ist es natürlich ein semantisches Problem, man möchte vielleicht gerne leere Zeichenketten und null dort speichern können und mit verschiedenen Bedeutungen behandeln.

Eine hässliche, aber doch praktikable Möglichkeit, damit umzugehen ist die Getter und Setter der Zeichenketten-Attribute entsprechend zu ändern. Man kann eine „magische Zeichenkette“ definieren, die man garantiert nicht als Wert dort speichern möchte. Dann kann man im Getter vergleichen, ob das Attribut diese Zeichenkette als Wert hat und in dem Fall die leere Zeichenkette zurückgeben. Und im Setter prüft man erst, ob der neue Wert diese magische Zeichenkette ist, was man mit einer Exception ablehnt, und andernfalls, ob der neue Wert die leere Zeichenkette ist, was man durch die magische Zeichenkette ersetzt.

Bespiel in Java (ohne JPA-Annotationen, Synchronisation, toString(), hashCode(), equals() u.s.w.; geht analog für andere Programmiersprachen)


public class MyEntity {
  private static String MAGIC_VALUE = "_._._«NULL»_._._";
  private String value;

  public String getValue() {
    if (MAGIC_VALUE.equals(value)) {
      return "";
    } else {
      return value;
    }
  }

  public void setValue(String newValue) {
    if (MAGIC_VALUE.equals(newValue)) {
      throw new IllegalArgumentException("value="+newValue+" not allowed");
    } else if ("".equals(newValue)) {
      this.value = MAGIC_VALUE;
    } else {
      this.value = newValue;
    }
  }
}

Damit das ganze auch mit Attributen funktioniert, die in der Datenbank als VARCHAR(1) oder VARCHAR(2) definiert sind, ist es vielleicht eine gute Idee, Steuerzeichen oder UTF-8-Zeichen aus einer Sprache, die man nie unterstützen will, zu verwenden. Aber es bleibt eine unbefriedigende Lösung.

Hat jemand eine bessere Idee dazu?

Gibt es noch andere Datenbanken, die den gleichen Fehler wie Oracle in diesem Punkt haben?

Share Button

Latenz von DB-Verbindungen

English

Applikationen, die eine Datenbank verwenden, sind oft zu langsam, obwohl man doch einen großen Server für die Applikation und einen zweiten großen Server für die Datenbank bereitgestellt hat. Und schaut man sich diese beiden an, sind sie womöglich noch nicht einmal so stark ausgelastet.

Das Problem ist, dass die Verbindung zwischen den beiden Servern zwar sehr schnell ist, was man vor allem daran sieht, wenn man große Datenmengen auf einmal überträgt.

Typische Datenbank-Applikationen benötigen aber viele einzelne Zugriffe auf die Datenbank. Bei jedem dieser Zugriffe muss ein Kommunikationsprotokoll angewendet werden, also mehrere Male eine Antwort über die Verbindung abgewartet werden. Deshalb führen viele kleine Datenbankzugriffe zu einer Verlangsamung der Applikation, weil dauernd auf die Netzwerkkommunikation gewartet werden muss.

Was kann man tun?
Sinnvoll ist sicher, die Applikation so zu optimieren, dass durch geschickte Queries mehr Daten auf einmal übertragen werden. Das ist oft nicht einfach, wenn man Frameworks wie zum Beispiel Hibernate oder Eclipselink verwendet.
Eine andere Optimierung ist es, Datenbank und Applikation auf demselben Server laufen zu lassen. Diese Optimierung ist auch nicht einfach, weil das die Systemadministratoren in der Regel überhaupt nicht mögen, aber es ist eine Möglichkeit, die man doch in Betracht ziehen sollte, wenn sich anders keine hinreichend gute Performance erzielen lässt.

Share Button