SQL-Montag: Was sind Datenbank-Indizes und welche Arten gibt es?

Tuesday, April 05, 2011 12:11:09 AM (Mitteleuropäische Sommerzeit, UTC+02:00)

Wie schon letzte Woche, stellt Thomas Mentzel wieder einige Fragen in seinem Blog, die es zu beantworten gilt.
Am heutigen SQL-Montag steht die Frage im Raum, was Datenbank-Indizes sind und welche Arten es gibt.
Da ich mir beim letzten Mal schon die SQL Frage geschnappt habe, werde ich heute wieder versuchen diese Frage zu beantworten.

Hinweis: Indizes können nicht komplett in einem kleinen Blogeintrag abgehandelt werden, deshalb ist es ratsam, das Thema in der MSDN zu vertiefen. Hier ist ein guter Einstiegspunkt.

Was sind Indizes?

Ein Index (Singular von Indizes) wird in einer Datenbank genutzt, um Abfragen und Sortiervorgänge zu beschleunigen. Mit Hilfe von Indizes kann die Menge an Daten reduziert werden, die von der Festplatte gelesen werden müssen, um das Abfrageergebnis zu ermitteln. Weiterhin können Indizes die Eindeutigkeit von Daten in einer Tabelle erzwingen.

database-indizes

Es wird im Wesentlichen zwischen Nonclustered Index und Clustered Index unterschieden.

Clustered Index (gruppierter Index)

Ein Clustered Index speichert die Zeilen der zugrunde liegenden Tabelle in sortierter Reihenfolge des Clustered Index Schlüssels. Dieser Schlüssel ist die Spalte die zur Indizierung ausgewählt wurde, wobei auch mehrere Spalten ausgewählt werden können. Pro Tabelle kann nur ein gruppierter Index gesetzt werden, da die Datenzeilen nur in einer Reihenfolge sortiert werden können.
Ein Beispiel: Wir haben eine Tabelle Kunde mit den Spalten ID und Kundenname. Es wurde ein Clustered Index auf die Spalte ID gesetzt.
Fragen wir den Kunden mit der ID 77 ab, geht dies extrem schnell. Suchen wir jedoch nach einem Kunden mit dem Namen ‚Meyer‘ dauert dies viel länger, da der SQL Server jeden Eintrag im Clustered Index durchgehen muss.
Wird in einer Tabelle eine Identity Spalte definiert, wird automatisch ein Clustered Index für diese Spalte erstellt!

Nonclustered Index (nicht gruppierter Index)

Ein Nonclustered Index enthält den Wert des indizierten Schlüssels und den Zeiger auf den Speicherort der restlichen Daten. Der Nonclustered Index ist mit dem Inhaltsverzeichnis eines Buches vergleichbar. Im Inhaltsverzeichnis steht der Wert (z.B. das Schlagwort) nach dem gesucht wird und die Seitennummer (der Zeiger) auf der die restlichen Informationen zu finden sind.
Nonclustered Indizes sind aus diesem Grund sehr gut für Abfragen geeignet, die nach genauen Übereinstimmungen suchen. Wenn in unserer Kundentabelle also ständig nach Kundennamen gesucht wird, wird ein Nonclustered Index auf die Spalte Kundenname von Vorteil sein.
Nonclustered Indizes können auf Tabellen mit Clustered Index angewendet werden, sowie auch auf Heap-Tabellen. Eine Heap-Tabelle ist eine Tabelle die nicht über einen Clustered Index verfügt. Pro Tabelle können mehrere (bis zu 999) Nonclustered Index erstellt werden.

Unique

Sowohl Clustered Indizes als auch Nonclustered Indizes können Unique (eindeutig) sein.
Ein Beispiel hierzu: Wir haben wieder unsere Kundentabelle mit der Spalte ID und der Spalte Kundenname. Auf diese Tabelle wird ein Nonclustered Index gesetzt der für die Spalte Name eindeutig sein soll.
Wenn versucht wird, zwei gleiche Namen einzufügen, gibt es folgende Fehlermeldung:

