Über unsMediaKontaktImpressum
William Durkin 11. April 2017

SQL Server 2016: Was ist neu? – Teil 3: Entwicklung & Tools

In dieser Folge der Neuerungen bei SQL Server 2016 werden wir uns auf die Entwicklung von T-SQL und die dazugehörigen Tools konzentrieren. Über die Zeit werden neue Methoden entwickelt und Erkenntnisse gewonnen, die eine Programmiersprache kontinuierlich verbessern. Microsoft hat mit SQL Server 2016 einige Neuerungen in die Database Engine eingebaut, die das Leben eines Entwicklers erleichtern. Wie in den ersten beiden Teilen (Teil 1 & Teil 2) dieser Serie erwähnt, sind viele Änderungen durch die Cloud-Lösung "Azure" entstanden. Im Folgenden erfahren wir, wie das Produkt speziell für Entwickler verbessert und erweitert wurde.

JSON

Unter den Datenaustauschformaten hat sich JSON seit Anfang der 2000er Jahre zum Austauschformat Nummer 1 entwickelt [1]. Als SQL Server 2005 entwickelt wurde, war XML noch die Nummer eins und Microsoft hat lange gezögert, das mittlerweile deutlich "trendigere" JSON mit einzubinden. Es war zwar vor SQL Server 2016 möglich, JSON-Daten zu verarbeiten, allerdings musste man zu Drittanbieterlösungen greifen. Die Wahl fiel auf SQLCLR (JSON4SQL oder JSON.SQL) oder Transact-SQL-Lösungen, die mit Einschränkungen verbunden waren [2].

Mit SQL Server 2016 ist es endlich soweit und JSON wird nativ unterstützt. Es ist möglich, Daten als JSON sowohl an SQL Server zu übergeben als auch Daten im JSON-Format auszugeben. Das heißt, es müssen weder CLR-Objekte erstellt werden, noch muss man mit unhandlichen T-SQL-Funktionen umgehen. Es wird eine einfache Option bei der Abfrage mitgeteilt, und die Daten werden verarbeitet. Um Tabellendaten als JSON auszugeben, hat man zwei Möglichkeiten:

  1. FOR JSON AUTO
  2. FOR JSON PATH

Für die Entwickler unter uns, die schon mit XML in SQL Server gearbeitet haben, sind diese Befehle bereits vertraut. Wenn ein Select mit einem der beiden Zusätze ausgeführt wird, werden die Daten per Select geladen und anschließend als JSON formatiert (inklusive Datentypumwandlung sowie Zeichenumwandlung, wo notwendig). Hier sehen wir im Vergleich eine Abfrage mit JSON und die gleiche Abfrage mit XML als Ausgabeformat:

SELECT
     CustomerID ,
     OrderId ,
     ProductId ,
     Quantity ,
     Price ,
     OrderDate ,
     AreaId
FROM dbo.Orders
FOR JSON AUTO;
SELECT
     CustomerID ,
     OrderId ,
     ProductId ,
     Quantity ,
     Price ,
     OrderDate ,
     AreaId
FROM dbo.Orders
FOR XML AUTO;

Wenn wir die zwei Abfragen ausführen, können wir sehen, wie die Formate sich unterscheiden:

Als erstes haben wir die JSON-Daten:

[
{"CustomerID":1,"OrderId":1,"ProductId":4711,"Quantity":1,"Price":100.000,"OrderDate":"2017-03-09T11:41:36.233","AreaId":1},
{"CustomerID":2,"OrderId":2,"ProductId":4712,"Quantity":1,"Price":200.000,"OrderDate":"2017-03-09T11:41:36.233","AreaId":1},
{"CustomerID":3,"OrderId":3,"ProductId":4713,"Quantity":1,"Price":500.000,"OrderDate":"2017-03-09T11:41:36.233","AreaId":2}
]

Und anschließend die XML-Daten:

<dbo.Orders CustomerID="1" OrderId="1" ProductId="4711" Quantity="1" Price="100.000" OrderDate="2017-03-09T11:41:36.233" AreaId="1" />
<dbo.Orders CustomerID="2" OrderId="2" ProductId="4712" Quantity="1" Price="200.000" OrderDate="2017-03-09T11:41:36.233" AreaId="1" />
<dbo.Orders CustomerID="3" OrderId="3" ProductId="4713" Quantity="1" Price="500.000" OrderDate="2017-03-09T11:41:36.233" AreaId="2" />

