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:
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.
-
class Program
-
{
-
/// <summary>
-
/// Datenstruktur für die Beziehungen (TabelleA nach TabelleB)
-
/// </summary>
-
public struct Relationship
-
{
-
public String tableA;
-
public String tableB;
-
}
-
static void Main(string[] args)
-
{
-
-
try
-
{
-
SqlConnection dbConnection = new SqlConnection
-
(@"data source=xxxxx;Integrated Security=SSPI;initial catalog=xxxx;persist security info=false;packet size=4096");
-
dbConnection.Open();
-
List<String> tables = GetTableNames(dbConnection);
-
List<Relationship> rels = GetRelationsships(dbConnection);
-
SaveGml(TablesToGml(tables), RelationshipsToGml(rels));
-
Console.WriteLine("Die Datei wurde erfolgreich erzeugt");
-
-
}
-
catch (Exception e)
-
{
-
Console.Write(e.Message);
-
}
-
Console.ReadLine();
-
}
-
-
/// <summary>
-
/// Speichert die endgültige GML-Datei ab.
-
/// </summary>
-
/// <param name="tables"></param>
-
/// <param name="rels"></param>
-
private static void SaveGml(string tables, string rels)
-
{
-
File.WriteAllText("test.gml",
-
@"Creator ""yFiles""
-
Version ""2.6""
-
graph
-
[
-
hierarchic 1
-
label """"
-
directed 1" + tables + rels+"]");
-
}
-
-
/// <summary>
-
/// Wandelt die Liste der Tabelle ins (stark vereinfachte) GML-Format um.
-
/// </summary>
-
/// <param name="tables"></param>
-
/// <returns></returns>
-
public static String TablesToGml(List<String> tables)
-
{
-
String gml = "";
-
foreach (string tab in tables)
-
{
-
gml = String.Concat(gml,Environment.NewLine,
-
"node",Environment.NewLine,
-
"[",Environment.NewLine,
-
"id \""+tab+"\"",Environment.NewLine,
-
"label \""+tab+"\"",Environment.NewLine,
-
"]");
-
}
-
return gml;
-
}
-
-
/// <summary>
-
/// Wandelt die Liste der Beziehungen ins (stark vereinfachte) GML-Format um
-
/// </summary>
-
/// <param name="rels"></param>
-
/// <returns></returns>
-
public static String RelationshipsToGml(List<Relationship> rels)
-
{
-
String gml = "";
-
foreach (Relationship rel in rels)
-
{
-
gml = String.Concat(gml,Environment.NewLine,
-
"edge",Environment.NewLine,
-
"[",Environment.NewLine,
-
" source \""+rel.tableA+"\"",Environment.NewLine,
-
" target \""+rel.tableB+"\"",Environment.NewLine,
-
"]");
-
}
-
return gml;
-
}
-
-
/// <summary>
-
/// Liest die Namen der Tabellen aus der Datenbank
-
/// </summary>
-
/// <param name="dbConnection"></param>
-
/// <returns></returns>
-
public static List<String> GetTableNames(SqlConnection dbConnection)
-
{
-
SqlCommand sqlCommand = dbConnection.CreateCommand();
-
sqlCommand.CommandText =
-
@"Select Name from dbo.sysobjects WHERE xType = 'U' order by Name";
-
SqlDataReader sqlReader = sqlCommand.ExecuteReader();
-
while (sqlReader.Read())
-
{
-
tables.Add(sqlReader["Name"].ToString());
-
}
-
sqlReader.Close();
-
return tables;
-
}
-
-
/// <summary>
-
/// Liest die Relationsships aus der Datenbank aus
-
/// </summary>
-
/// <param name="dbConnection"></param>
-
/// <returns></returns>
-
public static List<Relationship> GetRelationsships(SqlConnection dbConnection)
-
{
-
SqlCommand sqlCommand = dbConnection.CreateCommand();
-
sqlCommand.CommandText =
-
@"SELECT
-
K_Table = FK.TABLE_NAME,
-
FK_Column = CU.COLUMN_NAME,
-
PK_Table = PK.TABLE_NAME,
-
PK_Column = PT.COLUMN_NAME,
-
Constraint_Name = C.CONSTRAINT_NAME
-
FROM INFORMATION_SCHEMA.REFERENTIAL_CONSTRAINTS C
-
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS FK ON C.CONSTRAINT_NAME = FK.CONSTRAINT_NAME
-
INNER JOIN INFORMATION_SCHEMA.TABLE_CONSTRAINTS PK ON C.UNIQUE_CONSTRAINT_NAME = PK.CONSTRAINT_NAME
-
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE CU ON C.CONSTRAINT_NAME = CU.CONSTRAINT_NAME
-
INNER JOIN (
-
SELECT i1.TABLE_NAME, i2.COLUMN_NAME
-
FROM INFORMATION_SCHEMA.TABLE_CONSTRAINTS i1
-
INNER JOIN INFORMATION_SCHEMA.KEY_COLUMN_USAGE i2 ON i1.CONSTRAINT_NAME = i2.CONSTRAINT_NAME
-
WHERE i1.CONSTRAINT_TYPE = 'PRIMARY KEY'
-
) PT ON PT.TABLE_NAME = PK.TABLE_NAME";
-
SqlDataReader sqlReader = sqlCommand.ExecuteReader();
-
while (sqlReader.Read())
-
{
-
singleRel.tableA = sqlReader["K_Table"].ToString();
-
singleRel.tableB = sqlReader["PK_Table"].ToString();
-
-
//Gibt's mehrere gleiche Beziehungen wird nur EINE dargestellt.
-
if (!rel.Contains(singleRel))
-
{
-
rel.Add(singleRel);
-
}
-
-
}
-
sqlReader.Close();
-
return rel;
-
-
}
-
}
Die damit erzeugte Datei „test.gml“ kann man nun mit YED öffnen – und sieht dann so aus:

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

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:
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




Kann man friedliche Olympische Spiele in einem Land veranstalten, das zur selben Zeit die Menschenrechte mit Füßen tritt?
Wer nutzt sie nicht, die kleinen gelben Zettelchen?
Tja, jetzt habe ich einen MP3-Player. Den i.Beat organix von Trekstore mit 1 GB.