Cannot insert duplicate key row in object 'dbo.Kunden with unique index 'Index1'

Mit dieser Möglichkeit kann die Datenintegrität der Tabellendaten sichergestellt werden.

Weitere Indizes

Des Weiteren gibt es einige spezielle Indizes deren Bedeutung in der MSDN nachgelesen werden kann:

Index mit eingeschlossenen Spalten
Volltext
Räumlich (für den Geography-Datentyp)
Filtered (für fest definierte Teilmengen)
XML (für den Datentyp XML)

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


SQL-Montag: Was ist der Unterschied zwischen “Delete From” und “Truncate”?

Monday, March 28, 2011 10:42:28 PM (Mitteleuropäische Sommerzeit, UTC+02:00)

Thomas Mentzel hat in seinem Blog eine ziemlich coole Aktion gestartet, bei der er am Anfang der Woche fünf Fragen stellt.
Jede Frage bezieht sich auf einen anderen Werktag der Woche und behandelt ein Thema aus dem .NET-Programmierumfeld.

Die erste Frage, die er zum heutigen “SQL-Montag” gestellt hat, ist: Was ist der Unterschied zwischen Delete From und Truncate?

Diese Frage möchte ich gern beantworten.

delete-truncateDelete und Truncate sind T-SQL Befehle, mit denen Datensätze aus Tabellen einer MS-SQL Datenbank gelöscht werden können.
Das sind auch schon die Gemeinsamkeiten. Die Unterschiede liegen im Detail.

Der Befehl Delete löscht die Datensätze physikalisch und speichert das Löschen jeder einzelnen Zeile im Transaction-Log ab. Werden viele Zeilen gelöscht, wächst das Log File entsprechend schnell.


Werden Datensätze mit Truncate gelöscht, werden die Datensätze nicht physikalisch gelöscht, sondern werden nur zum überschreiben freigegeben. Das Freigeben der Daten wird ebenfalls geloggt, nur auf eine andere Art und Weise.
Dadurch ist Truncate zwar schneller, hat aber auch einige Nachteile:

  • Um ein Truncate Statement ausführen zu dürfen, muss man db_owner, ddl_admin oder Besitzer der Tabelle sein.
  • Truncate funktioniert nicht bei Tabellen, die FOREIGN KEY Constraints haben.
  • Truncate kann keinen Trigger aktivieren.
  • Die Daten einer Tabelle können nicht mit Truncate gelöscht werden, wenn die Tabelle Grundlage einer View ist.

Ein weiterer wesentlicher Unterschied ist, dass man bei Delete die zu löschenden Daten mit Hilfe der Where Bedingung einschränken kann. Mit Truncate können nur ganze Tabellen gelöscht werden.

Löscht man Daten aus einer Tabelle, die eine IDENTITY-Spalte hat, kann man beim Truncate Statement feststellen, dass der Wert der IDENTITY-Spalte auf den Ausgangswert (in der Regel 0) zurück gesetzt wird.
Löscht man die Daten hingegen mit dem Delete Statement, sieht man, dass der Zähler der IDENTITY-Spalte erhalten bleibt.

Hierzu noch ein Tipp: Möchte man mit Delete löschen, weil man beispielsweise eine Where Bedingung braucht, kann man den Zähler der IDENTITY-Spalte nachträglich auf den Ausgangswert mit Hilfe des folgenden Befehls auf 0 zurück setzen:

DBCC CHECKIDENT (Tabellenname, reseed, 0)

Wer beantwortet morgen die Frage zum Thema LINQ? Smiley

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


prio.conference 2010 – mein Braindump

Wednesday, October 20, 2010 9:20:54 PM (Mitteleuropäische Sommerzeit, UTC+02:00)

Vom 19. bis 20. Oktober 2010 fand die prio.conference zum ersten Mal in Nürnberg statt. Der Veranstaltungsort kam mir sehr gelegen, da ich bis zur Meistersingerhalle nur 15 Minuten mit dem Auto fahren musste.

