18Jan

Für gezielte Datenbankexporte oder -views möchte man oft eine Zeile für einen Eintrag in der SQL Abfrage erhalten. Beim Verknüpfen von mehreren Tabellen führt dies bei 1:n oder n:m Beziehungen zu dem Nachteil, dass für die Basistabelle mehrere Zeilen entstehen. Zur Verdeutlichung sei folgendes Beispiel (in PostgreSQL) gegeben:

create table account (
ID BIGINT not null,
EMAIL CHARACTER VARYING(1024) not null unique,
primary key (ID)
);


create table history (
ID BIGINT not null,
ACCOUNT_FK BIGINT not null,
ENTRY CHARACTER VARYING(1024) not null unique,
primary key (ID)
);

Ziel soll es sein, ein Abfrage zu erstellen, die alle Accounts und die dazu zugehörigen Historyeinträge zurückliefert. Allerdings soll pro Account nur eine Zeile verwendet werden.

Folgende Abfrage führt nicht zum Ziel:

select account.email, history.entry
from account, history
where account.id = history.account_fk;

Eine Möglichkeit ist es, die Einträge in der History zu verknüpfen, z. B. über ein concat Funktion. Wenn diese als Aggregatfunktion zur Verfügung steht, kann diese in einem group by verwendet werden.

In PostgreSQL ist dies wie folgt möglich:

CREATE AGGREGATE textcat_all(
basetype = text,
sfunc = textcat,
stype = text,
initcond = ''
);

Mit folgender Abfrage kommt man dann zu dem Ziel nur noch eine Zeile pro Account zu erhalten:


select account.email, textcat_all(history.entry || ',')
from account, history
where account.id = history.account_fk;
group by account.email

(Siehe dazu auch hier http://archives.postgresql.org/pgsql-novice/2003-09/msg00177.php)

In mysql ist dies noch einfacher, denn hier existiert bereits eine solche Aggregationsfunktion: http://dev.mysql.com/doc/refman/5.0/en/group-by-functions.html#function_group-concat


10Jan

Standardmäßig generiert die Hibernate Andromda Cartridge die Mappingdateien so, dass eine Sequenz für alle Tabellen genutzt wird. Eine Umstellung auf eine Sequenz für jede Tabelle ist dabei sehr einfach möglich. In der andromda.xml muss die Hibernate Cartridge einfach wie folgt angepaßt werden:

<namespace name="hibernate">
<properties>
...
<property name="defaultHibernateGeneratorClass">sequence</property>
<property name="sequenceIdentifierSuffix">_seq</property>
...
</properties>
</namespace>

Der finale Sequzenzname ergibt sich dabei aus dem Tabellennamen plus den Wert, der der Property sequenceIdentifierSuffix zugeordnet ist.


16Okt

Um schnell Datenbankschemata zu visualisieren bietet sich Schemaspy (veröffentlicht unter LGPL) an. Es wird auf der Kommandozeile zum Beispiel wie folgt aufgerufen:

java -jar schemaSpy.jar -cp postgresql-8.1-408.jdbc3.jar -t pgsql -db beispiel_db -u improve -s public -host beispielport -port 5431 -o .

Damit die Generierung der Tabellen und Diagramme erfolgreich verläuft, müssen 2 Bedingungen erfüllt werden:

  1. ein Treiber für den entsprechenden Datenbanktyp muss vorhanden sein. Der Pfad zum Treiber kann entweder in durch den Parameter -cp spezifiziert werden (siehe oben) oder in den [databaseType].properties von SchemaSpy angegeben werden
  2. zum Rendern der Graphiken muß der Dot-Renderer von Graphviz im selben Ordner wie Schemaspy liegen, ansonsten wird die folgende Fehlermeldung angezeigt:
    Warning: Failed to run dot.
    Download dot version 2.2.1 or versions greater than 2.4 from www.graphviz.org and make sure that dot is in your path.

    Momentan wird von Graphiz nur die Version 2.14.x bereitgestellt, mit der jedoch ebenfalls die Graphiken erzeugt werden können: Einfach die Dateien dot.exe, z.dll, jepg.dll und png.dll aus dem bin-Ordner von Graphviz in das Verzeichnis der schemaspy.jar kopieren.