Automatisches Erzeugen eines Datenbankdiagrams aus einer MSSQL-Datenbank mit Hilfe von YED

Mit dem Microsoft SQL Server Management Studio (Express) kann man seiner Datenbank unter dem Punkt „Database Diagrams“ eine grafische Darstellung der Datenbank hinzufügen.

Soweit so gut – nur sieht das dann meistens so aus:

ERMSQL

Also nicht gerade übersichtlich. Und das Ganze per Hand in eine schöne Form zu bringen ist sehr mühselig.

Aber es gibt ein schönes Freewareprogramm: YED. Damit kann man sehr schön Diagramme machen. Und vor allem: es kann die Elemente automatisch anordnen, so dass sie (einigermaßen) übersichtlich dargestellt werden. Aber leider kann es keine Datenbankstruktur auslesen…

Aber wozu ist man Programmierer….

Nachfolgendes C#.net Konsolen-Programm liest aus einer Datenbank die Tabellen aus, holt sich die Beziehungen (Relationships) der Tabellen untereinander und speichert es in Form einer *.gml Datei ab.

  1. class Program
  2.     {
  3.         /// <summary>
  4.         /// Datenstruktur für die Beziehungen (TabelleA nach TabelleB)
  5.         /// </summary>
  6.         public struct Relationship
  7.         {
  8.             public String tableA;
  9.             public String tableB;
  10.         }
  11.         static void Main(string[] args)
  12.         {
  13.  
  14.             try
  15.             {
  16.                 SqlConnection dbConnection = new SqlConnection
  17.                  (@"data source=xxxxx;Integrated Security=SSPI;initial catalog=xxxx;persist security info=false;packet size=4096");
  18.                 dbConnection.Open();
  19.                 List<String> tables = GetTableNames(dbConnection);
  20.                 List<Relationship> rels = GetRelationsships(dbConnection);
  21.                 SaveGml(TablesToGml(tables), RelationshipsToGml(rels));
  22.                 Console.WriteLine("Die Datei wurde erfolgreich erzeugt");
  23.                
  24.             }
  25.             catch (Exception e)
  26.             {
  27.                 Console.Write(e.Message);
  28.             }
  29.             Console.ReadLine();
  30.         }
  31.  
  32.         /// <summary>
  33.         /// Speichert die endgültige GML-Datei ab.
  34.         /// </summary>
  35.         /// <param name="tables"></param>
  36.         /// <param name="rels"></param>
  37.         private static void SaveGml(string tables, string rels)
  38.         {
  39.             File.WriteAllText("test.gml",
  40.                 @"Creator   ""yFiles""
  41. Version ""2.6""
  42. graph
  43. [
  44.     hierarchic  1
  45.     label   """"
  46.     directed    1" + tables + rels+"]");
  47.         }
  48.  
  49.         /// <summary>
  50.         /// Wandelt die Liste der Tabelle ins (stark vereinfachte) GML-Format um.
  51.         /// </summary>
  52.         /// <param name="tables"></param>
  53.         /// <returns></returns>
  54.         public static String TablesToGml(List<String> tables)
  55.         {
  56.             String gml = "";
  57.             foreach (string tab in tables)
  58.             {
  59.                gml = String.Concat(gml,Environment.NewLine,
  60.                     "node",Environment.NewLine,
  61.                     "[",Environment.NewLine,
  62.                     "id \""+tab+"\"",Environment.NewLine,
  63.                     "label  \""+tab+"\"",Environment.NewLine,
  64.                     "]");
  65.             }
  66.             return gml;
  67.         }
  68.  
  69.         /// <summary>
  70.         /// Wandelt die Liste der Beziehungen ins (stark vereinfachte) GML-Format um
  71.         /// </summary>
  72.         /// <param name="rels"></param>
  73.         /// <returns></returns>
  74.         public static String RelationshipsToGml(List<Relationship> rels)
  75.         {
  76.             String gml = "";
  77.             foreach (Relationship rel in rels)
  78.             {
  79.                 gml = String.Concat(gml,Environment.NewLine,
  80.                     "edge",Environment.NewLine,
  81.                     "[",Environment.NewLine,
  82.                     "   source \""+rel.tableA+"\"",Environment.NewLine,
  83.                     "   target \""+rel.tableB+"\"",Environment.NewLine,
  84.                     "]");
  85.             }
  86.             return gml;
  87.         }
  88.        
  89.         /// <summary>
  90.         /// Liest die Namen der Tabellen aus der Datenbank
  91.         /// </summary>
  92.         /// <param name="dbConnection"></param>
  93.         /// <returns></returns>
  94.         public static List<String> GetTableNames(SqlConnection dbConnection)
  95.         {
  96.             List<string> tables = new List<string>();
  97.             SqlCommand sqlCommand = dbConnection.CreateCommand();
  98.             sqlCommand.CommandText =
  99.                 @"Select Name from dbo.sysobjects WHERE xType = 'U' order by Name";
  100.             SqlDataReader sqlReader = sqlCommand.ExecuteReader();
  101.             while (sqlReader.Read())
  102.             {
  103.                 tables.Add(sqlReader["Name"].ToString());
  104.             }
  105.             sqlReader.Close();
  106.             return tables;
  107.         }
  108.  
  109.         /// <summary>
  110.         /// Liest die Relationsships aus der Datenbank aus
  111.         /// </summary>
  112.         /// <param name="dbConnection"></param>
  113.         /// <returns></returns>
  114.         public static List<Relationship> GetRelationsships(SqlConnection dbConnection)
  115.         {
  116.             List<Relationship> rel = new List<Relationship>();
  117.             SqlCommand sqlCommand = dbConnection.CreateCommand();
  118.             sqlCommand.CommandText =
  119.                 @"SELECT
  120. K_Table = FK.TABLE_NAME,
  121. FK_Column = CU.COLUMN_NAME,
  122. PK_Table = PK.TABLE_NAME,
  123. PK_Column = PT.COLUMN_NAME,
  124. Constraint_Name = C.CONSTRAINT_NAME
  125. FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
  126. INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
  127. INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
  128. INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
  129. INNER JOIN (
  130. SELECT i1.TABLE_NAME, i2.COLUMN_NAME
  131. FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
  132. INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
  133. WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
  134. ) PT ON PT.TABLE_NAME = PK.TABLE_NAME";
  135.             SqlDataReader sqlReader = sqlCommand.ExecuteReader();
  136.             while (sqlReader.Read())
  137.             {
  138.                 Relationship singleRel = new Relationship();
  139.                 singleRel.tableA = sqlReader["K_Table"].ToString();
  140.                 singleRel.tableB = sqlReader["PK_Table"].ToString();
  141.  
  142.                 //Gibt's mehrere gleiche Beziehungen wird nur EINE dargestellt.
  143.                 if (!rel.Contains(singleRel))
  144.                 {
  145.                     rel.Add(singleRel);
  146.                 }
  147.  
  148.             }
  149.             sqlReader.Close();
  150.             return rel;
  151.  
  152.         }
  153.     }

Die damit erzeugte Datei „test.gml“ kann man nun mit YED öffnen – und sieht dann so aus:

ERMYED_First

Alle „Kästchen“ sind hier hintereinander angeordnet, da ich mit obigem Programm nur ein vereinfachtes GML-Format angelegt habe. Das macht aber nichts, denn YED kann nun daraus ein übersichtliches Diagramm machen!

Man wählt dazu lediglich aus:

Layout – Orthogonal – Kompakt
YedMenue

Und siehe da: nun habe ich ein schönes Datenmodell, das ich nur noch ein bischen aufhübschen muß! Die Breite der Kästchen ändert man am besten gleich zuerst: alles markieren und per Maus breiter ziehen. Hintergrundfarbe festlegen, etwas rumspielen und fertig:

ERMYED

Einzige Voraussetzung ist, dass die Beziehungen zwischen den Tabellen auch in der Datenbank als Relationships angelegt sind.

Danke an
Bernhard für den Tipp mit YED
Pinal Dave für die Select-Anweisung

Deutschland : China

Was unterscheidet Deutschland von China?

Ganz einfach:
In Deutschland fahren immer weniger Menschen mit dem Auto und dafür mehr mit dem Fahrrad.
In China fahren immer mehr mit dem Auto und immer weniger mit dem Fahrrad…

Tibet-Freunde leben gefährlich…

China ist allgegenwärtig – und dank des Internets mitten in unseren Wohnzimmern. Wie in einem schweizer BLOG zu lesen, startet China Hacker-Angriffe auf Webseiten und Rechner von Tibet-Sympathisanten.
Mehr dazu im RainbowNet Blog Schweiz

Dazu kann ich nur eines sagen:

Visual Studio 2008 – Installationsprobleme

Endlich ist es soweit! Die Visual Studio 2008 DVD ist angekommen.
Voller Vorfreude lege ich mit der Installation los, schließlich erwarten mich viele neue Features, die ich schon längst haben möchte. Doch die Freude währt kurz – der Installer bleibt beim Schritt „Microsoft Visual Studio 2008″ mit dem Prozeß „hxMeger_vsipcc_x86_de….“ hängen. Auch nach 30 Minuten tut sich nichts, im Taskmanager zeigt nur noch der Leerlaufprozess Aktivität… Was tun?

Im Internet findet man ähnliche Fehlerberichte – aber keine Lösung.

Visual Studio 2008

Also durchforste ich den Taskmanager und kille den einen oder anderen Prozess – ohne Wirkung. Der Installationsprozess „devenv.exe“, der eigentlich VS installieren sollte schläft. Kurzer Hand wird der Prozess gekillt – und siehe da: die Installation läuft weiter!

Doch nur, um dann beim Schritt „Crystal Reports Basic für Visual Studio 2008″ wieder hängen zu bleiben.

Wieder wird devenv.exe abgeschossen – er hat schon über 100 MB Speicher belegt.
Und wieder läuft die Installation weiter.

Doch devenv.exe gibt nicht auf – der Prozess erscheint sofort wieder neu. Und hängt beim „Crystal Reports Basic Language Pack“. Wieder abgeschossen.

Wieder läuft die Installation weiter – fast bis zum Schluß. Bei „MS SQL-Veröffentlichungsassisten“ tut sich wieder nichts. Nachdem der Fortschrittsbalken geraume Zeit bei 100% ist wird devenv.exe wieder mal abgeschossen.

Die Installation wurde – trotz der Abschüsse – als erfolgreich gemeldet.
Ob durch die wilde Schießerei später Probleme auftreten werden, wird sich zeigen. Zumindest läuft VS 2008 und auch meine Projekte lassen sich öffnen und laufen. Was will man mehr? (Außer vielleicht eine problemlose Installation…)

Nachbarschaftspost.com – Spam im Quadrat

Bisher war’s ja fast noch einfach. Da wurde eMail gespammt und Telefonwerbung betrieben.
Seit heute ist das bei mir wohl anders: jetzt geht’s Hand in Hand, SPAM im Quadrat sozusagen.

Erhielt ich doch einen Anruf, in dem mir eine Computerstimme mitteilte, ich hätte ein „WICHTIGE“ Nachricht von meinem Nachbarn erhalten und soll auf nachbarschaftspost.com einen Code eingeben um sie anzuhören. Weder wurde der Name des Nachbarn genannt, der angeblich eine Botschaft für mich hat, noch wurde auf Kosten hingewiesen.

Ich wüsste zwar nicht, welcher Nachbar mir eine Nachricht auf diese Weise hinterlassen sollte, war aber trotzdem neugierig. Liest man dann das Kleingedruckte auf nachbarschaftspost.com, welches übrigens in Augenkrebs erregenden Farben dargestellt wird, merkt man, daß man hier gleich einen Vertrag abschließt.

Und zwar gleich für 2 Jahre und mit 9 Euro pro Monat.

Eine teure Nachbarschaftspost – und außerdem ist es doch viel einfacher, mal zum Nachbarn rüber zu gehen und zu klingeln. Und einen Briefkasten gibts ja schließlich auch noch….

Stell Dir vor es sind Olympische Spiele – und keiner geht hin.

Free TibetKann man friedliche Olympische Spiele in einem Land veranstalten, das zur selben Zeit die Menschenrechte mit Füßen tritt?

Es liegt (auch) in der Hand der Sportler…

Aufruf zum Boykott

Aufruf: Schreiben Sie Bundeskanzlerin Merkel

Boycott the Opening of the Olympic Games! – eMail-Aktion

Appell der tibetischen Athleten an die Sportler der Welt

Keine abstehenden Post-it mehr!

Post-It ZettelWer nutzt sie nicht, die kleinen gelben Zettelchen?
Und hat es Euch auch schon geärgert, daß sie unten, am nicht klebenden Ende, immer abstehen? Nun – im Internet gibts wie so oft die Lösung! Dave Gray zeigt auf einem Video, wie man’s richtig macht damit’s auch mit den Post-It Zettelchen klappt….
Hier gehts zum Video

Stasi-Methoden unter Freunden…

Geht’s Euch nicht auch oft so: da findet man was Tolles im Internet und will seine Kollegen und Freunde an dieser sensationellen Entdeckung teilhaben lassen. Flugs schickt man eine Mail mit dem Link auf diese Seite …. und hört nie wieder was darüber. Kein Danke, kein „tolle Info!“, kein gar nix.

Hat der Empfänger die Mail nicht bekommen? Hat er/sie den Link nicht angeklickt?
Man weiß es nicht, man weiß es nicht. Und man kann nichts tun außer nachzufragen.

Oder doch?
LinkBlip schafft hier Abhilfe! Ähnlich wie tinyurl.com macht dieses online-Tool aus einem langen Link einen Kurzen. Und zusätzlich kann man sich eine Benachrichtungsmail schicken lassen, die darüber informiert, wann der Link von wem angeklickt worden ist!

Und das Schönste: das Ganze läßt sich als Bookmarklet in den Browser integrieren – ganz ohne Installation! (Anleitung siehe bei LinkBlip unter „Install the Browser Button“)

Eigentlich ein wunderschönes „Stasi-Tool“, findet ihr nicht?
Linkblip

Ab heute höre ich PodCast’s!

„Wer nicht mit der Zeit geht, der geht mit der Zeit“ heisst ein alter Spruch. Bisher habe ich um das Thema MP3-Player und PodCast’s einen Bogen gemacht. „Wer braucht denn schon sowas….“ und „Dafür habe ich keine Zeit“ sind die Gedanken, mit denen ich meine altmodische Denkweise zu verteigen suchte. Trotzdem, es hat mich nicht losgelassen.

i.beat OrganixTja, jetzt habe ich einen MP3-Player. Den i.Beat organix von Trekstore mit 1 GB.
Und was soll ich sagen: erstaunlich! Es ist ganz was anderes als Radio hören. Viel selektiver, gezielter!

Vielleicht schaffe ich es sogar mein Hörbuch, das seit langem als CD ungehört rumliegt, mal anzuhören. „Das Buch der Menschlichkeit“ vom Dalai Lama. In MP3 umgewandelt liegt es schon auf dem handlichen Player. Und Rundfunkt-Podcasts habe ich auch schon entdeckt.

Man sitzt ja den ganzen Tag vom dem PC, liest, liest und liest. Ist das Hören vielleicht ein alternativer Informationsaufnahmeweg? Augenschonend?
Interessant!!!

Advent, Advent – ein Büchlein brennt

Die Adventszeit bringt auch Entwickler auf gute Ideen: Auf der Homepage von entwickler-press.de gibt es einen Adventskalender. Nichts besonderes zu dieser Jahreszeit. Aber das Schöne an diesem Adventskalender: hinter jedem Türchen gibt es ein eBook zum download. Heute (und nur heute) z.B. ein Java-Buch.
Mal schauen, was es morgen gibt….

Nächste Seite »


 

November 2009
M D M D F S S
« Jul    
 1
2345678
9101112131415
16171819202122
23242526272829
30  

Kategorien