In den zwei Tagen gab es ziemlich viel neues. Einiges davon hatte ich schon über Twitter vom .NET Open Space mitbekommen, welcher einige Tage vorher in Leipzig statt fand.

Da ich während der Sessions auf der prio.conference nichts mitgeschrieben habe, nutze ich einfach mal diesen Blogpost um zu notieren, was ich für wichtig halte. Sicher interessiert es auch den ein oder anderen.

Die Konferenz startete erst einmal ziemlich ungewöhnlich mit einer Märchenerzählerin und einem Vortrag von einem Filmregisseur. Die Märchenerzählerin gab während des ersten Tages einige Grimm-Märchen zum besten und mappte die Lehren aus den Märchen auf die heutige Welt der Softwareentwicklung. Nette Idee, aber für mich war es ein bisschen zu langatmig.

Ivan Engler ist ein Schweizer Regisseur, der vor seiner Karriere beim Film auch mal 5 Jahre Software entwickelt hat. Er zog viele Parallelen zwischen der Filmproduktion und der Softwareentwicklung. Die wesentliche Aussage war: Erst denken, dann programmieren.

Danach gab es erst mal etwas handfestes von Thorsten Hans und Jürgen Gutsch. Thorsten zeigte den Einsatz von JSON in .NET und jQuery. Jürgen beschäftigte sich in der Vergangenheit oft mit WebDAV und berichtete in 60 Minuten sehr anschaulich über seine Erfahrungen mit diesem offenen Standard.

In einer so genannten General Session erklärte Martin Huber die Unterschiede zwischen verschiedenen Mechanismen für die verteilte Kommunikation, schließlich war ja verteilte Architektur das Thema der prio. Sein Schwerpunkt war das Für und Wider von RESTful HTTP.

Golo Roden hielt auf der Prio zwei Vorträge, einer war zum Thema Windows Identity Foundation. Ein Framework was kaum einer kennt und schlecht dokumentiert ist. WIF ist aber sicher nicht uninteressant, wenn man auf der Suche nach einer zentralen Lösung für Authentifizierung und Rechtevergabe ist.

Auf der prio wurde in mindestens zwei Vorträgen deutlich, dass wir uns immer öfter fragen müssen, ob wir nicht alt eingeschliffene Vorgehensweisen hinterfragen sollten. Am deutlichsten wurde dies am Beispiel vom klassischen 3 (bzw. n) Tier Schichtenmodell und von zentralen relationalen Datenbanken.
Am Abend des ersten Tages stellte Udi Dahan die CQRS Architektur (Command Query Responsibility Segregation) vor und erklärte die Vorteile gegenüber einer klassischen Schichtenarchitektur. CQRS sollte zum Beispiel eingesetzt werden, wenn hochperformante Anwendungen gefordert werden bei denen sich extrem viele User gleichzeitig anmelden.

Nach einem guten Essen und zwei, drei Bier mit Jürgen ging es zum Coding Dojo. Dies war mein erstes Dojo. In der letzten Zeit konnte man über Blogs und in Twitter scheinbar endlose Diskussionen über die verschiedenen Dojo-Styles und über die Frage wer es erfunden hat, mitverfolgen. Diese Diskussionen haben aus meiner Sicht ein schlechtes Bild auf die Idee des Dojos und auf deren Veranstalter geworfen. Jetzt konnte ich mir selbst ein Bild davon machen. Stefan Lieser und Ralf Westphal haben das Dojo moderiert und haben sich dabei vielleicht ein wenig zu viel zurückgehalten. Die Aufgabe war ein einfacher Formelparser der kurz vor knapp fertig wurde. Wie im richtigen Leben. Ich fand es besonders cool, dass die Aufgabe nach viel hin und her von zwei “alten Hasen” ganz souverän mit TDD Unterstützung gemeistert wurde. Ich finde die Idee, zusammen zu coden, gut weil man dabei viel von einander lernt. Wie man das ganze nennt und in welchem Rahmen man das macht, sind für mich “nur Implementierungsdetails”.