Beide Datenformate sind sehr ähnlich, und der Aufruf von der JSON-Formatierung folgt den gleichen Syntaxregeln wie XML. Das hat damit zu tun, dass Microsoft die XML-Parser innerhalb des SQL Servers benutzt hat, um die Erzeugung von JSON-Daten zu ermöglichen.
Hier müssen wir allerdings aufpassen: FOR JSON AUTO lässt standardmäßig NULL-Werte aus der Ausgabe heraus. Wenn in der Beispieltabelle ein Wert als NULL existiert, wird diese Spalte für den Datensatz überhaupt nicht ausgegeben:

SELECT
     CustomerID ,
     OrderId ,
     ProductId ,
     Quantity ,
     Price ,
     OrderDate ,
     AreaId
FROM dbo.OrdersFOR JSON AUTO;
[
{"CustomerID":1,"OrderId":1,"ProductId":4711,"Quantity":1,"Price":100.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":1},
{"CustomerID":2,"OrderId":2,"ProductId":4712,"Quantity":1,"Price":200.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":1},
{"CustomerID":3,"OrderId":3,"ProductId":4713,"Quantity":1,"Price":500.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":2},
{"CustomerID":1,"OrderId":2,"ProductId":4711,"Quantity":1,"Price":100.000,"OrderDate":"2017-03-09T11:52:52.857"}
]

AreaId ist bei dem vierten Datensatz NULL und gar nicht in der Ausgabe vorhanden. Um NULL-Werte trotzdem auszugeben, müssen wir die Zusatzoption INCLUDE_NULL_VALUES beim FOR JSON AUTO-Befehl hinzufügen:

SELECT
     CustomerID ,
     OrderId ,
     ProductId ,
     Quantity ,
     Price ,
     OrderDate ,
     AreaId
FROM dbo.Orders
FOR JSON AUTO, INCLUDE_NULL_VALUES;
[
{"CustomerID":1,"OrderId":1,"ProductId":4711,"Quantity":1,"Price":100.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":1},
{"CustomerID":2,"OrderId":2,"ProductId":4712,"Quantity":1,"Price":200.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":1},
{"CustomerID":3,"OrderId":3,"ProductId":4713,"Quantity":1,"Price":500.000,"OrderDate":"2017-03-09T11:52:01.003","AreaId":2},
{"CustomerID":1,"OrderId":2,"ProductId":4711,"Quantity":1,"Price":100.000,"OrderDate":"2017-03-09T11:52:52.857","AreaId":null}
]

FOR JSON AUTO hat die Ausgabe automatisch in einer bestimmten Hierarchie dargestellt, die Option FOR JSON PATH erlaubt uns, die Ausgabe in beliebigen Struktur zu bringen.

Um die Ausgabe unserer Testtabelle zu ändern, können wir die Spalten der Bestellung in eine Hierarchieebene einbringen. Somit werden die bestellungsrelevanten Daten von Kunde und Bereich getrennt. Hierzu müssen wir den Spalten jeweils einen Alias geben, um sie anschließend in der Hierarchie gruppieren zu können:


SELECT
     CustomerID ,
     OrderId AS 'Order.OrderId',
     ProductId AS 'Order.ProductId',
     Quantity AS 'Order.Quantity',
     Price AS 'Order.Price',
     OrderDate AS 'Order.OrderDate',
     AreaId
FROM dbo.Orders
FOR JSON PATH;
[  
   {  
      "CustomerID":1,
      "Order":{  
         "OrderId":1,
         "ProductId":4711,
         "Quantity":1,
         "Price":100.000,
         "OrderDate":"2017-03-09T11:52:01.003"
      },
      "AreaId":1
   },
   {  
      "CustomerID":2,
      "Order":{  
         "OrderId":2,
         "ProductId":4712,
         "Quantity":1,
         "Price":200.000,
         "OrderDate":"2017-03-09T11:52:01.003"
      },
      "AreaId":1
   },
   {  
      "CustomerID":3,
      "Order":{  
         "OrderId":3,
         "ProductId":4713,
         "Quantity":1,
         "Price":500.000,
         "OrderDate":"2017-03-09T11:52:01.003"
      },
      "AreaId":2
   },
   {  
      "CustomerID":1,
      "Order":{  
         "OrderId":2,
         "ProductId":4711,
         "Quantity":1,
         "Price":100.000,
         "OrderDate":"2017-03-09T11:52:52.857"
      }
   }
]

So können wir sehen, dass die Spalten, die unter "Order.xxx" benannt werden, in einer Hierarchie zusammengefasst wurden.

Insgesamt werden sehr viele Datentypen im SQL Server bei der FOR JSON-Konvertierung unterstützt, jedoch nicht alle. Die SQL CLR-Typen, sowie Geography- und Geometry-Datentypen werden nicht unterstützt. Eine vollständige Liste stellt Microsoft zur Verfügung [3].

In-Memory OLTP

Die In-Memory-Technologien bei Datenbanksystemen sind gerade sehr beliebt. Ob SAP HANA, Oracle In-Memory Processing, IBM DB2 oder (seit SQL Server 2014) auch Microsoft – In-Memory-Datenverarbeitung im OLTP- und OLAP-Bereich wird bei allen namenhaften Herstellern deutlich ausgebaut.

Bei SQL Server gab Hekaton in SQL Server 2014 sein Debut. Es waren enorme Verarbeitungsersparnisse möglich, wenn man mit der langen Liste von Einschränkungen leben konnte. Die Tatsache, dass es möglich war, Daten zu prozessieren ohne dabei auf Sperren achten bzw. warten zu müssen, war ein Segen. Mit SQL Server 2016 hat Microsoft einen großen Sprung nach vorne gemacht und viele der Einschränkungen von der Liste gestrichen.

Die erste große Verbesserung ist die Tatsache, dass wir nun In-Memory-Objekte ändern können. Vor SQL Server 2016 wurden wir gezwungen, ein Objekt zu löschen, um Änderungen dann per CREATE-Befehl neu zu erzeugen. Mit SQL Server 2016 ist es jetzt möglich, bestehende Tabellen und Gespeicherte Prozeduren mittels ALTER-Befehl anzupassen. Dadurch gewinnen wir als Entwickler sowie Datenbankadministrator enorm an Flexibilität in der Verteilung von Anpassungen und Neuentwicklungen, denn ein ALTER ist in der Regel schneller und einfacher durchzuführen, als ein DROP und CREATE. Somit rutschen In-Memory-Tabellen und gespeicherte Prozeduren näher an die "normalen" Tabellen und gespeicherten Prozeduren heran und lassen sich fast genauso behandeln. Das Hinzufügen von Spalten an eine Tabelle wird mit der gleichen Syntax durchgeführt, wie bei einer gewöhnlichen Tabelle:

ALTER TABLE dbo.Categories ADD NewColumn int NOT NULL

Solche Änderungen sind möglich, müssen aber vorsichtig geplant sein. Die Änderungen werden im Hintergrund wie folgt ausgeführt:

  1. ALTER-Befehl vom SQL Server entgegennehmen,
  2. Objekt finden, um die Änderung durchzuführen,
  3. Kopie des Objektes (inkl. neuer Spalte) erzeugen,
  4. Daten des Objektes in die "neue" Tabelle kopieren,
  5. Referenzen von der "alten" Tabelle auf die "neue" Tabelle umlenken und
  6. "Alte" Tabelle löschen.

Man muss dabei bedenken, dass zwischen Schritt 3 und Schritt 6 die Tabelleninhalte doppelt gespeichert werden. Das kann kritisch werden, wenn die Tabelle eine große Menge an Arbeitsspeicher belegt und durch die Änderung rasch (wenn auch nur kurzzeitig) der Arbeitsspeicherbedarf verdoppelt wird.

Es ist nun auch möglich, deutlich mehr Datentypen innerhalb der In-Memory-Engine zu nutzen, und es ist jetzt einfacher, die Datentypen aufzulisten, die nicht unterstützt werden:

  • Datetimeoffset
  • Geography
  • Geometry
  • Hierarchyid
  • Rowversion
  • Xml
  • Sql_variant

Das heißt, bis auf "Randtypen" werden alle Datentypen unterstützt. Somit ist die Benutzung von In-Memory-Tabellen bei deutlich mehr Projekten bzw. Applikationen möglich, als bei SQL Server 2014. Von der Liste abzuleiten ist die Tatsache, dass nun die LOB-Datentypen unterstützt werden. Das sind die Datentypen VARCHAR(MAX), NVARCHAR(MAX) und VARBINARY(MAX). Mit SQL Server 2016 ist es möglich, bestehende Projekte ohne große Umbaumaßnahmen auf die In-Memory OLTP-Engine umzuändern.

SQL Server Management Studio (SSMS)

Als Schnittstelle für viele Entwickler und Administratoren ist SSMS ein sehr wichtiges Werkzeug, das in der Vergangenheit eher stiefmütterlich behandelt wurde. SSMS hat aber während der Entwicklung von SQL Server 2016 einige begrüßenswerte Verbesserungen erfahren, die es deutlich stärker und gleichzeitig flexibler machen.

Die größte und bedeutendste Verbesserung ist die Entkopplung von SQL Server und SSMS. Das heißt, die Entwicklung von SQL Server und SSMS sind ab SQL Server 2016 komplett getrennt worden. So ist es möglich, die Entwicklung und Verbesserung von SSMS schneller voranzutreiben als die des SQL Servers. Früher mussten wir auf eine neue Version des gesamten SQL Servers warten, bevor SSMS aktualisiert wurde, jetzt haben wir seit der Veröffentlichung von SQL Server 2016 fast monatliche Aktualisierungen von SSMS. So ist es einfacher, neue Features für die Administratoren und Entwickler zu liefern. SSMS wird nicht mehr beim SQL Server mitgeliefert, sondern muss getrennt heruntergeladen werden. Derzeit gibt es sowohl die aktuelle Version als auch eine Community Technology Preview (CTP)-Version von SSMS. Die CTP ist eine Betaversion, die vorab für mutige ITler bereitgestellt wird [4]!

Live Query Statistics (LQS)

Während der Entwicklung eines Datenbankprojektes sollten Entwickler sowie Administratoren sehr genau auf die Abfragen und deren Ausführungsstatistiken achten. Je früher Probleme erkannt werden, desto einfacher wird es, sie zu lösen. Dafür hat Microsoft ein weiteres Werkzeug geliefert, um besonders die Ausführungspläne von Abfragen verständlicher zu machen.

LQS zeigt Ausführungspläne an, während die dazugehörigen Abfragen noch verarbeitet werden. Das erlaubt es Entwicklern oder Administratoren zu sehen, wie die Daten durch einen Ausführungsplan "fließen". Hierzu muss man lediglich Live Query Statistics auf der SSMS Oberfläche aktivieren (s. Abb.1).

Wurde LQS aktiviert und eine Abfrage ausgeführt (die auch lang genug läuft, um die Ausführung zu verfolgen), sehen wir das bekannte Ausführungsplanfenster. Mit LQS sehen wir allerdings kein Ergebnis nach der Ausführung, sondern eine Echtzeitanzeige der Ausführung.

In Abb.2 sehen wir die Live Query Statistics während eine Abfrage prozessiert wird. Anders als bei einer abgeschlossenen Abfrage bewegen sich die gestrichelten Linien, um den Datenfluss darzustellen. Zusätzlich dazu werden die Knoten mit dem jeweiligen prozentualen Fortschritt angezeigt. So ist sehr einfach zu erkennen, wo die Verarbeitung schnell und wo sie langsam vorankommt und demnach auch, wo Optimierungspotenzial steckt.

Fazit

Wir haben in diesem Artikel gesehen, dass es für Entwickler einige Verbesserungen beim SQL Server 2016 gibt. Wir konnten hier nicht alle Veränderungen auflisten, diese "Kostprobe" gibt hoffentlich einen guten Einstieg. Die hier aufgeführeten Neuerungen sind allesamt begrüßenswert und werden die tägliche Arbeit vieler Entwickler erleichtern und die entwickelten Lösungen performanter machen. Bereits die neue SSMS-Version, die kostenlos heruntergeladen werden kann [5] sollte Grund genug sein, sich als Entwickler mit dem SQL Server 2016 zu befassen.

Dieser Artikel ist Teil einer Serie von William Durkin über die Neuheiten von SQL Server 2016.

  Teil I: SQL Server 2016: Security
  Teil II: SQL Server 2016: Database Engine Features

Autor
Das könnte Sie auch interessieren
Kommentare (0)

Neuen Kommentar schreiben