Der zweite Tag der Konferenz begann mit einem Vortrag von Stefan Lieser zum Thema Bounded Contexts. Der Vortrag kritisierte das von Microsoft empfohlene Modell einer zentralen relationalen Datenbank weil je nach Kontext andere Daten wichtig sind. Er zeigte, wie man in einer großen Anwendung durchaus mehrere Datenbanken einsetzen kann. Je nach Aufgabe kann dabei ein anderes Datenbanksystem (NoSQL,  RDMS …) eingesetzt werden. Für den Abgleich der Datenbanken untereinander empfahl er einen Service Bus.
Zum Thema Service Bus hielt Björn Rochel einen sehr guten Vortrag. Er gab eine Einführung in den Rhino Service Bus. Der Bus basiert auf verschiedenen vorhandenen Technologien wie zum Beispiel MSMQ 4.0 und und hat als Ziel den Einstieg in das Thema Service Bus sehr einfach zu gestalten. Dies konnte Björn gut demonstrieren.

Weiter ging es für mich mit der Session von Bernd Marquardt zum Thema MPI. Ein mächtiges Werkzeug um Rechenoperationen über ein Netzwerk zu verteilen, also zu parallelisieren. Das braucht man immer wieder, wenn man zum Beispiel die Elektronendichte in einem Gasnebel berechnen will Zwinkerndes Smiley

Der Top Speaker der Konferenz war sicher Ayende Rahien. Er hielt eine Session, in der er NoSQL-Datenbanken, Dokument-Datenbanken, Graph-Datenbanken und so genannte Column Family Databases miteinander verglich. Der Vortrag war ganz ok. Anschaulicher wurde es jedoch im nächsten Vortrag von Sergey Shishkin der verschiedene NoSQL- und Clouddatenbanken an praktischen Beispielen, inklusive Quellcode, vorstellte.

Das letzte große Highlight der Konferenz war Ralf Westphal mit seinem Vortrag zu EBC (Event-Based Components). Ich hatte seine Artikel zu EBC in der Vergangenheit nur kurz überflogen und hab das Thema nicht besonders ernst genommen. Der Vortrag hat aber definitiv Lust auf mehr gemacht, vor allem wenn Stefan und Ralf das Tooling noch zu Ende entwickeln, sind EBC’s ganz bestimmt eine feine Sache.

Mein Fazit der Konferenz:

  • Der Einsatz von relationalen Datenbanken sollte genau geprüft werden, können andere Datenbanken die Anforderungen besser erfüllen (siehe CAP-Theorem)?
  • Die Cloud kommt und macht auch Sinn.
  • Nur Code ist die Wahrheit.
  • Den Rhino Service Bus und die Couch DB in Verbindung mit JQuery sollte man sich ansehen.
  • Exceptions heißen ab sofort Bumsti.
  • Schichtenarchitektur in Frage stellen und mit EBC bzw. CQRS  vergleichen.


Wo nehme ich bloß die Zeit her, um mich mit den ganzen Sachen zu beschäftigen?

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


ADO.NET Data Services (Astoria): XML nicht als RSS Feed anzeigen

Friday, August 22, 2008 12:01:51 AM (Mitteleuropäische Sommerzeit, UTC+02:00)

Eins der neuen Features im .NET Framework 3.5 SP1 sind die ADO.NET Data Services, diese sind auch unter dem Namen Astoria bekannt.

Wer die Data Services nutzen möchte und den Internet Explorer verwendet, sollte die folgende Einstellung vornehmen:

Extras -->Internetoptionen --> Inhalte --> Feeds --> Einstellungen --> Feedleseanzeige einschalten --> deaktivieren

Mit Hilfe dieser Einstellung werden die XML Daten vom Internet Explorer nicht als RSS Feed angezeigt.
Das Ergebnis ist deutlich besser lesbar ;-)

Feedanzeige

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


Einführung in Linq to XML

Saturday, June 28, 2008 12:11:28 AM (Mitteleuropäische Sommerzeit, UTC+02:00)

Vor kurzem habe ich eine dreiteilige Artikelserie geschrieben die den Einstieg in das Thema Linq to XML erleichtern soll. Die Artikel sind analog zu dem 4 grundlegenden Datenbankoperationen CRUD (Create, Retrieve, Update und Delete ) gegliedert.
Zu jedem Artikel gibt es ein Beispielprojekt zum Download.

LINQ to XML Teil 1 – Erstellen einer XML Datei
LINQ to XML Teil 2 – Abfragen einer XML Datei
LINQ to XML Teil 3 – Manipulieren einer XML Datei

Viel Spaß beim Lesen!

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


Mitschnitte des Launch Events online

Friday, March 14, 2008 2:28:42 PM (Mitteleuropäische Zeit, UTC+01:00)

Im Februar wurden die 3 Produkte Visual Studio 2008, SQL Server 2008 & Windows Server 2008 in Frankfurt vorgestellt.
Wer nicht dabei sein konnte oder sich einige ausgewählte Sessions nocheinmal ansehen möchte, kann dies jetzt tun.

Diese exklusiven Mitschnitte folgender Vorträge stehen ab sofort unter diesem Link bereit:

-   Keynote
-   Neu in Visual Studio 2008
-   SQL Server 2008
-   Überblick Windows Server 2008 Management
-   Internet Information Server 7
-   Virtualisieren mit dem Windows Server

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


LIKE und Wildcards bei Linq

Sunday, December 16, 2007 4:54:46 PM (Mitteleuropäische Zeit, UTC+01:00)

Möchte man mit SQL zum Beispiel alle Kundennamen aus einer Tabelle abfragen die mit "Me" beginnen, verwendet man LIKE, wie das folgende Beispiel zeigt:

SELECT * FROM customer
WHERE ContactName LIKE 'Me%' 

Linq bietet für diesen Zweck die Methode StartsWith an:

var customers = from c in db.Customers
                where c.ContactName.StartsWith("Me")
                select c; 

Möchte man jedoch auf die LIKE Methode in Linq nicht verzichten um Wildcards wie das Prozentzeichen zu verwenden, kann die Methode SqlMethods.Like aus dem Namespace System.Data.Linq.SqlClient verwendet werden.

Beispiel:

var customers = from c in db.Customers
                where SqlMethods.Like(c.ContactName, "Me%")
                select c;

Diesen Tooltip sollte man an dieser Stelle einfach ignorieren :-)

Like

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


Neue Insert und Delete Methoden bei Linq

Wednesday, November 28, 2007 9:50:13 PM (Mitteleuropäische Zeit, UTC+01:00)

Auf vielen Webseiten, meist Entwicklerblogs, findet man derzeit diverse Linq Beispielabfragen Wie zum Beispiel diese hier:

db.Customers.Add(newCustomer)
db.SubmitChanges()
Diese Add Methode gab es nur in der Beta 1 und 2, in der RTM Version wurden die ADD und Remove Methoden umbenannt:

Beta 2 Version RTM Version
Add() InsertOnSubmit()
AddAll() InsertAllOnSubmit()
Remove() DeleteOnSubmit()
RemoveAll() DeleteAllOnSubmit()

Diese Übersicht hab ich im Blog von Özgür Aytekin gefunden, Danke!

Achtung: Sogar in der MSDN findet man noch oft die veralteten Methoden!

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


SQL Befehle einer Linq Abfrage ausgeben

Sunday, November 25, 2007 7:53:30 PM (Mitteleuropäische Zeit, UTC+01:00)

Daniel Walzenbach hat in seinem Blog gezeigt wie man die von Linq erzeugte SQL Abfrage in die Console umleiten kann.
Was machen nun die Webentwickler die keine Console haben?
Eine Möglichkeit ist, den Inhalt in den Debugger Output zu schreiben, dazu hat Kris Vandermotten eine kleine Klasse geschrieben die in seinem Blog zu finden ist.
Wer sich die SQL Abfrage im Browser ansehen möchte, kann  den StringWriter verwenden wie der folgende Code zeigt:

DataContext db = new DataContext();

StringWriter stringWriter = new StringWriter();
db.Log = stringWriter;

// Linq Abfrage

Response.Write(stringWriter.ToString());

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


Linq vs. ADO.NET

Sunday, November 25, 2007 7:29:27 PM (Mitteleuropäische Zeit, UTC+01:00)

Heute habe ich eine SQLRoleProvider Klasse von ADO.NET auf LINQ umgestellt.
Die beiden folgenden Codebeispiele machen genau das gleiche.
An diesem Beispiel wird deutlich wie effektiv LINQ sein kann.

ADO.NET Variante:

bool exists = false;
connectionString = ConfigurationManager.ConnectionStrings["myConnectionString"].ConnectionString;
SqlConnection conn = new SqlConnection(connectionString);
SqlCommand cmd = new SqlCommand("SELECT COUNT(*) FROM Roles WHERE Rolename = @Rolename", conn);

cmd.Parameters.Add("@Rolename", SqlDbType.VarChar, 255).Value = rolename;
cmd.Parameters.Add("@ApplicationName", SqlDbType.VarChar, 255).Value = ApplicationName; 

conn.Open(); // try catch finally hab ich für dieses Beispiel entfernt
int numRecs = (int) cmd.ExecuteScalar();
conn.Close();
if (numRecs > 0)
       exists = true;
return exists;


Linq Variante:

private DataContext db = new DataContext();
var roleCount = (from r in db.Roles
         where r.Rolename == rolename
         select r).Count();

return (roleCount > 0);

Der von der Linq Abfrage erzeugte SQL Code sieht dann so aus:

SELECT [t0].[ID], [t0].[Rolename]
FROM [dbo].[Roles] AS [t0]
WHERE [t0].[Rolename] = @p0

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de


MS SQL Server Datenbanken kopieren

Thursday, November 22, 2007 12:56:07 AM (Mitteleuropäische Zeit, UTC+01:00)

Wie kann eine SQL Server Datenbank von einem SQL Server zu einem andern SQL Server kopiert werden, wenn nur eingeschränkte Zugriffsrechte zu Verfügung stehen?
Dies ist zum Beispiel der Fall, wenn die DB bei einem ISP gehostet ist.
Das Anlegen eines DB Backups ist auf Grund fehlender Schreibrechte oft nicht möglich. Was tun?
Mit dem SQL Manager von EMS ist es möglich, ein SQL Script zu erstellen, mit welchem die komplette Datenbank wiederhergestellt werden kann. Die Software erzeugt ein SQL Script in dem alle „Create Table“, „Insert Into“ usw. Anweisungen enthalten sind.
Dieses Script kann, je nach Größe der Datenbank, sehr groß werden. Dies sollte allerdings in Zeiten von großen Datenträgern, schnellen Netzwerkanbindungen und guten Packprogrammen kein Problem darstellen.

Wurde das Script erstellt und auf das Ziel – System kopiert, kann es einfach mit dem SQL Manager ausgeführt werden und die Datenbank wurde eins zu eins kopiert.

Beim Erstellen des Scripts kann ausgewählt werden, ob nur die Daten, nur die Struktur der DB oder beides erstellt werden soll.
Es folgt eine Kurzanleitung.

Erstellung eines SQL Script:
- Verbindung zur DB aufbauen
- Tools | DB extrahieren | speichern in Datei

Ausführen des SQL Script
- Verbindung zur neuen DB aufbauen
- Hauptmenü | SQL Script ausführen

Eine kostenlose Light Version des SQL Managers kann hier runtergeladen werden.
Der SQL Manager ist für alle gängigen DMS erhältlich.

Wenn ihnen der Artikel gefallen hat oder er für sie hilfreich war,
bitte "kicken" sie ihn.

Kick it on dotnet-kicks.de