DATENINTEGRATION UND PROTOTYP-ERSTELLUNG ZUR ANALYSE VON ENERGIEDATEN Bachelorarbeit Marcel Menz Bachelor of Science in Wirtschaftsinformatik Fachhochschule Nordwestschweiz Auftraggeber: Canoo Engineering, Basel Dozent: Professor Dr. Bradley Richards 2. September 2011 EIDESSTATLICHE ERKLÄRUNG Ich erkläre hiermit an Eides statt, dass ich die vorliegende Thesis selbständig und ohne unzulässige fremde Hilfe angefertigt habe. Die verwendeten Quellen sind vollständig zitiert. Datum: 01.09.2011 Unterschrift_______________ MANAGEMENT SUMMARY Ziel der vorliegenden Arbeit war, die ULCGeoMaps und den ULCBigTableExplorer in einem Prototyp zu vereinen und die Komponenten und deren Integrationsfähigkeit zu validieren. Insbesondere sollte die gemeinsame Programmierschnittstelle überprüft werden. Ebenfalls interessierte die Frage, wie gut die Komponenten mit einer Datenbank zusammenarbeiten. Zu diesem Zweck wurden Energiedaten aus Deutschland verwendet. Diese wurden zuerst vorverarbeitet. Eine gemeinsame Nutzung des ULCBigTableExplorer und der ULCGeoMaps ist möglich. Die Komponenten sind schon weit entwickelt. Es hat sich aber gezeigt, dass insbesondere dem ULCBigTableExplorer noch einige wichtige Funktionen fehlen um erweiterte Analysen durchführen zu können. Die Komponente sollte bei den Diagrammen, den Aggregationen, Sortierungen und Berechnungen sowie beim Datenexport erweitert werden. Dies ist aber aufgrund der soliden Basis schnell möglich. Beim ULCBigTableExplorer sollte zudem noch die Performanz verbessert werden. Die Integration mit einer Datenbank ist noch nicht elegant möglich. Die Datenanbindungsschnittstelle ist noch zu stark auf die Verwendung mit Datenfiles optimiert. Die Flexibilität der Datenbank kann noch nicht genutzt werden. Insbesondere für einen Einsatz im Bereich "Business Intelligence" ist aber eine gute Unterstützung von Datenbanken matchentscheidend. Aufgrund der gut durchdachten Architektur der Komponenten ist eine Erweiterung aber schnell möglich. Der Prototyp ist im Moment erst auf der Datenebene integriert. Eine vollständige Integration der Komponenten ist schon in Planung. Dies wäre sicherlich eine gewinnbringende Kombination. Die einfache Nutzung der Komponenten muss dabei aber im Auge behalten werden. Durch eine moderate Weiterentwicklung, die sich konsequent von den Anforderungen eines Analysetools leiten lässt, können die Komponenten verbessert und markttauglich gemacht werden. INHALTSVERZEICHNIS 1 ABBILDUNGSVERZEICHNIS ............................................................................................................................. VIII 2 TABELLENVERZEICHNIS ................................................................................................................................. VIII 3 4 EINLEITUNG ................................................................................................................................................. 9 3.1 Auftraggeber.......................................................................................................................................... 9 3.2 Projektpartner ....................................................................................................................................... 9 3.3 Hintergrund ........................................................................................................................................... 9 3.4 Ausgangslage ....................................................................................................................................... 10 3.5 Problemstellung................................................................................................................................... 10 3.6 Zielsetzung ........................................................................................................................................... 10 3.7 Nutzen ................................................................................................................................................. 10 3.8 Vorgehen ............................................................................................................................................. 11 KOMPONENTEN ......................................................................................................................................... 12 4.1 Funktionalität ...................................................................................................................................12 4.1.2 Theoretische Einordnung .................................................................................................................13 4.2 5 6 ULCBigTableExplorer ........................................................................................................................... 12 4.1.1 ULCGeoMaps ....................................................................................................................................... 15 4.2.1 Funktionalität ...................................................................................................................................15 4.2.2 Theoretische Einordnung .................................................................................................................16 DATENANALYSE .......................................................................................................................................... 17 5.1 Vorgehen ............................................................................................................................................. 17 5.2 Was wurde analysiert? ........................................................................................................................ 17 5.3 Daten ................................................................................................................................................... 19 5.3.1 Gemeindedaten Rheinland Pfalz ......................................................................................................19 5.3.2 EEG-Kraftwerksdaten Rheinland Pfalz ..............................................................................................21 5.3.3 Stromdaten Verbandsgemeinden Rheinland Pfalz ..........................................................................23 5.3.4 Open GEO DB Datenbank .................................................................................................................24 DATENBANKSCHEMA ................................................................................................................................... 25 6.1 Beschreibung ....................................................................................................................................... 26 6.1.1 Geographische Entitäten ..................................................................................................................26 6.1.2 Tabelle kraftwerk .............................................................................................................................26 6.1.3 Tabelle Gemeindedaten ...................................................................................................................26 6.1.4 Tabelle Gemeindeverbandsdaten ....................................................................................................26 6.1.5 Tabellen meta_info/ meta_info_mapper .........................................................................................26 6.1.6 Tabelle mapping _helper ..................................................................................................................26 6.1.7 Tabelle open_geodb .........................................................................................................................27 6.1.8 Abbildung der Gemeindehierarchie .................................................................................................27 6.1.9 Trennung Stamm- und Bewegungsdaten .........................................................................................28 6.1.10 Datenbank Views ..............................................................................................................................31 6.1.11 Modellierung in GORM ....................................................................................................................32 7 DATENIMPORT ........................................................................................................................................... 34 7.1 8 Vorgehen ............................................................................................................................................. 34 DATENINTEGRATION.................................................................................................................................... 36 8.1 Gemeindemapping EEG-Kraftwerksdaten ........................................................................................... 36 9 10 8.1.1 Problem ............................................................................................................................................36 8.1.2 Normalisierung der Gemeindenamen ..............................................................................................36 8.1.3 Vorgehen Normalisierung ................................................................................................................36 8.1.4 Zuordnungsheuristik ........................................................................................................................37 8.1.5 Resultate ..........................................................................................................................................44 DATENANREICHERUNG ................................................................................................................................. 46 9.1 Längen- und Breitengrade ................................................................................................................... 46 9.2 Resultate .............................................................................................................................................. 47 PROTOTYP ERSTELLUNG ............................................................................................................................... 50 10.1 Ziele ..................................................................................................................................................... 50 10.2 Vorgehen ............................................................................................................................................. 50 10.3 Datenauswahl GUI ............................................................................................................................... 50 10.4 BigTableDataProvider .......................................................................................................................... 51 10.4.1 Hintergrund ......................................................................................................................................51 10.4.2 Architektur .......................................................................................................................................51 10.4.3 Programmierschnittstelle .................................................................................................................52 10.4.3.1 DataDescription ...................................................................................................................... 52 10.4.3.2 DataSource ............................................................................................................................. 54 10.4.4 Index .................................................................................................................................................55 10.5 Herausforderungen ............................................................................................................................. 56 10.5.1 Grails ULC Plugin ..............................................................................................................................56 10.5.2 Index .................................................................................................................................................56 10.5.3 Laden der Ressourcen ......................................................................................................................56 10.5.4 Dependency Management ...............................................................................................................57 10.5.5 Benutzerschnittstelle .......................................................................................................................57 10.5.5.1 Null Safety .............................................................................................................................. 57 10.5.5.2 ValueGetterFunction .............................................................................................................. 57 10.5.5.3 Data Source Singleton ............................................................................................................ 58 10.5.5.4 Eingebauter Date Kategorisierer ............................................................................................ 59 10.5.5.5 NoAggregationAggregationFunction ...................................................................................... 59 10.5.5.6 toName() ................................................................................................................................ 59 10.5.5.7 Dokumentation....................................................................................................................... 59 10.5.6 Performanz .......................................................................................................................................59 10.6 10.5.6.1 Datenbank Abfragen............................................................................................................... 59 10.5.6.2 Indexgenerierung ................................................................................................................... 61 10.5.6.3 Bemerkungen Performanz ...................................................................................................... 62 Bewertung der Komponenten ............................................................................................................. 62 10.6.1 Index .................................................................................................................................................62 10.6.2 Wechseln der DataDescription und DataSource ..............................................................................63 10.6.3 Kategorienbildung ............................................................................................................................63 10.6.3.1 Längen- und Breitengrade ...................................................................................................... 64 10.6.4 Aggregation der Werte .....................................................................................................................64 10.6.5 Auswertungen über die Zeit .............................................................................................................65 10.6.6 Sortierungsfunktion..........................................................................................................................65 10.6.7 Charts ...............................................................................................................................................65 10.6.8 Exportfunktionalität .........................................................................................................................66 10.6.9 Vollständige Integration der Komponenten .....................................................................................66 10.6.10 Direkte Datenbank abfragen ............................................................................................................66 11 EVALUATION COUCHDB............................................................................................................................... 69 11.1 Was ist NoSQL? .................................................................................................................................... 69 11.2 Warum NoSQL in diesem Projekt? ...................................................................................................... 69 11.2.1 Schnelle Anfragen ............................................................................................................................70 11.2.2 Schemafreiheit .................................................................................................................................70 11.2.3 Kategorisierung auf der Datenbank .................................................................................................70 11.2.4 Grails Plugin ......................................................................................................................................70 11.2.5 Know-How ........................................................................................................................................70 11.3 Konzepte von NOSQL ........................................................................................................................... 70 11.3.1 Schemafreiheit .................................................................................................................................70 11.3.2 CAP Theorem ....................................................................................................................................72 11.3.3 Map/ Reduce ....................................................................................................................................72 11.3.4 Vor- und Nachteile von CouchDB gegenüber relationalen Systemen ..............................................76 11.4 12 Ergebnis ............................................................................................................................................... 77 FAZIT ....................................................................................................................................................... 79 12.1 Fachliches ............................................................................................................................................ 79 12.2 Projektablauf ....................................................................................................................................... 79 12.3 Zielerreichung ...................................................................................................................................... 80 12.4 Persönliches Fazit ................................................................................................................................ 81 13 DANK ...................................................................................................................................................... 83 14 LITERATURVERZEICHNIS ................................................................................................................................ 84 15 GLOSSAR/ TECHNOLOGIEN ........................................................................................................................... 87 16 15.1 Closure ................................................................................................................................................. 87 15.2 Levenshtein-Distanz............................................................................................................................. 87 15.3 JSON ..................................................................................................................................................... 87 15.4 Groovy ................................................................................................................................................. 87 15.5 Grails Webframework.......................................................................................................................... 87 15.6 Canoo Ultra Light Client (ULC) ............................................................................................................. 88 15.7 MySQL .................................................................................................................................................. 88 ANHANG .................................................................................................................................................. 89 16.1 Quelldatenfiles .................................................................................................................................... 89 16.1.1 Gemeindeverzeichnis Rheinland Pfalz .............................................................................................89 16.1.2 EEG-Kraftwerksdaten Rheinland Pfalz ..............................................................................................89 16.1.3 Stromdaten Verbandsgemeinden Rheinland Pfalz ..........................................................................90 16.2 Inhalt der CD ........................................................................................................................................ 91 16.2.1 Arbeit ................................................................................................................................................91 16.2.2 Quelldaten Files ................................................................................................................................91 16.2.3 Gemeindemapping Dateien .............................................................................................................91 16.2.4 Datenbank Output Files....................................................................................................................91 16.2.5 Groovy Skripten ................................................................................................................................91 16.2.6 SQL Skripten .....................................................................................................................................92 1 ABBILDUNGSVERZEICHNIS Abbildung 1, ULCBigTableExplorer........................................................................................................................ 12 Abbildung 2, ULCGeoMaps ................................................................................................................................... 15 Abbildung 3, OpenGeoDB Datenauschnitt ............................................................................................................ 24 Abbildung 4, Datenbankschema ........................................................................................................................... 25 Abbildung 5, Zielformat Gemeindehierarchie ....................................................................................................... 28 Abbildung 6, GORM Klasse GemeindeView .......................................................................................................... 32 Abbildung 7, XML-Response Yahoo Geolokationsservice ..................................................................................... 43 Abbildung 8, Scatter-Plot der Kraftwerks Längen- und Breitengrade ................................................................... 48 Abbildung 9, Karte Rheinland Pfalz ....................................................................................................................... 48 Abbildung 10, Datenauswahl GUI ......................................................................................................................... 51 Abbildung 11, Architektur BigTableDataProvider, (Bräunlich, 2011).................................................................... 52 Abbildung 12, Code: defineStructure-Methode, EEGDataDescriptionGORM....................................................... 53 Abbildung 13, Kategorieanwahl ULCBigTableExplorer ......................................................................................... 66 Abbildung 14, Beispiel CouchDB Dokument im JSON Format .............................................................................. 71 Abbildung 15, Beispiel CouchDB View .................................................................................................................. 73 Abbildung 16, Beispiel Grouping CouchDB ........................................................................................................... 75 Abbildung 17, Beispiel 2 Grouping CouchDB ........................................................................................................ 75 Abbildung 18, Beispiel 3 Grouping CouchDB ........................................................................................................ 76 2 TABELLENVERZEICHNIS Tabelle 1, Regionalschlüssel Beispiel .................................................................................................................... 20 Tabelle 2, Beispiel Kraftwerkstabelle .................................................................................................................... 28 Tabelle 3, zeilenorientierte Speicherung Bewegungsdaten .................................................................................. 29 Tabelle 4, Gemeindemapping Resultate ............................................................................................................... 44 Tabelle 5, Resultate Längen- und Breitengrad Abfragen ...................................................................................... 47 Tabelle 6, Bit-Index BigTableDataProvider............................................................................................................ 55 Tabelle 7, Performanz Indexerstellung ................................................................................................................. 61 Tabelle 8, Auszug Tabelle ULCBigTableExplorer ................................................................................................... 64 viii 3 EINLEITUNG 3.1 AUFTRAGGEBER Canoo Engineering AG in Basel bietet Produkte und Dienstleistungen im Bereich Software. Die beiden Hauptprodukte sind die Canoo RIA Suite mit der leistungsfähige Java-Webapplikationen vollständig in Java realisiert werden können und Software-Tools im Bereich Sprachanalyse. Canoo beschäftigt zurzeit über 40 Softwareentwickler. Viele davon sind aktive Commiter bei Open Source Projekten und Sprecher auf internationalen Konferenzen. 3.2 PROJEKTPARTNER Die ECOSCOP ist eine Gesellschaft für Umweltberatung und -recherche in Trier. Sie ist eine Gründung von Wissenschaftlern, Technikern und Praktikern der unterschiedlichsten Fachbereiche. Der Ansprechpartner für die vorliegende Arbeit war Matthias Gebauer. Die ECOSCOP ist seit ihrer Gründung in den Schwerpunkten "Beratung & Planung von kleinen Energieanlagen", "Umweltberatung", "Weiterbildung und Knowhow-Transfer" und "Umwelt und Informatik" tätig. 3.3 HINTERGRUND In Deutschland besteht eine Einspeisevergütung für alternative Energie (EEG). Das Einspeisen von Strom, aus zum Beispiel einer Solaranlage, wird von der öffentlichen Hand subventioniert. Von der Politik werden Zielvorgaben gemacht und diese überprüft. In gewissen Zeitabständen wird also eruiert, wie sich diese Einspeisevergütung auswirkt. Insbesondere soll natürlich der Anteil von alternativer Energie erhöht werden. Zwischen den Kommunen wird ausserdem ein Benchmarking durchgeführt. Im Moment besteht kein Standard wie solche Energiebilanzen zu erstellen sind. Die Vergleichbarkeit ist dadurch schwierig. Bei den vorhandenen Tools am Markt besteht insbesondere die Schwierigkeit, dass die Verarbeitungsschritte der Systeme nicht transparent sind. Canoo und ECOSCOP möchten ein Tool entwickeln, dass den Anforderungen dieser Domäne gerecht wird. 9 3.4 AUSGANGSLAGE Die RIA Suite von Canoo erlaubt es Rich Internet Applications (RIAs) vollständig in Java zu realisieren. Dabei steht den Entwicklern ein reichhaltiges Set von GUI-Komponenten zur Verfügung. Im Canoo RIALab werden Prototypen von neuen Komponenten entwickelt. Der ULCBigTableExplorer und die ULCGeoMaps sind ein Resultat dieser Arbeit. Die Komponenten sollen die Möglichkeit bieten grosse Datenmengen auf eine möglichst einfache Art zu analysieren. Ein Anwendungsentwickler soll die Komponenten möglichst einfach in Applikationen integrieren können. Um dieses Ziel zu unterstützen wurde eine gemeinsame Datenanbindungsschicht implementiert. 3.5 PROBLEMSTELLUNG Die ULCGeoMaps-Komponente wurde bereits einmal erfolgreich in einem Kundenprojekt eingesetzt. Der BigTableExplorer nicht. Dieser befindet sich noch stärker in Entwicklung. Die Praxistauglichkeit der beiden Komponenten, insbesondere des ULCBigTableExplorers wurde bisher nicht getestet. Die Komponenten arbeiten zur Zeit nur mit CSV-Files. Wie gut sich die Komponenten zusammen mit einer Datenbank nutzen lassen, ist noch unklar. Die gemeinsame Datenanbindungsschicht ist noch neu und ebenfalls nicht ausgiebig getestet. 3.6 ZIELSETZUNG Das Ziel der vorliegenden Arbeit ist es, die Daten des Projektpartners zu intergieren und mit dem Einsatz der neuen Komponenten der Canoo RIA Suite, auswertbar zu machen. Dazu werden die Daten in einer Datenbank integriert und ein Prototyp entwickelt. Als Integrationsbasis soll das Grails Webframework Verwendung finden. 3.7 NUTZEN Der Projektpartner erhält einen Prototyp mit dem er erste Analysen seiner Daten vornehmen kann. Die darunterliegende integrierte Datenbasis kann er auch unabhängig von den Tools weiterverwenden. Canoo erhält ein Proof of Concept für seine neuen Komponenten. Eine vollständige Bewertung ist im Rahmen dieser Arbeit aus zeitlichen Gründen nicht möglich. Erwartet werden dürfen aber insbesondere Antworten auf die folgenden Fragen: Wie gut integrieren die Komponenten mit einer Datenbank? Wie leicht lassen sich die Komponenten ins Grails Webframework integrieren? 10 Wie stabil laufen die Komponenten? Welche Fehler wurden identifiziert? Wie performant läuft die Applikation mit den bestehenden "real world" Daten? Welche zusätzlichen Anforderungen an die Funktionalität und die Programmierschnittstelle können aus der Arbeit hergeleitet werden? 3.8 VORGEHEN Es wurde grob in drei Phasen vorgegangen. Zuerst wurden die Daten integriert, danach der Prototyp entwickelt und anschliessend das Projekt dokumentiert. Die Datenintegration unterteilte sich in die Phasen: Datenanalyse Datenintegration Datenanreicherung Überprüfung Datenqualität Danach wurde auch ein Grails Domänenmodell/ Datenbankschema entworfen und die Daten in die Datenbank geladen. Die Prototyperstellung unterteilte sich in die Phasen: Datenanbindungsschicht und Datendefinitionen implementieren Integration der Komponenten mit Grails Datenbank Views erstellen und anbinden Entwicklung eines Datenauswahl GUIs Bug Fixing Testing/ Profiling und Optimierung des Prototypen Deployment Während allen Phasen des Projekts wurde fortlaufend dokumentiert. Anschliessend erfolgte die Konsolidierung der Entwürfe in diesen Bericht. 11 4 KOMPONENTEN 4.1 ULCBIGTABLEEXPLORER Der ULCBigTableExplorer wurde von Dieter Holz und Franz-Josef Wiszniewsky entwickelt. Abbildung 1, ULCBigTableExplorer 4.1.1 FUNKTIONALITÄT Der ULCBigTableExplorer soll eine möglichst einfache mehrdimensionale Auswertung von tabellarischen Daten ermöglichen. Die Komponente hat drei Darstellungsbereiche: Die KategorieAnsicht, die Tabelle mit den Quelldatensätzen und eine Chart-Ansicht. Es können, wie in Abbildung 1 ersichtlich, mehrere Kategoriepanels eingeblendet werden. Das Einblenden macht aber natürlich nur Sinn, wenn für die entsprechenden Spalten auch Kategorien definiert wurden. Die Panels können ihre Position jeweils mit dem Nachbarpanel tauschen. Die Anwahl einer oder mehrerer Kategorien wirkt als Filter auf die Datensätze in der Tabelle und die Chart-Anzeige. Die Filter werden UND-verknüpft. Die Kategorieanwahl in Abbildung 1führt also dazu, 12 dass in der Tabelle nur die Wasser-, Wind- und Biomassekraftwerke, die im Jahr 2005 oder 2007 in Betrieb genommen wurden, angezeigt werden. Die Zahl hinter der dem Kategorienamen, wie zum Beispiel WAS (11), zeigt wie viele Datensätze nach der Filterung noch vorliegen. In den Jahren 2007 und 2005 sind also 11 Wasserkraftwerke in Betrieb gegangen. Pro Kraftwerk liegt in den Quelldaten jeweils eine Zeile vor. Im Moment kann die Komponente Säulen-, Kuchen-, Linien- und XY-Diagramme darstellen. Sie wählt aufgrund der Kategorieanwahl jeweils eine geeignete Darstellung. Eine manuelle Anwahl ist ebenso möglich. Nicht jeder Diagrammtyp ist aber sinnvoll. In Abbildung 1 ist auf der X-Achse die Anzahl der Kraftwerke aufgetragen, auf der Y-Achse liegen die Jahre und die Farben kennzeichnen den Kraftwerkstyp. Beim Anwählen einer Säule werden die entsprechenden Datensätze in der Tabelle markiert. Die Komponente hat ausserdem eine Suchfunktionalität. 4.1.2 THEORETISCHE EINORDNUNG Übersichtstabellen entstehen nach (Reber, Analyseprozesse in Datawarehouses, 2011) durch Filterung und Aufsummierung (Aggregation) von Detaildaten. Ersteres erlaubt das vorliegende Tool. Die Aggregation der Daten ist in der Architektur der Komponenten vorgesehen, aber noch nicht im GUI umgesetzt. Es stellt sich die Frage, welche Aspekte eines OLAP (Online Analytical Processing) Tools der ULCBigTableExplorer bereits abdeckt. Nach (Reber, Analyseprozesse in Datawarehouses, 2011) sind OLAP Tools: "mehrdimensional, weil es ... o endbenutzerfreundlich, weil es ... o direkte Manipulation ermöglicht o Ergebnisse einfach darstellt, insbesondere visualisiert detaillierend und zusammenfassend, weil ... o Daten übersichtlich zusammengefasst und nur auf Verlangen detailliert o Drilling Up and Down navigiert entlang einer Dimension analysierend und synthetisierend, weil ... o der Benutzer Dimensionen einfach hinzufügen und weglassen kann schnell, weil es ... o 13 Indikatoren nach ihren Dimensionen analysiert ad hoc-Abfragen in Sekunden beantwortet o aufwendige ad-hoc-Berechnungen durch Voraggregation vermeidet Data Mart - orientiert, weil es ... o weniger Details als das zentrale EDW unterstützt" Der ULCBigTableExplorer ermöglicht mehrdimensionale Auswertungen, nach vordefinierten Kategorien. Die Auswertungsdimensionen können schnell gewechselt werden, dass heisst es ist analysierend und synthetisierend. Auch die Benutzerfreundlichkeit ist hoch. Eine Analyse ist sehr einfach. Detaillieren und Zusammenfassen kann das Tool, wie gesagt, noch nicht. Das heisst ein Drill Down and Drill Up, also das Zusammenfassen oder Detaillieren entlang einer Dimension (Reber, Analyseprozesse in Datawarehouses, 2011), ist noch nicht möglich. Durch einen optimierten Index soll das Tool auch schnelle Antwortzeiten bieten. Typisch für ein Data Warehouse ist die Unterscheidung von Fakten (Indikatoren) also einem betriebswirtschaftlicher Erfolgsfaktor und Dimensionen, also den Kriterien seiner Beurteilung (Reber, Modellierung von Datawarehouses, 2010). Die Dimensionen sind beim ULCBigTableExplorer die Kategorien nach denen gefiltert wird. Was aber sind die Fakten? Im Moment sind die Fakten die Kraftwerke die nach der Filterung noch vorhanden sind und insbesondere deren Anzahl. So können Fragen wie: Wie viele Solarstromkraftwerke wurden zwischen 2005 und 2010 in Trier in Betrieb genommen, leicht beantwortet werden. Für die Frage aber wie viel Energieertrag in kWh die Kraftwerke in diesen Jahren geliefert haben, ist dies noch nicht direkt möglich. 14 4.2 ULCGEOMAPS Die ULCGeoMaps wurde von Michael Faes und Christoph Bräunlich entwickelt. Abbildung 2, ULCGeoMaps 4.2.1 FUNKTIONALITÄT Die ULCGeoMaps ermöglicht eine Auswertung von aggregierten Daten bezüglich der Dimension Raum. Für jede geographische bzw. administrative Einheit werden in einem Tooltip alle vorhandenen aggregierten Werte angezeigt, sobald sich der Mauszeiger über dem Gebiet befindet. Im "Data 15 Analyzer" Menü wird eine Datenart angewählt, in unserem Fall Leistung der Kraftwerke in kW. Die Polygonzüge, die über der Karte liegen, werden dadurch nach den Kategorien in der Legende eingefärbt. Durch einen langen Klick auf einen Polygonzug kann in dieses Gebiet hinein navigiert werden. Daraufhin werden die geographisch darunter liegende Einheiten angezeigt. Es können auch mehrere Polygonzüge miteinander kombiniert werden. Die tiefste Navigationsebene ist die einzelne Adresse. In unserem Fall ist somit das Einzeichnen von einzelnen Kraftwerken möglich. 4.2.2 THEORETISCHE EINORDNUNG Die Fakten sind, im Fall der ULCGeoMaps, die aggregierten Werte. Zum Beispiel der Energieertrag in kWh. Diese werden nach der Dimension Raum ausgewertet. Eine Grundfunktionalität ist der DrillDown und Drill-Up. Es kann in die einzelnen Raumgrenzen hinein und wieder heraus gesprungen werden. Die Daten werden dadurch auf verschiedenen geographischen Hierarchiestufen (Bundesland, Regierungsbezirk, Landkreis, …) auswertbar. Bei (Martin Theus, 2009) wird dieser Art der Visualisierung auch ein Name gegeben. "The most common way to display geographically referenced data ist choropleth maps. Even if a finer resolution for the geographical location of the items can be given, the interest lies mostly in the aggregated data represented by administrative entities such as ZIP-code areas *…+." (Martin Theus, 2009). Der deutsche Begriff wäre laut Wörterbuch: Flächenkartogramm. 16 5 DATENANALYSE Die verarbeiteten Daten sind alle aus Deutschland. Zusammen mit dem Projektpartner wurde entschieden nur die Daten vom Bundesamt Rheinland Pfalz zu verwenden. Alle Daten lagen in Form von Excel Files vor. 5.1 VORGEHEN Zuerst wurden die bereits vorhanden Datenfiles gesichtet. Es zeigte sich, dass die gleichen Daten jeweils von verschiedenen Quellen vorhanden waren. Andere Daten waren zu Beginn der Arbeit noch nicht vorhanden oder in einer Form, die nicht für die Verarbeitung geeignet schien. Mit dem Projektpartner wurde abgegrenzt welche Daten analysiert und integriert werden sollten. Der Stromdatensatz und der EEG-Kraftwerksdatensatz wurden vom Projektpartner vorverarbeitet. 5.2 WAS WURDE ANALYSIERT? Folgende Fragen wurden während der Datenanalyse gestellt: Gibt es einen eindeutigen Schlüssel der den jeweiligen Datensatz eindeutig identifiziert oder können mehrere Attributwerte zu einem Schlüssel kombiniert werden? Welche Skalenniveaus sind vorhanden (nominal, ordinal, numerisch)? Dies ist insbesondere wichtig, um die Darstellung der Kategorien im ULCBigTableExplorer zu modellieren. Bei ordinalen Werten ist die Reihenfolge in der die Kategorien im GUI angezeigt werden zum Beispiel relevant, während dessen dies bei nominalen Werten nicht der Fall ist. Welche Datentypen sind vorhanden? Die entsprechenden Datentypen werden auch in der Datenbank verwendet. Gibt es abhängige Spaltenwerte, das heisst Werte die von anderen Spaltenwerten abhängen? Dies ist für die Modellierung des Schemas relevant. Sind die Daten vollständig vorhanden? Es muss auf Datenbank- und Applikationsebene entschieden werden, wie mit Leerwerten umgegangen wird. 17 Wie ist die syntaktische Variabilität der Spaltenwerte? Werden zum Beispiel Adressinformationen immer gleich angegeben oder gibt es Varianten? Dies ist insbesondere für die Verarbeitung der Daten relevant. Die Importskripten müssen diese Unterschiede kennen. Sind zusammengesetzte Spaltenwerte vorhanden oder sind alles atomare Werte? Dies ist für die Modellierung des Schemas relevant. Zum Beispiel muss geklärt werden, ob zusammengesetzte Werte aufgetrennt werden sollen. Können aus Spaltenwerten fachliche Informationen herausgelesen werden? Welche Informationen sind zum Beispiel in einem Schlüssel codiert? Wie sind temporale Informationen angegeben? Die Importskripten müssen diese Syntax kennen. Welche Metadaten sind vorhanden? In welcher Zeichencodierung sind die Daten zum Beispiel gespeichert. 18 5.3 DATEN 5.3.1 GEMEINDEDATEN RHEINLAND PFALZ Siehe auch im Anhang 16.1.1 Vom deutschen statistischen Bundesamt wurden Gemeindedatensätze bezogen. Diese enthalten die Gemeindedaten aller Gemeinden in Deutschland. Die folgenden Daten sind für die Arbeit relevant: Satzart Gemeindename Regionalschlüssel Fläche in km2 Bevölkerungszahlen Postleitzahl Die Satzart beschreibt die Hierarchiestufe auf der die entsprechende geographische Entität steht. Im Originalfile sind die folgenden Stufen angegeben: 10 = Bundesland 20 = Regierungsbezirk 30 = Region (nur in Baden Württemberg) 40 = Landkreis 50 = Verbandsgemeinde 60 = Gemeinde Die Analyse der Daten ergab, dass nicht alle Bundesländer einen Regierungsbezirk haben. Es kann aber in einem Bundesland verschiedene Regierungsbezirke geben. In Rheinland Pfalz sind es deren drei. Die Satzart 30 bezieht sich nur auf ein Bundesland und ist in unserem Fall irrelevant. Eine Stufe tiefer sind die Landkreise. Im Datensatz ist ersichtlich, dass nicht alle Gemeinden in einem Landkreis sind. Es gibt kreisfreie Städte wie zum Beispiel Koblenz. Es sind auch nicht alle Gemeinden in einer Verbandsgemeinde. Die Gemeinden sind die unterste Stufe der Hierarchie. Es sind keine Daten zu den Gemeinde- und Stadtteilen vorhanden. Der Gemeindename ist der Bezeichner der geographischen Entität, also zum Beispiel " RheinlandPfalz", "Sinzig, Stadt" oder "Koblenz, kreisfreie Stadt". Für unseren Zweck sind vor allem die Gemeindenamen auf der Stufe Gemeinde relevant. 19 Beispiele: Berod bei Hachenburg Steinebach/ Sieg Altenkirchen (Westerwald), Stadt Rosenheim (Landkreis Altenkirchen) Sonnenberg-Winnenberg Es gibt zusammengesetzte Gemeindenamen bei nicht eindeutigen Namen (a + b), Zusätze wie "Stadt" oder "Landkreis" (c, d) und Doppelnamen (e). Der Regionalschlüssel ist eine, auf Gemeindeebene, zwölfstellige Zahl. Diese identifiziert die Gemeinde eindeutig. Der Regionalschlüssel löst den älteren achtstelligen Gemeindeschlüssel ab. Beide Schlüssel sind noch in Gebrauch (Wikipedia, Amtlicher Gemeindeschlüssel, 2011). Beispiel: 07 2 31 0134 134 Wittlich, Stadt Tabelle 1, Regionalschlüssel Beispiel Die Ziffern 1-2 identifizieren das Bundesland. Die Ziffern 3-5 identifizieren den Landkreis bzw. die kreisfreien Städte. Ziffer 3 ist der Regierungsbezirk oder ehemalige Regierungsbezirk oder 0 bei den Gemeinden ohne Regierungsbezirk. In Baden-Württemberg zeigt die vierte Ziffer außerdem an, zu welchem Regionalverband die Gemeinde gehört. Die Ziffern 1-5 werden als Kreisschlüssel bezeichnet. Die Ziffern 6-9 identifizieren den Gemeindeverband. Seit dem 1. Januar 2009 wird die Ziffernfolge 0000 für verbandsfreie Gemeinden durch 0, gefolgt von einer Wiederholung der Stellen 10 bis 12 ersetzt. An der ersten Stelle steht bei verbandsangehöriger Gemeinden die Zahl 5 bei verbandsfreien Gemeinden die Zahl 0 und bei gemeindefreien Gebieten die Zahl 9. Die Ziffern 10 bis 12 identifizieren die Gemeinde (Wikipedia, Amtlicher Gemeindeschlüssel, 2011). Die Fläche in km2 und die Bevölkerungsinformationen sind auf Gemeindestufe vorhanden. Die Aggregationen für die darüber liegenden geographischen Entitäten, sind nicht im Datensatz. Für jede Gemeinde ist eine Postleitzahl angegeben. Bei Gemeinden, die mehrere Postleitzahlen haben, wird jeweils nur diejenige des Verwaltungssitzes angegeben (Angabe im Quelldatenfile). 20 5.3.2 EEG-KRAFTWERKSDATEN RHEINLAND PFALZ Siehe auch im Anhang 16.1.2 Der Datensatz enthält Daten zu Kraftwerken die eine Einspeisevergütung enthalten (EEG). Es liegen 48667 Zeilen vor. Die folgenden Daten sind für die Arbeit relevant: Strasse Postleitzahl Ort Leistung in kW Energieträger INB_Datum Ertrag in kWh Vergütung in Euro In der Spalte Strasse stehen die Strassennamen der jeweiligen Kraftwerke und eine oder mehrere Hausnummern. Dabei ist die Abtrennung der Hausnummer unterschiedlich. Auch gibt es Teilweise Zusätze wie "Schulhaus" und dergleichen. Es gibt auch Zeilen die die identische Strasseninformation haben. Diese Datensätze unterscheiden sich teilweise nur durch den Anlagenschlüssel, dieser ist das Identifikationsmerkmal. Beispiele: Batterieweg 103 / Blumenberg 33 / 1641B 195/50 Calmuth 7 (Schloss Calmuth) / Pastor-Keller-Straße 192 Z (Sporthalle) / Grüner Weg 3a / 224/16 Vorderste Berg / Flurstück( 114 ) Am Tränkwald 21 Flurstück 740_82 Breitwiesenstr. 1a und 1b 2 Hallen auf Parzelle 24/1 / Bei allen Zeilen des Files gibt es einen Eintrag in der Spalte Strasse. Bei 42 Datensätzen sind aber nur die Hausnummern vorhanden. 21 Es gibt anzumerken, dass bei ca. 10 Prozent der Datensätze schon Längen- und Breitengrade vorhanden sind. Diese wurden nicht weiter berücksichtigt, da diese Information für alle Datensätze benötigt wird und auf anderem Weg beschaffen werden soll. Eine Spalte enthält die Postleitzahlen. Die Gemeinden haben jeweils mehrere Kraftwerke und damit kommen die Postleitzahlen mehrfach vor. Eine einzelne Gemeinde kann auch verschiedene Postleitzahlen haben. Zudem kann eine Postleitzahl von verschiedenen Gemeinden verwendet werden. Die Postleitzahlen sind vollständig vorhanden. Die Spalte Ort enthält die Gemeindenamen. Bei einer Zeile gibt es keinen Eintrag und eine Zeile enthält nur einen Schrägstrich. Einige Gemeindenamen enthalten hinter dem Namen eine Nummer wie zum Beispiel: "Bad Neuenahr-Ahrweiler / 13" oder Zusätze wie zum Beispiel: "Meisenheim / Auf der Lettweiler Höhe". Einige nur einen Schrägstrich. In der Spalte Leistung steht die Leistung der einzelnen Kraftwerke in kW. Ein Datensatz enthält keine Informationen und ein anderer 0. Alle anderen haben einen Eintrag in Form einer Gleitkommazahl. Diese hat höchstens drei Nachkommastellen. Die Spalte Energieträger beschreibt die Art des Kraftwerks. Es gibt im gesamten Datensatz sieben verschiedene Werte. Diese sind: BIO, DEP, GEO, KLA, SOL, WAS, WIN. Es handelt sich um Abkürzungen. SOL steht zum Beispiel für Solarstrom. Der Energieträger ist für alle Zeilen vorhanden. Die Spalte INB_Datum enthält das Inbetriebnahmedatum des Kraftwerks. Drei Zeilen enthalten hier keinen Datumswert. Die Spalte Ertrag in kWh enthält die kWh, die in einem Jahr von dem entsprechenden Kraftwerk geliefert wurden, als Ganzzahl. Das Jahr, auf das sich diese Zahlen beziehen, ist nicht im Datensatz ersichtlich, wurde aber in den Metadaten mitgeliefert. 14866 Zeilen enthalten keinen Eintrag. 317 Zeilen haben den Eintrag 0. Die Spalte Vergütung in Euro enthält den Geldbetrag, der als Einspeisevergütung bezahlt wurde. Das Jahr, auf das sich diese Zahlen beziehen, ist nicht im Datensatz ersichtlich, wurde aber als Metadaten mitgeliefert. 14866 Zeilen enthalten keinen Eintrag. Dies sind die gleichen Zeilen, die auch beim Ertrag keinen Wert haben. 310 Zeilen haben den Eintrag 0. Auch hier sind es, mit zwei Ausnahmen, die Datensätze, bei denen auch beim Ertrag eine 0 steht. 22 5.3.3 STROMDATEN VERBANDSGEMEINDEN RHEINLAND PFALZ Siehe auch Anhang 16.1.3 Das File enthält die Strom Verbrauchsdaten für die Verbandsgemeinden in Rheinland Pfalz. Laut Aussage des Projektpartners sind nicht alle Verbandsgemeinden enthalten. Die folgenden Daten sind enthalten: VGSchlüssel VG Nutzergruppe Verbrauch 2007 in kWh Die Spalte VGSchlüssel enthält einen eindeutigen Schlüssel der die Verbandsgemeinde identifiziert. Es handelt sich dabei um die letzten fünf Ziffern des Gemeindeschlüssels, der schon im Abschnitt 5.3.1 beschrieben wurde. Die Spalte VG enthält den Namen der Verbandsgemeinde. Die Angaben sind vollständig. Die Spalte Nutzergruppe beschreibt die Art der Nutzergruppe. Die vorkommenden Werte sind: Industrie u. Gewerbe > 30kW u. 30.000 kWh p.a., Wärmespeicher, Wärmepumpe, Haushalte, Gewerbe < 30kW und 30.000 kWh p.a., Landwirtschaft. Die Angaben sind vollständig. Die Spalte Verbrauch 2007 in kWh enthält die aufsummierten Stromverbräuche in kWh pro Verbandsgemeinde als Ganzzahl. Die Angaben sind vollständig. Es gibt anzumerken, dass der gleiche Schlüssel (VGSchlüssel) mit dem gleichen Verbandsgemeindename (VG) jeweils für jede Nutzergruppe vorkommt, dass heisst redundant. 23 5.3.4 OPEN GEO DB DATENBANK "Im Mittelpunkt des Projektes OpenGeoDB steht der Aufbau einer möglichst vollständigen Datenbank mit Geokoordinaten zu allen Orten und Postleitzahlen (bisher: A,B,CH,D und FL). Dies soll vor allem durch die Beteiligung von möglichst vielen Personen geschehen, die diese zentrale Datenbank pflegen" (OpenGeoDB, 2011). Die Daten der OpenGeoDB werden von freiwilligen gesammelt und gepflegt. Dadurch haben sie keinen offiziellen Charakter und können uns ausschliesslich als Referenz dienen. Die Nachvollziehbarkeit ist ein zentrales Kriterium unseres Projektpartners. Diese ist hier nicht gewährleistet. Es ist nicht klar wer die Daten erfasst und nach welchen Verfahren bearbeitet hat. Abbildung 3, OpenGeoDB Datenauschnitt 24 6 DATENBANKSCHEMA Abbildung 4, Datenbankschema 25 6.1 BESCHREIBUNG 6.1.1 GEOGRAPHISCHE ENTITÄTEN Die Tabellen staat, bundesland, regierungsbezirk, landkreis, gemeindeverband, gemeinde enthalten Informationen zu geographischen bzw. administrativen Entitäten. Es handelt sich jeweils um eine 1:n Beziehung. 6.1.2 TABELLE KRAFTWERK Diese Tabelle enthält die Stamm- und Bewegungsdaten der einzelnen Kraftwerke. Warum diese beiden Datenarten in einer Tabelle gemischt sind, erläutert der Abschnitt 6.1.9. Es sind drei Fremdschlüssel auf die Metainformationen vorhanden und ein Fremdschlüssel auf die Gemeinde. 6.1.3 TABELLE GEMEINDEDATEN Diese Tabelle enthält zusätzliche Daten zu der Gemeinde. Im Moment sind dies Bevölkerungs- und Flächendaten. 6.1.4 TABELLE GEMEINDEVERBANDSDATEN Die Tabelle enthält zusätzliche Daten zu dem Gemeindeverband. Im Moment sind dies Stromverbrauchsdaten. 6.1.5 TABELLEN META_INFO/ META_INFO_MAPPER Die Tabelle Meta_Info enthält die Metainformationen zu den Daten. Es besteht eine 1:n Beziehung zu den Tupeln der Meta_Info_Mapper Tabelle. Diese enthält das Referenz- sowie Importdatum der Daten und hat eine 1:n Beziehung zu allen anderen Tabellen, ausser den Hilfstabellen. Die Metadaten eines Datenfiles werden also in der Meta_Info Tabelle gespeichert. Da aber die einzelnen Spalten der Importfiles teilweise unterschiedliche Referenzdatumswerte ausweisen, muss über die Zwischentabelle Meta_Info_Mapper verküpft werden. 6.1.6 TABELLE MAPPING _HELPER Diese Tabelle enthält Informationen zu dem Gemeindemapping. Teilweise wurden die Kraftwerksdaten manuell zu den Gemeindedaten gemappt oder durch eine Heuristik zugeordnet. Die Resultate dieser Zuordnungen sind in dieser Tabelle hinterlegt und können in Zukunft genutzt werden, um die Kraftwerksdatensätze einfacher zuzuordnen. 26 6.1.7 TABELLE OPEN_GEODB Diese Tabelle enthält ebenfalls Informationen zu geographischen Entitäten, aus dem OpenGeoDB Projekt (OpenGeoDB, 2011). Die Daten werden als Hilfsmittel bei dem Gemeindemapping (siehe 8.1) verwendet. 6.1.8 ABBILDUNG DER GEMEINDEHIERARCHIE Es bestehen unterschiedliche Formen hierarchische Daten in einem relationalen Datenbanksystem abzubilden. In den Gemeindequelldaten (siehe 5.3.1) ist die ganze Hierarchie in einer Tabelle gespeichert. Über den Regionalschlüssel ist es möglich alle Vaterelemente zu bestimmen. Für die Gemeinde 07 1 31 5001 001 Adenau, Stadt ist zum Beispiel ersichtlich, dass sie in der Verbandsgemeinde mit dem Regionalschlüssel 07 1 31 5001 Adenau liegt und im Landkreis mit dem Regionalschlüssel 07 1 31 Ahrweiler Die Gemeindedaten hätten exakt so in einer Datenbanktabelle gespeichert werden können. Falls die einzelnen Teile des Regionalschlüssels in einzelnen Spalten gespeichert worden wären, hätten einfach Abfragen gemacht werden können. Zum Beispiel welche Gemeinden im Landkreis "Ahrweiler" liegen. Alternativ hätte eine Tabelle nach dem "Adjazenz List Modell" aufgebaut werden können. Dabei hätte jeder Tupel, ausser dem Wurzelknoten, in einer Spalte "parent", jeweils eine Referenz auf den Tupel des Vaterelements (Fürst, 2006). Diese Art der Speicherung erachte ich als sinnvoll, wenn häufig neue Knoten auf zusätzlichen Hierarchiestufen dazukommen. Diese können einfach hinzugefügt werden. Die Abfragen sind aber aufwendig. Die Anzahl der Hierarchiestufen ist in unserem Fall stabil. Der Gemeindedatensatz beinhaltet auch für jeden Eintrag einen direkten Vorgänger. Es wurde entschieden, für jede Stufe eine Tabelle anzulegen. Jeder Gemeindeeintrag hat somit genau fünf Hierarchiestufen über sich. Der Vorteil dieser Abbildung ist insbesondere, dass die von der Komponente benötigte tabellarische Ansicht der 27 Daten leicht erzeugt werden kann. Die Informationen zu den geographischen Entitäten sollen wie folgt vorliegen: Abbildung 5, Zielformat Gemeindehierarchie Mit der gewählten Modellierung können die Hierarchiestufen, mittels einfachen Joins, in einem View zusammengeführt werden. Ein Vorteil ist ebenfalls, dass die Hierarchiestufen im Schema ersichtlich sind. Die Möglichkeit die Daten direkt in einer Tabelle abzuspeichern, die dem obigen View entspricht, wurde aufgrund der damit entstehenden Redundanzen vermieden. Bei Problemen mit der Performanz, kann das Resultat einer Abfrage des Views, auch in einer temporären Tabelle gespeichert werden. 6.1.9 TRENNUNG STAMM- UND BEWEGUNGSDATEN Die Quelldaten enthalten verschiedene Datensätze, die sich auf ein bestimmtes Datum oder Jahr beziehen, also Bewegungsdaten. Als Bespiel sollen die Ertragsdaten der Kraftwerke dienen. Für jedes Kraftwerk ist in der Spalte "Ertrag in kWh" die gelieferte Energie, eines in den Metadaten bestimmten Jahres, enthalten. Im ULCBigTableExplorer sollen die Erträge wie folgt dargestellt werden: Kraftwerksadresse Ort Ertrag in kWh 2009 Ertrag in kWh 2010 Tabelle 2, Beispiel Kraftwerkstabelle Kraftwerksadresse und Ort sind die Stammdaten und die Erträge die Bewegungsdaten. Jedes Jahr kommt eine neue Spalte hinzu. Es ist anzumerken, dass die Stammdaten nicht verändert werden, dass heisst es findet keine Stammdatenpflege statt. Des Weiteren werden die Daten in der Form wie sie auch in der Komponente angezeigt werden, geliefert. Natürlich jeweils nur für ein Jahr. Die folgenden Optionen waren denkbar: Stamm- und Bewegungsdaten in einer Tabelle. Die Tabelle entspricht genau der Ansicht in der Komponente und ebenfalls der Struktur des angelieferten Files. Jedes Jahr müsste die Datenbanktabelle um eine Spalte ergänzt werden. Vertikale Partitionierung. Die Ertragsdaten würden in eine separate Tabelle ausgelagert und diese jedes Jahr um eine Spalte ergänzt. 28 Spaltenorientierte Jahrestabellen. Die Bewegungsdaten würden pro Jahr in eine Tabelle ausgelagert. Jedes Jahr würde eine neue Tabelle erzeugt. Zeilenorientierte Tabelle für die Bewegungsdaten. Für jedes Kraftwerk werden die Bewegungsdaten zeilenorientiert gespeichert. Im nächsten Jahr müsste lediglich eine neue Zeile hinzugefügt werden. fk_kraftwerk Jahr Ertrag … Tabelle 3, zeilenorientierte Speicherung Bewegungsdaten Die Begründung für eine Variante soll nach dem Ausschlussverfahren erfolgen. Die Option d. wäre die offensichtlichste Variante. Bei dieser Variante müssen keine strukturellen Änderungen an der Tabelle vorgenommen werden. Im ursprünglichen Entwurf des Schemas wurde diese Option gewählt. Zu Beginn des Projekts war aber noch nicht klar, wie die Bewegungsdaten im ULCBigTableExplorer dargestellt werden sollen. Die spaltenorientierte Darstellung (Tabelle 2) die gewählt wurde, kommt einer zeilenorientierten Speicherung der Bewegungsdaten nicht entgegen. Ein SQL Statement, das die Ertrags- und Vergütungsdaten spaltenorientiert in einem View konsolidiert, könnte wie folgt aussehen: SELECT k.adresse, g.name, gv.name as gemeindeverband, lk.name as landkreis, rb.name as regierungsbezirk, ertVerg.ertrag2009, ertVerg.ertrag2010, ertVerg.ertrag2011, ertVerg.verguetung2009, ertVerg.verguetung2010, ertVerg.verguetung2011 FROM kraftwerk k, gemeinde g, gemeindeverband gv, landkreis lk, regierungsbezirk rb, ( SELECT ev.fk_kraftwerk as kraftwerk, ev2009.ertrag_kwh as ertrag2009, ev2010.ertrag_kwh as ertrag2010, ev2011.ertrag_kwh as ertrag2011, ev2009.verguetung_euro as verguetung2009, ev2010.verguetung_euro as verguetung2010, ev2011.verguetung_euro as verguetung2011 FROM ertrag_verguetung ev INNER JOIN ertrag_verguetung ev2009 ON ev.fk_kraftwerk = ev2009.fk_kraftwerk AND ev2009.jahr = 2009 INNER JOIN ertrag_verguetung ev2010 ON ev.fk_kraftwerk = ev2010.fk_kraftwerk AND ev2010.jahr = 2010 29 INNER JOIN ertrag_verguetung ev2011 ON ev.fk_kraftwerk = ev2011.fk_kraftwerk AND ev2011.jahr = 2011 GROUP BY ev.fk_kraftwerk ) as ertVerg WHERE k.id = ertVerg.kraftwerk AND g.id = k.gemeinde_id AND g.gemeindeverband_id = gv.id AND gv.landkreis_id = lk.id AND lk.regierungsbezirk_id = rb.id; Das Problem einer solchen Anfrage ist sofort ersichtlich. Sie ist kompliziert, sicherlich langsam und muss jedes Jahr abgeändert werden. Der Preis den man für diese Modellierung bezahlt ist zu hoch, insbesondere um nur ein 'alter table' Statement zu vermeiden. Es gibt auch zu erwähnen, dass das Grails Domänenobjekt das der konsolidierten Datenbanktabelle entspricht, auch jedes Jahr abgeändert werden müsste, unabhängig davon in welcher Form die Bewegungsdaten vorliegen. Des Weiteren ist es sehr wahrscheinlich, dass zukünftig weitere Spalten mit neuen Informationen zu den Kraftwerken vorhanden sind. Eine zeilenorientierte Tabelle müsste daher auch um eine Spalte ergänzt werden. Die Möglichkeit die Spalten erst auf der Applikationsebene zu bilden würde das Problem zwar lösen, aber es wären keine flexiblen Voraggregationen möglich (siehe 6.1.10). Es wurde entschieden die Stamm- und Bewegungsdaten in einer Tabelle zu speichern, dass heisst in der Form in der sie bereits im angelieferten File vorliegen und wie sie vom ULCBigTableExplorer benötigt werden (Option a.). Wenn neue Daten dazukommen wird die Tabelle um eine Spalte erweitert. Der Vorteil dieser Option ist auch der vereinfachte Import der Daten, durch die Entsprechungen in der Struktur. Die Optionen b. und c. bieten keine Vorteile gegenüber Option a. und wurden nicht weiter in Betracht gezogen. Eine Schwierigkeit ergibt sich bezüglich der Metainformationen, zum Beispiel dem Dateinamen. Diese sind in der Tabelle meta_info gespeichert und über die Tabelle meta_info_mapper mit den Datensätzen verknüpft. Diese Metadaten beziehen sich jeweils auf einen Tupel der Stammdaten bzw. einer Spalte der Bewegungsdaten, zum Beispiel auf die Spalte Ertrag2009. Es wurde entschieden den Spalten mit den Bewegungsdaten jeweils eine Spalte für den Fremdschlüssel auf die Metainformationen hinzufügen. Die Spalten Ertrag2009 und Verguetung2009 hätten zum Beispiel eine Spalte fk_ev2009_meta_info_mapper, die auf den entsprechenden meta_info_mapper Tupel referenziert. 30 6.1.10 DATENBANK VIEWS Es wurde entschieden für die Analysen verschiedene Datenbank Views zu erstellen. Damit kann schon von der Datenbank her, die benötigte tabellarische Ansicht erzeugt werden. Auch ist es möglich schon Voraggregation zu machen. Es sind drei Views vorhanden: KraftwerksView Dieser View ist auf Kraftwerksebene. Es handelt sich um einen virtuellen View, das heisst das DBMS erzeugt im Hintergrund die entsprechenden Abfragen. Es gibt keine Aggregation da die Kraftwerksdaten die unterste Ebene sind. GemeindeView Dieser View ist auf Gemeindeebene. Es handelt sich um einen materialisierten View. Weil MySQL dieses Konzept nicht unterstützt wurde einfach eine zusätzliche Tabelle gefüllt. Bei neuen Daten muss diese wieder aktualisiert werden. Auf Trigger wurde verzichtet. Ein virtueller View konnte nicht gemacht werden, da MySql keine Views auf Abfragen die Subqueries enthalten erlaubt. Die Leistungs- /Ertrags und Vergütungsdaten der Kraftwerke wurden hinzu aggregiert. Damit wird es zum Beispiel möglich die Stromertragsdaten in Beziehung zu der Bevölkerungsanzahl auszuwerten. GemeindeverbandsView Dieser View ist auf Gemeindeverbandsebene und enthält Stromverbrauchs- und dazu aggregierte Ertragsdaten. Er ist ebenso wie der GemeindeView materialisiert. 31 6.1.11 MODELLIERUNG IN GORM Es soll anhand eines Beispiels die Art der Modellierung in GORM beschrieben werden. Klasse GemeindeView Abbildung 6, GORM Klasse GemeindeView Die Klasse GemeindeView ist das Gegenstück zu dem Datenbank View mit gleichem Namen. Als erstes sind die Attribute aufgelistet. Wenn Grails gestartet wird und diese Datenbanktabelle noch nicht besteht wird sie automatisch anhand dieser Informationen erstellt. Bei Änderungen wird sie auch automatisch angepasst. Natürlich kann dieses Verhalten für den Produktivbetrieb ausgeschaltet werden. Die getGeoHierarchie() Methode ist eine getter-Methode für ein quasi virtuelles Attribut geoHierarchie. Der Zugriff ist wie für ein normales Attribut möglich, gemeindeView.getHierarchie . Das Attribut wird von einem Kategorisierer des ULCBigTableExplorers verwendet, um eine Gemeindehierarchie darzustellen, nach deren Einträge gefiltert werden kann. In der mapping Closure (siehe 15.1) wird das 32 Datenbankmapping konfiguriert. Es werden Angaben zu der ID, der Versionierung, dem Cache und dem Tabellenname gemacht. Die transient Closure definiert, dass das geoHierarchie Attribut keine Entsprechung in der Datenbank hat. Die constraints null sein darf. 33 Closure enthält Validationsinformationen, hier dass der Attributwert bei der Fläche 7 DATENIMPORT Die Quelldaten wurden mit Hilfe von Importskripten in die Datenbank gespeichert. Es wurde entschieden die Programmiersprache Groovy zu verwenden. Eine Beschreibung der Sprache befindet sich in Kapitel 15.4. Mehrere Argumente sprachen für Groovy. Das für die Integration verwendete Grails Framework (siehe 15.5) ist in Groovy geschrieben. Das heisst, es konnte die Grails Konsole verwendet werden. Mit diesem kleinen Programm können Groovy Skripte direkt auf einer Grails Instanz ausgeführt werden. Man hat dadurch Zugriff auf das Grails API. Man ist insbesondere in der Lage, direkt Domänenobjekte zu instanziieren und zu speichern. Die Sprache hat ausserdem sehr elegante Mittel um mit Files umzugehen, Webservices aufzurufen und XML zu verarbeiten. Des Weiteren ist sie sehr Ausdrucksstark, es kann viel mit wenig Code ausgedrückt werden. Bei Canoo ist ausserdem viel Groovy Know-How vorhanden. Dierk Koenig ist ein "comitter" beim Groovy Projekt und hat das Buch "Groovy in Action" geschrieben. 7.1 VORGEHEN Die einzelnen Excel-Files wurden im CSV Format gespeichert. Die Files mussten jeweils in einem Quelltext Editor geöffnet und zu UTF-8 konvertiert werden. Das Verarbeiten des File Inhalts, kann in Groovy in einer Closure (siehe 15.1) erledigt werden. Ein fragmentarisches Beispiel von dem Skript GemeindedatenImport.groovy soll die grundlegende Funktionsweise exemplarisch aufzeigen. Hier wird über die Gemeindedaten iteriert. Die Methode "splitEachLine" zerteilt jede Zeile des CSVFiles auf dem angegeben Zeichen und übergibt die Liste der Teilstrings der Closure. Der Ausdruck fields[7]?.trim() 34 zeigt die Prägnanz von Groovy. Das Fragezeichen verhindert eine NullPointerException wenn das achte ([7]) Element null ist. Anschliessend wird ein Gemeindeverband-Objekt erzeugt und mit dem Aufruf der Methode save() gespeichert. Diese Methode wird dem Objekt dynamisch vom Framework hinzugefügt und muss nicht implementiert werden (Metaprogrammierung) (Ledbrook, 2009). Andere Entitäten die im Gemeindevebandsobjekt gekapselt sind, werden gleich mitgespeichert. Hier zum Beispiel das Landkreis Objekt. Um das Eintragen des Fremdschlüssels in der Datenbank muss sich der Entwickler nicht kümmern. Dies wird von Grails übernommen. Grails arbeitet mit dem Persistenz-Framework Hibernate (Ledbrook, 2009). Um die Zeitdauer des Imports zu verkürzen, wurden bei allen Skripten die Inserts in eine Transaktion gepackt und auf der Hibernate Session jeweils nach 100 Datensätzen die flush() Methode aufgerufen. Dies veranlasst Hibernate ein einziges Insert Statement abzusetzen. Der Aufruf der save() Methode auf der Domäneninstanz führt also nicht direkt zu einem Insert. Der folgende Code zeigt die konkrete Implementierung für die Kraftwerksdaten. In der cleanUpGorm() Methode wird die aktuelle Hibernate Session von der SessionFactory abgefragt und die mittels des Aufrufs von daraufhin gelöscht. 35 flush() die Daten in die Datenbank geschrieben. Die Session wird 8 DATENINTEGRATION Der eigentliche Datenintegrationsteil der vorliegenden Arbeit, war das Mapping der EEGKraftwerksdaten auf die Gemeindedaten des statistischen Amtes. Letztere stellen die Referenz für alle anderen Datensätze dar, die einer geographischen Entität zugeordnet werden können. Alle Datensätze müssen sich also darauf beziehen. 8.1 GEMEINDEMAPPING EEG-KRAFTWERKSDATEN 8.1.1 PROBLEM Die EEG-Kraftwerksdaten besitzen keinen eindeutigen Schlüssel mit dem die Datensätze direkt einer geographischen Entität, also in unserem Fall einer Gemeinde, zugeordnet werden könnten. Es sind jeweils nur die Gemeindenamen und die jeweilige Postleitzahl vorhanden. 8.1.2 NORMALISIERUNG DER GEMEINDENAMEN Der EEG-Datensatzes und der Gemeindedatensatz wurden jeweils um den normalisierten Gemeindenamen ergänzt. Ein Gemeindename wie "Bad Münster am Stein-Ebernburg, Stadt" wurde zum Beispiel um seinen normalisierten Namen, nämlich "BAD MUENSTER" ergänzt. Am Anfang der Arbeit wurde davon ausgegangen, dass die Gemeindedaten des OpenGEODB Projekts (siehe 5.3.4) Verwendung finden. Diese enthalten bereits den normalisierten Gemeindenamen. Dieser Datensatz wurde zu Gunsten der offiziellen Gemeindedaten vom statistischen Amt aufgegeben. Das Mappen mit dem normalisierten Gemeindenamen war aber auch bei den schliesslich benutzen Datensätzen eine erfolgreiche Strategie. Insbesondere die Gemeindenamen des EEG-Kraftwerksdatensatzes mussten sowieso bereinigt werden, da sie Schrägstriche und teilweise Zahlen enthielten. 8.1.3 VORGEHEN NORMALISIERUNG Der Gemeindenamen wurde bei den folgenden Zeichen und Wörtern getrennt: , | bei | am | an | vor | im | unter | bin | ( | / 36 Der linke Teilstring wurde wie folgt weiter verarbeitet: Umlaute konvertieren: ä -> ae; Ä -> Ae; ö -> oe; Ö -> Oe; ü -> ue; Ü -> Ue St. -> Sankt Alles zu Grossschrift konvertieren 8.1.4 ZUORDNUNGSHEURISTIK Es wurde versucht möglichst viele der Datensätze automatisiert zuzuordnen, um den manuellen Aufwand klein zu halten. Hier werden die verschiedenen Schritte des Mappings beschrieben. Wenn bei einem Schritt eine Zuordnung möglich war, wurde der Vorgang abgebrochen. Mit Gemeindename wird immer der "normalisierte" Gemeindename gemeint. Mit Referenzdaten werden die Gemeindedaten des statistischen Amtes gemeint. Schritt 1, Direkte Zuordnung über den Gemeindenamen und die Plz. Die Angaben zum Gemeindenamen und der Postleitzahl im Kraftwerksdatensatz wurden verwendet, um das korrespondierende Objekt im Gemeindedatensatz zu finden. Der Methodenaufruf auf dem Gemeindenamen zeigt wiederum die Eleganz des Grails-Frameworks. Die Methode findByNameNormalisertAndPlz(name, plz) ist implizit vorhanden und muss nicht programmiert werden. Der Rückgabewert ist ein Objekt des Typs Gemeinde oder null. In SQL entspräche der Aufruf einem select * from Gemeinde where nameNormalisiert = :name AND plz = :plz; . Diese Anfragemethoden heissen bei Grails "dynamic finders" (Ledbrook, 2009). Viele verschiedene Anfragemethoden sind "out-of-the-box" vorhanden. Schritt 2, Nutzung der MappingHelper Tabelle Einige Datensätze wurden schon früher manuell zugeordnet und die Zuordnungen in der Datenbanktabelle MappingHelper abgelegt. Auf diese Tabelle wurde ein Lookup mittels der Postleitzahl und dem normalisierten Namen des EEG-Kraftwerksdatensatzes gemacht. 37 Schritt 3, Eindeutiger Gemeindename und Levenshtein-Distanz von Plz höchstens 1 Bei diesem Schritt wurden zuerst überprüft, ob der Gemeindename im EEG-Kraftwerksdatensatz im Referenzdatensatz eindeutig ist. Falls dem so war, wurde überprüft, ob die Postleitzahl eine Levenshtein-Distanz (siehe 15.2) von höchstens eins hat und in diesem Fall direkt gemappt. Zusätzlich wurde der Yahoo Gelocations Webservice verwendet um die Wahrscheinlich der korrekten Zuordnung zu beurteilen, getQualityByYahooLookup(plzRef, name, adresse) . Bei Schritt 8 wird dieser Aufruf beschrieben. Schritt 4, Eindeutiger Gemeindename Es wurde überprüft, ob der Gemeindename in den Referenzdaten Eindeutigkeit ist und in diesem Fall direkt gemappt. 38 Schritt 5, Inhaltsvergleich Gemeindename Alle Gemeinden, mit der im EEG-Kraftwerksdatensatz angegeben PLZ, wurden aus den Referenzdaten geladen und überprüft, ob der Gemeindename des EEG-Datensatzes in einem Gemeindename der geladenen Referenzdaten vorkommt oder ob einer der Gemeindenamen des Referenzdatensatzes in dem Gemeindenamen des EEG-Datensatzes vorkommt. 39 Schritt 6, Levenshtein-Distanz Alle Gemeinden, mit der im EEG-Kraftwerksdatensatz angegeben PLZ, wurden aus den Referenzdaten geladen und überprüft, ob der Gemeindename des EEG-Datensatzes im Vergleich mit einem Gemeindename der geladenen Referenzdaten, eine Levenshtein-Distanz (siehe 15.2) von kleiner 20 Prozent der Namenslänge besass. Schritt 7, OpenGeoDB-Lookup Im EEG-Kraftwerksdatensatz sind einige Kraftwerke nicht einer Gemeinde, sondern einem Gemeindeteil bzw. Stadtteil zugeordnet. Die Referenzdaten sind aber nur bis Stufe Gemeinde vorhanden. Um heraus zu finden, in welcher Gemeinde dieses Kraftwerk liegt, wurde die OpenGeoDB-Datenbank (siehe 5.3.4) verwendet. Diese wurde in die lokale Datenbank eingespielt. Danach wurde in diesen Daten nach der PLZ und dem Gemeindenamen des EEGKraftwerksdatensatzes gesucht. Falls ein Eintrag auf dem Level 7 (Gemeindeteil) oder Level 8 (Stadtteil) gefunden wurde, wurde das entsprechende Vaterelement über die loc_id ausgelesen. Falls diese auf dem Level 6 war (Gemeinde), wurde diese Gemeinde in den Referenzdaten gesucht. 40 Schritt 8, Yahoo Lookup mit PLZ, Gemeindename und Adresse Mit der Postleitzahl, dem Gemeindenamen und der Adresse des Kraftwerks wurde der Yahoo Geolocation Webservice (Yahoo, 2011) angefragt. 41 Dieser liefert einen XML-Response zurück. Erneut konnte die Ausdrucksstärke von Groovy zum Zuge kommen. Das Aufrufen des Yahoo Webservices und das Auslesen der PLZ benötigt einen Einzeiler: new XMLParser().parse(url).Result.uzip.text() Die Struktur des zurückgelieferten XML ist in Abbildung 7 ersichtlich. Wenn die Adressezuordnung eine Qualität von über 80 hatte, wurde der zurückgelieferte "city"Name von Yahoo und die PLZ verwendet um die Gemeinde in den Referenzdaten nachzuschlagen. Schritt 9, Yahoo Lookup der übergeordneten Gemeinde Da der Referenzdatensatz, wie schon erwähnt, nur Informationen auf Gemeindeebene enthält, mussten die EEG-Kraftwerksdatensätze, die sich auf Gemeindeteile oder Stadtteile beziehen einer übergeordneten Gemeinde zugeordnet werden. Das unter Schritt 7 beschriebene Vorgehen nutzte dazu die Daten der OpenGeoDB. Hier wurde der Yahoo Geolocation Webservice verwendet. Der Gemeindename und die PLZ der EEG-Kraftwerksdaten wurden an den Webservice geschickt. Der XML-Response von Yahoo hat die folgende Struktur: 42 Abbildung 7, XML-Response Yahoo Geolokationsservice Unter dem Knoten neighborhood ist der gesuchte Gemeindeteil und unter dem Knoten city die übergeordnete Gemeinde. Diese wurde ausgelesen und mit der PLZ des EEG-Kraftwerksdatensatzes in den Referenzdaten gesucht. In der Yahoo Dokumentation wird das neighborhood Element wie folgt beschrieben: "The neighborhood element describes an area that is contained within a larger administrative place (city)." (Yahoo, 2011) 43 Schritt 10, Yahoo Lookup mit PLZ und Adresse Dieser ist fast identisch zum Schritt 8. Es wurde aber die PLZ und die Adresse zum Abfragen des Yahoo Webservices verwendet. 8.1.5 RESULTATE Im EEG-Datensatz gibt es 2797 unterschiedliche Gemeindename. 2728 Gemeinden konnten gemappt werden, 69 nicht. Dies entspricht einer Mappingquote vom 97.5%. In Rheinland Pfalz gibt es nur 2306 Gemeinden. Die Differenz ist durch die Gemeinde- oder Stadtteile und falsche Schreibweisen der Gemeindenamen zu erklären. In der nachfolgenden Tabelle ist ersichtlich, wie viele der Datensätze mit welchem Schritt gemappt wurden. Es wird die absolute Anzahl und das Verhältnis zu der Gesamtanzahl der Gemeindenamen angegeben. Schritt 1 2 3 4 5 6 7 8 9 10 nicht gemappt Total Tabelle 4, Gemeindemapping Resultate 44 Anzahl 2217 105 41 27 126 86 0 50 52 24 69 2797 % 80 4 2 1 4 3 0 1.5 1.5 1 2 100 Für 80 Prozent der Datensätze ist ein Mapping direkt über den Namen und die PLZ möglich. Es bleiben aber fast 600 Datensätze übrig. Diese manuell zu mappen wäre sehr mühsam. Die Heuristik hilft noch bei weiteren 511 Datensätzen. Insbesondere der Lookup auf die MappingHelper Tabelle (Schritt 2) und der Inhaltsvergleich des Gemeindenamens (Schritt 5) sind erfolgreich. Enttäuschend ist der Lookup auf die Open Geo DB (Schritt 7). Hier war kein Mapping möglich. Die fehlenden Mappings wurden vom Projektpartner manuell ergänzt. Bei einer handvoll Datensätzen war die Zuordnung nicht möglich. Die Mappings wurden in der Datenbanktabelle MappingHelper hinterlegt. Dadurch wird in Zukunft der Import dieses Datensatzes deutlich einfacher. Eine Zuordnung der problematischen Einträge kann direkt über diese Tabelle geschehen. Die Mapping-Heuristik, würde dann nur für die neuen Kraftwerksadressen benutzt. 45 9 DATENANREICHERUNG 9.1 LÄNGEN- UND BREITENGRADE Die Längen- und Breitengrade wurden mit folgendem Groovy Skript abgefragt. Der normalisierte Gemeindename, die PLZ und die aufbereitete Adresse wurden an den Yahoo Geolocations-Webservice geschickt und die zurückgelieferten Längen- und Breitengrade sowie der Qualitätslevel des Resultats in der Datenbank gespeichert. Das Qualitätslevel im Rückgabewert wird bei Yahoo wie folgt beschrieben: "The value of an Address Quality element defines the granularity of the location described by an address. It is expressed as an integer between 0 and 99; higher values indicate more precision. Values of 80 or greater describe points; values less than 80 and 70 or greater describe lines; values less than 70 describe areas. A value of 0 indicates that no location could be extracted from the address data" (Yahoo, 2011). 46 9.2 RESULTATE Der Kraftwerksdatensatz aus Rheinland Pfalz enthält 48667 Datensätze. Für 4 dieser Datensätze konnten keine Längen- und Breitengrade gefunden werden. In Tabelle 5, Resultate Längen- und Breitengrad Abfragen ist ersichtlich wie die Verteilung der Qualitätslevel ist. Level Anzahl % Beschreibung Yahoo (Yahoo, 2011) 87 86 85 84 72 71 60 59 50 40 19 29850 3745 4800 608 2992 865 2783 65 2070 877 8 61 8 10 1 6 2 6 <1 4 2 <1 Address match with street match Address mismatch with street match Address match with street mismatch Address mismatch with street mismatch Street match Street match, address ignored Postal district Postal district, street ignored Level4 (Neighborhood) Level3 (City/Town/Locality) Level1, (State/Province) level2 ignored (County) Summe 48663 100 Typ (Yahoo, 2011) Point Point Point Point Line Line Area Area Area Area Area Tabelle 5, Resultate Längen- und Breitengrad Abfragen 80% der Kraftwerke zeigen ein Qualitätslevel von über 80, dass heisst der Adresse konnte ein geographischer Punkt zugeordnet werden. Etwas schwer verständlich sind teilweise die Beschreibungen der einzelnen Levels bei Yahoo. Der Level 85 soll zum Beispiel ein Adressen-Match sein obwohl die Strasse nicht gematcht wurde. Die Erklärung ist, dass der Strassenname nicht exakt matched. In vielen Fällen war die Strasse in unseren Daten mit Str. abgekürzt. Dadurch wird nicht mehr ein Level von 87 zurückgegeben. Bei den Datensätze mit Level 71 und 72 konnte nur noch eine Strasse zugeordnet werden. Bei denen mit einem Level unter 70 nur noch eine Fläche wie zum Beispiel eine Stadt. Um die Zuordnungen weiter zu überprüfen wurden die Längen- und Breitengrade in einem ScatterPlot visualisiert. Dieser ist in Abbildung 8 zu sehen. 47 Abbildung 8, Scatter-Plot der Kraftwerks Längen- und Breitengrade Abbildung 9, Karte Rheinland Pfalz Es ist deutlich zu erkennen, dass die Punkte die Umrisse des Bundeslandes Rheinland Pfalz zeigen. Nur wenige Punkte sind ausserhalb dieses Gebiets und damit sicherlich falsch zugeordnet. Es wurde daraufhin eine SQL-Abfrage gemacht um ungefähr zu bestimmen wie viele Punkte nicht in Rheinland Pfalz liegen. SELECT count(*) FROM kraftwerk k WHERE k.laengengrad > 6.1 AND k.laengengrad < 8.5 AND k.breitengrad > 49 48 AND k.breitengrad <50.8; Das SQL fragt ab, welche Datensätzen einen Längengrad zwischen 6.1 und 8.5 und einen Breitengrad zwischen 49 und 50.8 besitzen. Das Resultat ist natürlich zu optimistisch, da ja Rheinland Pfalz kein Rechteck ist. 48206 der 48667 Datensätze liegen innerhalb dieser Grenzen und somit wahrscheinlich in Rheinland Pfalz. Dies entspricht ungefähr 99 Prozent. Weiter konnte mittels des Scatter-Plots und eines weiteren nicht abgebildeten Barcharts gezeigt werden, dass die nicht in den Polygonzügen von Rheinland Pfalz liegenden Punkte alle einen Qualitätslevel von über 80 haben. Die Qualitätslevels der Abfragen könnten sicherlich mit einem Aufbereiten der Adressinformation noch verbessert werden. Dies war aber im Rahmen dieser Arbeit nicht mehr möglich. 49 10 PROTOTYP ERSTELLUNG 10.1 ZIELE Mit dem Prototyp sollte überprüft werden, wie gut sich die beiden Komponenten integrieren lassen, wie stabil die Komponenten schon sind, wie die Zusammenarbeit mit der Persistenzschicht von Grails klappt, welche Mängel die Programmierschnittstelle allenfalls aufweist und welche zusätzlichen funktionalen sowie nicht-funktionalen Anforderungen sich ergeben. 10.2 VORGEHEN Die Erstellung des Prototyps ging über folgende Phasen: Einarbeitung Komponenten, Grails, Konzepte ULC Implementierung Datenanbindungsschicht und Datendefinitionen Integration der Komponenten mit Grails Datenbank Views erstellen und anbinden Entwicklung eines Datenauswahl GUIs Bug Fixing Testing/ Profiling Optimierung des Prototyps Deployment 10.3 DATENAUSWAHL GUI Aufgrund der fehlenden Aggregationsfunktionalität des ULCBigTableExplorer (siehe 10.6.4) wurde vom Auftraggeber gewünscht, gewisse Voraggregationen zu machen. Diese wurden in verschiedenen Views in der Datenbank realisiert (siehe 6.1.10) und können nun über das erstellte GUI angewählt werden. Ausserdem war das Anzeigen der entsprechenden Metadaten wichtig. Es gibt anzumerken, dass der ULCBigTableExplorer noch keine Möglichkeit bietet eine andere Datenquelle zu setzen und das GUI neu zu initialisieren. Beim Wechsel auf einen anderen View wird die Komponente also erneut erzeugt. 50 Abbildung 10, Datenauswahl GUI 10.4 BIGTABLEDATAPROVIDER 10.4.1 HINTERGRUND Um die gemeinsame Nutzung des ULCBigTableExplorer und der ULCGeoMaps zu vereinfachen wurde von den Entwicklern der Komponenten eine gemeinsame Datenanbindungsschicht implementiert, der BigTableDataProvider. Dieser stellt die Programmierschnittstellen für den Entwickler bereit und enthält die Implementierung des Indexes der von den Komponenten genutzt wird. In diesem Kapitel soll die Programmierschnittstelle kurz vorgestellt und die Funktionsweise des Index erklärt werden. 10.4.2 ARCHITEKTUR Auf eine Architekturbeschreibung wird größtenteils verzichtet. Die Aufgabe der vorliegenden Arbeit bestand darin die Komponenten zu verwenden und die Erfahrungen zu dokumentieren. Insofern ist es ausreichend die Programmierschnittstelle zu beschreiben und Details zur Architektur nur einzustreuen, falls diese für das Verständnis nötig ist. 51 Abbildung 11, Architektur BigTableDataProvider, (Bräunlich, 2011) 10.4.3 PROGRAMMIERSCHNITTSTELLE Der Anwendungsentwickler muss zur Datenanbindung die Klassen AbstractDataSource AbstractDataDescription und ableiten und deren abstrakte Methoden implementieren. Die beiden abstrakten Klassen implementieren die IDataDescription und IDataSource Interfaces. 10.4.3.1 DATADESCRIPTION Die DataDescription dient vor allem dazu, die Spalten des Datensatzes zu beschreiben (defineStructure-Methode), die DataSource Implementierung zu bestimmen (defineDataSourceMethode) und den Titel dieses Datensatzes zu definieren (defineTitle-Methode). In der vorliegenden Implementierung sind in der defineStructure-Methode Abbildung 12 enthalten Spaltendefinitionen enthalten. 52 unter anderem die in Abbildung 12, Code: defineStructure-Methode, EEGDataDescriptionGORM Zur Konfiguration der Spalten dient die Methode mapColumn(). Schnittstelle wurde. das Builder ColumnDescriptionBuilder Pattern verwendet aufgrund der Methodenaufrufe Im Es ist ersichtlich, dass für die Hintergrund ColumnDescriptions, generiert ein also Beschreibungen der Spalten. Es soll nicht auf die Implementierung eingegangen werden, sondern die Schnittstelle an Hand des Beispiels aus Abbildung 12, Code: defineStructure-Methode, EEGDataDescriptionGORM 12 illustriert werden. Mit dem Methodenaufruf zugewiesen. Der toCategorizer() Kategorisierer wird der Spalte eine Kategorisierungsimplementierung bestimmt, wie die Kategorien gebildet BigTableDataProvider bringt einige Standard-Kategorisierer mit. Einer davon ist der werden. Der ValueCategorizer, der für nominelle Spaltenwerte gedacht ist. Jeder diskrete Wert wird damit zu einer Kategorie. Mit dem Methodenaufruf toAggregationFunction() wird der Spalte eine Aggregations-Funktion zugewiesen. Auch hier sind einige Standardklassen vorhanden. Zum Beispiel die SumAggregationFunction die Double-Werte aggregiert. Mit dem Methodenaufruf setVisible() wird die bestimmt, ob die Spalte sichtbar sein soll oder nicht. Mit dem Methodenaufrufen setIcon().map() wird einem Spaltenwert ein Icon zugewiesen. Dies macht diskreten Werten Sinn. Im Kategoriebaum und in der Spalte erscheinen dann diese Icons. Mit dem Methodenaufruf toUnit() wird im GUI zum Wert hinzugefügt. 53 kann eine Einheit, zum Beispiel kWh, angegeben werden. Diese Mit dem Methodenaufruf toType() kann der Datentyp der Spaltenwerte angegeben werden. Mit dem Methodenaufruf toLocale() kann die Lokalisierung angegeben werden. Die Komponenten sind damit auch in der Lage zum Beispiel mit verschiedenen länderspezifischen Formaten umzugehen. Die Programmierschnittstelle bietet die Möglichkeit eine "virtuelle"-Spalte hinzuzufügen. Damit können andere Spaltenwerte einer Zeile zu einem neuen Spaltenwert kombiniert werden. Die gemeinsame Darstellung des Gemeindenamens und der PLZ in einer zusätzlichen "virtuellen" Spalte wäre damit zum Beispiel möglich. Auch Berechnungen von numerischen Werten sind denkbar. Für die virtuelle Spalte muss eine ValueGetterFunktion definiert werden. In dieser Klasse werden die Spaltenwerte verarbeitet. 10.4.3.2 DATASOURCE Die DataSource-Implementierung ist die eigentliche Datenanbindungsschicht. Fünf Methoden der AbstractDataSource müssen implementiert werden: getDataRecord(int rowNumber) Diese Methode gibt ein DataRecord, also ein Objekt das einer Zeile des Datensatzes entspricht, zurück. Der Übergabe-Parameter ist die Zeilennummer. getRowCount() Die Methode gibt die Anzahl der Datensätze zurück, also die Anzahl Zeilen. List<String> getHeaderNames() Diese Methode gibt die Spaltennamen zurück. Die Länge dieser Liste bestimmt wie viele Spaltendefinitionen (ColumnDescriptions) der BigTableDataProvider initial erstellt. Ausserdem sind diese Spaltennamen das Spaltenidentifikationselement, das in der DataDescription wieder verwendet wird (siehe Parameter der mapColumn-Methode in Abschnitt 10.4.3.1). init(IDataDescription description) Mittles Aufruf dieser Methode wird der DataSource eine Referenz auf die DataDescription übergeben. Damit kann die DataSource Spaltenkonfigurationen auslesen. getColumnWidths() 54 Diese Methode gibt ein int-Array mit den maximalen Spaltenbreiten in Zeichen zurück. 10.4.4 INDEX Beide Komponenten nutzen einen Index. Dieser speichert für alle Datensätze in welche Kategorien die Spaltenwerte fallen. Um den Speicherverbrauch klein zu halten und schnelle Schnittmengen bilden zu können, werden in einem byte-Array jeweils einzelne Bits gesetzt. Die Tabelle 6, Bit-Index BigTableDataProvider zeigt das Prinzip. Zeile 1 2 3 usw. Solar 1 0 1 Wind 0 1 0 Wasser 0 0 0 kW < 2 1 0 1 kW > 2 0 1 0 Trier 1 1 0 Koblenz 0 0 0 Tabelle 6, Bit-Index BigTableDataProvider Durch die Bildung von Schnittmengen kann nun bestimmt werden, welche Datensätze eine entsprechende Kategoriekombination aufweisen. Die Datensätze 1 und 3 sind zum Beispiel in der Kategorie Solar und der Kategorie kW < 2 vertreten. Der Index liegt serialisiert auf der Festplatte und wird beim Programmstart in den Speicher geladen. Falls der Index noch nicht vorhanden ist, wird er erzeugt. Die Datenabfrage geschieht dabei über die DataSource-Schnittstelle. Der Anwendungsentwickler muss sich normalerweise nicht um die Indexgenerierung kümmern. Der Index kann nur vollständig erzeugt werden. Es ist also bei einer Änderung der Kategorisierungslogik oder einem Update der Daten eine Neuindexierung notwendig. 55 10.5 HERAUSFORDERUNGEN An dieser Stelle sollen die Herausforderungen bei der Entwicklung beschrieben werden. Das Kapitel hat damit Dokumentationscharakter. Es wird nicht jede NullPointerException erwähnt, sondern dokumentiert wo die grössten Knacknüsse lagen. Dies wird hoffentlich bei einem Folgeprojekt helfen, Zeit zu sparen. Es ist auch zu sagen, dass viele Fehler bereits ausgebessert werden konnten und daher nicht Erwähnung finden. 10.5.1 GRAILS ULC PLUGIN Das Grails ULC Plugin hatte leider zwei Fehler. Dadurch dauerte der initiale Setup länger als geplant (2 Tage). Die Bugs wurden für die Version 0.3.5 bereits behoben. 10.5.2 INDEX Wie schon unter im Kapitel 10.4.4 beschrieben nutzen die beiden Komponenten den gleichen Index um schnelle Antwortzeiten zu erreichen. Der Index machte während der Prototyp Erstellung Probleme. Im Moment wird von den Komponenten nicht der exakt gleiche Index erstellt. Beide Komponenten fügen der DataDecription (siehe 10.4.3.1) eine virtuelle "Location"-Spalte hinzu, in der geographische Daten zusammengefasst sind. Diese beiden Spalten sind aber leider noch nicht gleich aufgebaut. Die GeoMaps kann dadurch nicht auf einem Index, der vom ULCBigTableExplorer erstellt wurde, arbeiten. Umgekehrt funktionierte es, da der ULCBigTableExplorer die zusätzliche Spalte nicht zwingend braucht. Die Indexierung dauert zudem ziemlich lange. Die Messungen sind in Kapitel Fehler! Verweisquelle konnte nicht gefunden werden. ersichtlich. Weitere Anmerkungen und Ideen finden sich im Kapitel 10.6.1. 10.5.3 LADEN DER RESSOURCEN Das Laden der Ressourcen wie Bilder und Datenfiles funktionierte leider nicht sofort. Schuld daran waren zum einen die "Build"-Voreinstellungen von Grails und die Art wie die Komponenten die Ressourcen luden. Um das erste Problem zu lösen, wurde im Verzeichnis grails-app ein Ressourcenordner erstellt und die Ressourcen dort abgelegt. Ausserdem wurde ein Event-Skript geschrieben. 56 eventCompileEnd = { ant.copy(toDir:"${classesDirPath}/resources"){ fileset(dir: "${basedir}/grails-app/resources ", includes: '**/*') } } Das Skript kopiert die Ressourcen beim Kompilieren in das Build-Verzeichnis. In den Komponentenimplementierungen wurde das Laden der Ressourcen abgeändert. Anstatt die Ressourcen-URLs nur über den Aufruf von getClass().getResource(path) Thread.currentThread()getContextClassLoader().getResource(path) zu laden, wurde der Aufruf hinzugefügt. Dieser funktioniert auch in einem Webcontainer. 10.5.4 DEPENDENCY MANAGEMENT In Grails werden die Dependencies im Konfigurationsfile BuildConfig.groovy angegeben. Da das verwendete Miglayout-Jar eine zirkuläre Abhängigkeit zu den ulc-core-client- und ulc-core-server-Jars aufweist, musste diese Dependency wie folgt eingebunden werden: compile("com.canoo.ulc:ulcbuilder-miglayout:1.0") { transitive = false } compile("com.canoo.ulc.ext.ULCMigLayout:ULCMigLayout-client:1.0") { excludes 'ulc-core-client' } compile("com.canoo.ulc.ext.ULCMigLayout:ULCMigLayout-server:1.0") { excludes 'ulc-core-server' } Ausserdem hat Grails mühe, Maven Dependencies einzubinden die im Namen eine Revisionsnummer haben. Diese Jars wurden direkt ins lib Verzeichnis gelegt. 10.5.5 BENUTZERSCHNITTSTELLE 10.5.5.1 Null Safety Die Aufrufe auf das DataRecord Objekt, das von der getDataRecord()-Methode in der DataSource Implementierung zurückgegeben wird, sind teilweise nicht null save. Zum Beispiel die Aufrufe DataRecord.getElementAsString() oder Indexes.addToIndexes(). Dadurch muss der Benutzer der Komponenten immer einen null-Check der zurückgelieferten Daten vornehmen. 10.5.5.2 ValueGetterFunction Das Konzept der ValueGetterFunction wurde bereits in Kapitel 10.4.3.1 kurz angeschnitten. Die Idee ist, dass Werte einer Zeile des Datensatzes in der getValue()-Methode einer ValueGetterFunction- Implementierung verarbeitet werden können. In der DataDescription kann eine ValueGetterFunction pro Spalte definiert werden. Damit ist es möglich Werte zum Beispiel umzurechnen. Ein Implementierungsbeispiel wäre die QuotientValueGetterFunction. 57 public class QuotientValueGetterFunction extends AbstractValueGetterFunction<Double> { @Override public Double getValue(List<String> rawData, ColumnDescription columnDescription){ return Double.parseDouble(rawData.get(2)) / Double.parseDouble(rawData.get(8)); } } Hier wird der Quotient zwischen dem Zeilenwert der 2. und 8. Spalte gebildet und zurückgegeben. In der DataSource-Implementierung wird die Methode folgendermassen aufgerufen: for (int i = 0; i < dataDescription.getNumberOfColumns(); i++){ ColumnDescription columnDescription = dataDescription.getColumnDescription(i); Object value = columnDescription.getValueGetterFunction() .getValue(data, columnDescription); data.add(value != null ? value : ""); } Für jede Spaltenbeschreibung (ColumnDescription) wird die ValueGetterFunction abgefragt und die getValue()-Methode aufgerufen. Falls für eine Spalte keine ValueGetterFunction definiert wurde, wird eine Default-Implementierung verwendet. Es ergeben sich zwei Probleme. Zum einen muss der Anwendungsentwickler zwingend den obigen Code implementieren. Der Grund ist, dass die GeoMaps eine virtuelle "Location"-Spalte dazufügt, deren ValueGetterFunction zwingend verwendet werden muss. Es kann also sein, dass vom Anwendungsentwickler keine ValueGetterFunctions definiert wurden und der trotzdem den obigen Code in seiner DataSource implementieren muss. Dies ist sicherlich sehr fehleranfällig. Eine Lösung wäre, den Code in dem BigTableDataProvider zu implementieren, das heisst in standardmässig aufzurufen. Ein weiteres Problem ist, dass die getValue()-Methode die Daten als Liste von Strings bekommt. Alle typisierten Attributwerte der Grails-Datenobjekte müssen also zuerst in Strings umgewandelt werden. Bei einem Datum packt Grails zum Beispiel den Wert der Datenbank in ein typisiertes Attribut, das in der DataSource zu einem String konvertiert wird. Darauf gibt die DefaultValueGetterFunction den Wert aber mittels Typinferenz (der Typ der Spaltenwerte kann in der DataDescription angegeben werden) wieder typisiert zurück. 10.5.5.3 Data Source Singleton Die DataSource wurde zuerst als Singleton implementiert. Dies führte dazu, dass die Applikation bei jedem zweiten Zugriff eines Clients abstürzte. Der Grund ist, dass die GeoMaps Komponente die Liste von Spaltentiteln, die durch den Aufruf der DataSource-Methode getHeaderNames() zurückgegeben wird, um einen Spaltentitel ergänzte (virtuelle Location-Spalte). Durch die Singleton Implementierung wurde die Liste beim zweiten Client wieder erweitert. Meines Erachtens müsste die DataSource als Singleton implementierbar sein. Es sollte allenfalls generell von einer, von den Komponenten selbst hinzugefügten virtuellen Spalte, abgesehen werden. 58 10.5.5.4 Eingebauter Date Kategorisierer Der standardmässig vorhandene Datums-Kategorisierer kann leider nicht mit java.util.Date Typen umgehen. Die Datumswerte mussten als formatierte Strings (dd.MM.yyyy) geliefert werden. 10.5.5.5 NoAggregationAggregationFunction Wenn in der DataDescription (siehe 10.4.3.1) eine Spalte auf sichtbar gesetzt wird, braucht die ULCGeoMaps im Moment noch eine zugewiesene Aggregationsfunktion. Gewisse Spalten möchte man aber natürlich nur im ULCBigTableExplorer auswerten. Der "workaround" ist im Moment eine Aggregationfunktion die nichts macht als den Wert zurückzugeben. Im GUI der ULCGeoMaps wird für diese Spalten einfach 0 angezeigt. Die ULCGeoMaps sollte nur die Spalten berücksichtigen, die sichtbar sind und auf denen eine Aggregationsfunktion definiert wurde. Diese Änderung ist bereits in der Umsetzung. 10.5.5.6 toName() In der DataDescription (siehe 10.4.3.1) kann im Moment die toName()-Methode noch nicht verwendet werden. Die Verwendung führt in der ULCGeoMaps zu einem Fehler. Die toName()-Methode wird verwendet, um den im GUI angezeigten Spaltennamen zu definieren. 10.5.5.7 DOKUMENTATION Wünschenswert wäre eine Dokumentation der Programmierschnittstelle. Insbesondere für die ULCGeoMaps wäre eine Dokumentation wie zum Beispiel ein neues Overlay (Polygonzüge) erstellt wird, wichtig. 10.5.6 PERFORMANZ Der Prototyp zeigte, dass insbesondere der ULCBigTableExplorer im Client-Server Betrieb sehr langsam reagiert. Das Aufklappen eines Hierarchieknotens in der Kategorieansicht reagiert zum Beispiel sehr träge. Dabei werden aber keine Daten gelesen und damit ist der Grund hierfür nicht bei der Datenabfrage zu suchen. Das Klären dieser komponentenspezifischen Performanzprobleme konnte im Rahmen dieser Arbeit nicht angegangen werden. 10.5.6.1 DATENBANK ABFRAGEN Alle hier dargelegten Performance Messungen wurden auf dem Kraftwerks-View (siehe 6.1.10) gemacht. Es wurde das Profiling Tool YourKit verwendet (www.yourkit.com). 59 Durch die Verwendung des Indexes (siehe 10.4.4) wird die Datenbank nur nach Primärschlüsseln abgefragt. In der DataSource-Implementierung werden die vom Index gelieferten Zeilennummern zu den Primärschlüsseln der Datenbankobjekte gemappt und diese geladen. Es gibt anzumerken, dass diese Art der Abfragen natürlich für eine Datenbank nicht optimal ist. Für die Abfrage würde ein SQL-Statement reichen. Die vorhandene Schnittstelle führt zu sehr vielen Einzelanfragen ans DBMS. Eine gezielte Mengenabfrage wird im Moment nicht unterstützt. Es zeigte sich, dass die Optimierung der Datenbankanfragen nicht einfach ist. Das Problem entsteht schon zu Applikationsstart. Die Komponenten haben dabei ein völlig unterschiedliches Abfrageverhalten. Während der ULCBigTableExplorer nur gerade die ersten in der Tabelle sichtbaren Datensätze anfragt (lazy loading) muss die ULCGeoMaps alle Datensätze laden, um sie zu aggregieren. Für die GeoMaps würde eine Mengenabfrage mehr Sinn machen. Mit der bestehenden Programmierschnittstelle ist dies aber nicht möglich. Zuerst wurde gemessen, wie lange die ULCGeoMaps benötigt alle Datensätze abzufragen und die Aggregation zu machen. Es wurde nichts gecached. Jeder Datensatz wurde mittels der get(id)- Methode von Grails geladen. Das Resultat war so schlecht wie erwartet. Das Laden der Objekte und die Aggregation dauerten für die etwas über 48000 Datensätze 6-7 Minuten. Hier bringt natürlich auch ein Cache nichts, da ja alle Datensätze geladen werden müssen. Es wurde entschieden zuerst einmal alle Datenobjekte, mittels der findAll()-Methode von Grails, in den Speicher zu laden. Dies dauerte im Schnitt 11 Sekunden. Danach wurde der Speicherbedarf gemessen. Insgesamt brauchte die Applikation Heap Speicher im Umfang von ca. 330 MB. Zwei Prozent davon waren Objekte des KraftwerksViews (5.5 MB). Für die vorliegende Anzahl Datensätze ist das vollständige Laden also unproblematisch. Anzumerken ist, dass der Index für die 22 kategorisierten Spalten 24 MB Speicher in Anspruch nimmt. Der Index wird in Abschnitt 10.6.1 kritisch hinterfragt. Ebenfalls wurde ein Versuch mit dem Second Level Cache von Grails bzw. Hibernate gemacht (EHCache http://ehcache.org/). Dies in Hinblick auf grössere Datenmengen. Auch hier wirken die unterschiedlichen Abfragecharakteristika der Komponenten negativ. Der ULCBigTableExplorer könnte von einem Cache profitieren. Die ULCGeoMaps braucht aber zumindest initial alle Objekte. Ausserdem sind die Anfragen welche nicht vom Cache bedient werden können trotzdem sehr langsam. Es wurde ebenfalls versucht immer 1000 Objekte miteinander zu laden. Die scheiterte daran, dass das Eintragen in den Cache nach ca. 10000 Objekten sehr langsam wurde. Auch eine angepasste EHCache-Konfiguration (ehcache.xml) löste das Problem nicht. 60 Ebenfalls gemessen wurde, wie lange der Aufruf der getDataRecord()-Methode der DataSource- Implementierung (siehe 10.4.3.2) dauert. Die Objekte waren dabei im Speicher. Die Abfrage der 48667 DataRecords dauerte 6-8 Sekunden. Das heisst ein einzelner Methodenaufruf kostete ungefähr 0.00015 Sekunden. Diese Aufrufe sind also unproblematisch. Die Verzögerung von ca. einer halben Sekunde beim Nachladen der Tabelleneinträge des ULCBigTableExplorers, ist somit vor allem auf die Latenz des Netzwerkes und die Übertragung der serialisierten Objekte zurückzuführen. 10.5.6.2 INDEXGENERIERUNG Es wurde überprüft, wie lange die Datenabfrage für die Indexgenerierung dauert. Bei den Messungen war nur die ULCBigTableExplorer Komponente instanziert. Versuch 1 2 3 4 5 6 GORMAccessDataSource 38 s 39 s 38s 37 s 2.6 s 2.5 s getDataRecord() 0.015 s 0.093 s 82 s 81 s 1.6 s >1700 s Index vorhanden Ja Ja Nein Nein Ja Nein Daten im Speicher Ja Ja Ja Ja Nein Nein Tabelle 7, Performanz Indexerstellung GORMAccessDataSource ist die DataSource-Implementierung für die Kraftwerksdaten. getDataRecord() ist die deren Methode, die die DataRecords zurückliefert. Bei den Versuchen 1 und 2 war der Index schon vorhanden und die Daten im Speicher. Die Instanzierung der DataSource und erwartungsgemäss wenig Zeit. Das die die Aufrufe der getDataRecord()-Methode getDataRecord()-Methode brauchten überhaupt aufgerufen wurde, ist darauf zurückzuführen, dass die Komponente die ersten Tabelleninhalte auch über diese Methode ausliest. Die Neugenerierung des Indexes dauerte, wenn die Daten im Speicher waren, ca. 80s (Versuche 3 und 4). Es wurden insgesamt Kategorien für 22 Spalten gebildet. Wenn die Daten einzeln abgefragt wurden und der Index vorhanden war, dauerten die Methodenaufrufe 1.6 Sekunden (Versuch 5). Auch hier zeigte sich natürlich die Langsamkeit der schon im Abschnitt 10.5.6.1 beschriebenen Einzelabfragen. Die Generierung des Indexes mittels Einzelabfragen wurde nach 1700s (28 Minuten) abgebrochen (Versuch 6). Diese Zahl erstaunte zunächst, da bei ersten Messungen die Einzelabfragen der 48667, 61 6-7 Minuten benötigten (siehe 10.5.6.1). Die Erklärung ist, dass der BigTableDataProvider bei der Indexgenerierung die getDataRecord()-Methode nicht 48667 mal sondern 48667*22 mal aufruft, dass heisst für jede Spalte. Dies führt zu über einer Million Zugriffen. 10.5.6.3 BEMERKUNGEN P ERFORMANZ Die Komponenten wurden vor dieser Arbeit ausschliesslich mit CSV-Files benutzt. Darum wurde eine indexbasierte Implementierung gemacht, die zeilenorientiert funktioniert. Einzelabfragen auf die Datenbank sind in der vorliegenden Implementierung, insbesondere für die ULCGeoMaps zu langsam. Auch Caching ist keine Lösung, da für die Aggregation alle Datensätze geladen werden müssen. Eine Möglichkeit wäre eine zusätzlich Methode im IDataSource-Interface, in deren Implementierung eine Menge von Datensätzen gelesen werden könnte. Für die vorliegende Datenmenge können alle Objekte in den Speicher geladen werden. Damit ergeben sich gute Zugriffzeiten. Die Indexierung ist natürlich mit Einzelabfragen auch nicht möglich. Unabhängig davon sollte aber die Häufigkeit des Methodenaufrufs (getDataRecord) überdenkt werden. Einmal das DataRecord einer Zeile abzufragen, sollte für die Indexierung reichen. Für eine datenbankorientierte Anwendung der Komponenten sollte eine indexfreie Nutzung ermöglicht werden. Dies wird im Anschnitt 10.6.1 und 10.6.10 näher erläutert. 10.6 BEWERTUNG DER KOMPONENTEN 10.6.1 INDEX Der Index ist gut für die bestehenden Komponenten einsetzbar, insbesondere wenn die Daten von einem File eingelesen werden. Er bietet die Möglichkeit schnell Schnittmengen von zwei Mengen von Zeilen zu bilden. Die kritischen Anmerkungen in diesem Kapitel sollen als Anregung zur Verbesserung des Indexes verstanden werden. Der Index hat einen relativ hohen Speicherbedarf. Für die 48677 Zeilen im Kraftwerks-View nimmt er 24 MB Heap in Anspruch. Natürlich ergibt sich der Speicherbedarf vor allem auch aufgrund der Anzahl gebildeter Kategorien. In Rheinland-Pfalz gibt es über 2000 Gemeinden und somit auch mindestens so viele Kategorien im Index. Der Programmierer des ULCBigTableExplorers, Franz-Josef Wiszniewsky, versuchte bereits einen Kategoriebaum mit allen Gemeinden in Deutschland im Index 62 abzulegen. Der Speicherverbrauch war nicht mehr vertretbar. In der momentanen Implementierung müssen Kategorsierer die sehr viele verschiedene Kategorien bilden mit Vorsicht eingesetzt werden. Die Komponenten sind im Moment noch relativ stark vom Index abhängig. Die Kategoriebäume im ULCBigTableExplorer werden zum Beispiel aus dem Index generiert. Die Erstellung des Index geht im Moment mehrere Minuten. Dies ist unproblematisch wenn die Daten und die Kategoriedefinitionen selten ändern. Kommen neue Daten hinzu, braucht es eine komplette Neubildung des Indexes. Es ist im Moment noch nicht möglich, dem Index einzelne Kategorien hinzuzufügen. Dadurch kann auch keine dynamische Kategorienanpassung, zum Beispiel direkt im GUI, gemacht werden. Bei der Entwicklung ist auch aufgefallen, dass die lange Zeit bis der Index gebildet ist, sich auf die Entwicklerproduktivität auswirkt. Im Moment wird der Index auf dem Filesystem gespeichert und beim Programmstart eingelesen. Falls der Index nicht vorhanden ist, wird er neu gebildet. Schön wäre, wenn die Komponenten selbst feststellen, dass die Datenbeschreibung geändert hat und den Index in diesem Fall neu bilden oder noch besser ergänzen könnten. Die Marktchancen der Komponenten würden sich meines Erachtens erhöhen, wenn es einen NoIndex Modus gäbe. In Abschnitt 10.6.10 werden dazu weitere Hinweise gegeben. Grössere Firmen haben teure Datenbanksysteme. Die Firmen möchten sicherlich diese Datenbanken nutzen, inklusive deren Indices. Die Komponenten müssten also auch die Möglichkeit bieten direkt Abfragen für die Datenbank zu generieren. 10.6.2 WECHSELN DER DATADESCRIPTION UND DATASOURCE Die ULCGeoMaps bietet bereits die Möglichkeit verschiedene DataDescriptions und DataSources zu definieren. In der Komponente wurde auch bereits eine Auswahlliste implementiert. Ein Wechseln der Datenquelle und des Kartenoverlays ist somit dynamisch möglich. Der ULCBigTableExplorer bietet dies noch nicht an. Das heisst es gibt bis jetzt keine Möglichkeit die DataDescription und DataSource neu zuzuweisen und die Komponente zu reinitialisieren. Im Prototyp wird darum jeweils eine neue Instanz der Komponente erstellt. 10.6.3 KATEGORIENBILDUNG Eine automatische Kategorienbildung für kontinuierliche Werte wäre ein mögliches zusätzliches Feature. Die Werte könnten zum Beispiel gleichmässig auf eine konfigurierbare Anzahl von Kategorien verteilt werden. 63 10.6.3.1 Längen- und Breitengrade In der DataDescription (siehe 10.4.3.1) gibt es bis jetzt keine Möglichkeit zu definieren welche Spalten Längen- bzw. Breitengrade enthalten. Dadurch können diese vom Yahoo Service abgefragten Informationen noch nicht verwendet werden, um die Kraftwerke auf der Karte einzuzeichnen. Es ist anzumerken, dass die ULCGeoMap sich selbst mit dem Yahoo Service verbindet und die Längen- und Breitengrade ad-hoc abfragt. Es sollte aber natürlich die Möglichkeit geben, schon vorhandene Informationen zu nutzen. 10.6.4 AGGREGATION DER WERTE Der BigTableDataProvider (siehe 10.4) bietet schon die Möglichkeit Aggregationsfunktionen zu definieren. Diese werden von der ULCGeoMaps bereits verwendet. Der ULCBigTableExplorer unterstützt im Moment aber noch keine Aggregationen. Als erste Erweiterung würde sich eine Summenbildungsmöglichkeit anbieten. Diese könnte unterhalb der jeweiligen Spalte angebracht sein. Des Weiteren sollten aber die berechneten Summen von mehreren Spalten verrechnet werden können. Später wären natürlich auch die Berechnung von statistischen Kennzahlen (Median, Standardabweichung, …) denkbar. Bei den vorliegenden Daten sind reine Aggregationsfunktionen nicht ausreichend. Der Grund dafür sind die verschiedenen geographisch/ administrativen Stufen auf denen die Daten vorliegen. Ein Beispiel soll dies verdeutlichen: Tabelle 8, Auszug Tabelle ULCBigTableExplorer Die Leistungsdaten (leistungkw2011) sollen auf der Ebene Gemeindeverband mit den Bevölkerungszahlen (bev2009) verglichen werden. Die Leistungsdaten werden dafür pro Gemeindeverband zusammengezählt. Natürlich müsste dazu der Gemeindeverband Altenglan als Filter gesetzt sein. Bei den Bevölkerungszahlen ist dies nicht direkt möglich. Diese Daten beziehen sich nicht auf das Kraftwerk, sondern auf die Gemeinde und sind darum in der Tabelle redundant. Um die Summe für den Gemeindeverband zu bilden, müsste also eine Gruppierungsfunktion vorhanden sein. Die Bevölkerungszahlen würden nach der Gemeinde gruppiert aufsummiert. 64 Für die vorliegende Arbeit wurden Datenbank Views erstellt (6.1.10), damit alle Daten auf der gleichen Stufe vorliegen (Kraftwerk, Gemeinde, Gemeindeverband). Es stellt sich die Frage, ob eine Auswertung von Daten mit verschiedenen Bezugsgrössen überhaupt unterstützt werden soll. Ich würde empfehlen, zuerst ein Konzept für diese zusätzliche Funktionalität zu entwickeln. Es ist sicherlich eine Abwägung zwischen Usability, Einfachheit und Funktionsumfang zu machen. 10.6.5 AUSWERTUNGEN ÜBER DIE ZEIT Eine zentrale Anforderung bei der Analyse von Energiedaten ist die Auswertung über die Zeit. Dies wird in der momentanen Implementierung noch nicht unterstützt. Beide Komponenten können zu Beispiel noch keine Diagramme anzeigen, auf denen die zeitliche Entwicklung visualisiert wird. Die bestehenden Charts des ULCBigTableExplorer müssten erweitert werden. Auch bei der GeoMaps wären Liniendiagramme denkbar. Im Moment werden die zeitlich referenzierten Daten im ULCBigTableExplorer in Jahresspalten dargestellt. Während einer Sitzung mit dem Projektpartner wurde bereits eine mögliche visuelle Zusammenfassung der Zeitspalten diskutiert und Ideen für die grafische Benutzeroberfläche entwickelt. In der Datendefinition (DataDescription) müssten Spalten als zeitlich gebunden markiert werden können (zum Beispiel asTime()-Methode). Häufig wäre es im Bereich Energiedaten sicherlich auch nötig, aggregierte Werte über die Zeit auszuwerten. Eine Aggregationsfunktionalität für den ULCBigTableExplorer ist also eine wichtige Voraussetzung auch für die zeitbasierte Analyse. 10.6.6 SORTIERUNGSFUNKTION Eine Sortierungsmöglichkeit für die Tabelle des ULCBigTableExplorers wäre allenfalls ein nützliches Feature. Dies hängt aber natürlich sehr stark von der Analysenart ab. Ist man vor allem an aggregierten Werten interessiert, braucht es diese Funktionalität wahrscheinlich nicht. Durch die zeilenorientierte Abfrage ist eine sortierte Rückgabe der Daten aus der Datenschicht (DataSource) im Moment nicht möglich. 10.6.7 CHARTS Die Charts im ULCBigTableExplorer visualisieren im Moment immer die Anzahl der Datensätze bzw. Kraftwerke. Wie unter 10.6.5 schon erwähnt wären für die Analyse auch andere Aspekte wichtig. Zum Beispiel könnten in einem Säulendiagramm auch die aggregierten Leistungswerte eines Kraftwerktyps visualisiert werden. 65 10.6.8 EXPORTFUNKTIONALITÄT Bis jetzt gibt es keine Exportfunktionalität. Insbesondere für den ULCBigTableExplorer wäre diese Funktionalität aber sinnvoll. Es wäre zum Beispiel ein Export der Tabelleninhalte und der Diagramme denkbar. 10.6.9 VOLLSTÄNDIGE INTEGRATION DER KOMPONENTEN Die vorliegende Arbeit widmete sich der datenorientierten Integration der Komponenten. Im Prototyp wird eine Selektion in der einen Komponente nicht in der anderen Komponente reflektiert. Im API besteht bis jetzt keine Möglichkeit auf einer Filterkomponente einen Listener zu definieren und damit die Kategorieauswahl zu propagieren. Canoo plant für die Zukunft eine vollständige Integration der Komponenten. Im ULCBigTableExplorer wäre die ULCGeoMaps als Kategoriepanel denkbar. Die geographische Filterung könnte dann mittels der Karte geschehen. Eine andere Möglichkeit wäre, die Tabelle mit der Karte zu ersetzen und die gefilterten und aggregierten Werte in ihrer geographischen Entität zu visualisieren. 10.6.10 DIREKTE DATENBANK ABFRAGEN Wie im Abschnitt 10.6.1 erwähnt, fehlt im Moment die Möglichkeit direkt Abfragen für die Datenbank zu generieren. Die Datenanbindungsschicht hat keine Informationen über die Kategorienanwahl im GUI und ist daher nicht in der Lage direkt SQL-Statements zu erstellen. Es soll an einem Beispiel erläutert werden, was genau gemeint ist und welche Herausforderungen sich bei einer Implementierung datenbankseitig ergeben würden. Anfragegeschwindigkeit wurden direkt in einem SQL Client gemacht. Abbildung 13, Kategorieanwahl ULCBigTableExplorer 66 Alle Messungen der Die in Abbildung 13 ersichtliche Anwahl der Kategorien, müsste in folgende Datenbankabfrage übersetzt werden: SELECT SQL_NO_CACHE * FROM view1 WHERE gemeindeverband = "Bernkastel-Kues" AND energietraeger = "SOL" AND leistungkw2011 > 5 AND leistungkw2011 <10 LIMIT 35; Das Resultat der Anfrage würde dann in der Tabelle dargestellt. Die Anfrage läuft, auch ohne Indices auf den Spalten, auf dem bestehenden Kraftwerks-View schnell (<0.03 s). Für die Tabellenansicht des ULCBigTableExplorer wäre die Möglichkeit direkt Abfragen zu bilden gut geeignet. Etwas schwieriger würde sich eine Abfrage für die Information über die Anzahl verbleibender Datensätze gestalten. Diese steht jeweils hinter dem Kategoriennamen. Wenn von der Verbandsgemeinde "Bernkastel-Kues" auf die Verbandsgemeinde "Manderscheid" gewechselt würde, bräuchte es folgende Abfrage um diese Information zu besorgen: SELECT count(*) FROM view1 WHERE gemeindeverband = "Manderscheid" energietraeger = "BIO" UNION SELECT count(*) FROM view1 WHERE gemeindeverband = "Manderscheid" energietraeger = "DEP" UNION […] UNION SELECT count(*) FROM view1 WHERE gemeindeverband = "Manderscheid" energietraeger = "SOL" AND leistungkw2011 < 5 […] UNION SELECT count(*) FROM view1 WHERE gemeindeverband = "Manderscheid" energietraeger = "SOL" AND leistungkw2011 > 1000; AND AND AND AND Die Abfrage muss also für alle Kategorien die Anzahl der verbleibenden Datensätze berechnen. Sie ist damit schon etwas aufwendiger und läuft auch etwas langsamer (<0.15s). Wenn nun aber die "geo" und "energietraeger" Panels im GUI vertauscht würden, bräuchte es nach jedem Wechsel der Energieträgerkategorie für jede Gemeindekategorie ein SQL-Statement. Bei sehr vielen Kategorien 67 würde die Abfrage sicherlich lange dauern. Wahrscheinlich würde eher ein Prepared Statement gebildet und die Abfragen einzeln durchgeführt. Am Anfang des Projekts durchgeführte Versuche zeigten, bei einem Datensatz mit 500'000 Zeilen zeigten, dass die Performanz dieser Abfragen ein Problem werden kann. Eine Lösung wären Indizes. In MySQL können Indices über mehrere Spalten angelegt werden, sogenannte Multi-Column Indizes (MySQL, MySQL Mulit-Column Indices, 2011). Diese werden aber nur benutzt, wenn die Spaltenangaben im WHERE-Teil des Statements genau die gleichen sind wie beim Definieren des Indexes. Auch die Reihenfolge der Spaltennamen spielt eine Rolle. Kommerzielle DBMS bieten aber noch andere Optimierungsstrategien zum Beispiel BitMap-Indices (Burleson, 2011). Direkt SQL Anfragen für die Datenbank zu generieren, wäre für die vorliegende Datenmenge sicherlich möglich. Eine Voraggregation der Werte für die ULCGeoMaps würde wahrscheinlich Sinn machen. Dies wird für analytische Anwendungen meistens gemacht (Reber, Analyseprozesse in Datawarehouses, 2011). Die Performanz der Ad-hoc-Abfragen für die Zeilenanzahl hinter dem Kategorienamen im ULCBigTableExplorer wäre sicherlich der schwierigste Teil. Eine Anpassung der Programmierschnittstelle wäre natürlich nötig. Die DataSource-Implementierung müsste in irgendeiner Form Zugriff auf die Kategorieanwahl haben, um die Statements zu bilden. Die direkte Nutzung einer Datenbank brächte eine grössere Flexibilität bei neuen Daten und sich ändernden Kategorien. Eine Sortierung, Gruppierung und Aggregation der Werte wäre auch möglich. Insbesondere Daten eines DataWarehouses wären sicherlich schon auf die Schlüsselfakten voraggregiert. 68 11 EVALUATION COUCHDB Am Anfang des Projekts herrschte zwischen dem Auftragnehmer und dem Auftraggeber eine unausgesprochene Einigkeit darüber, dass mit einer Datenbank eine "relationale" gemeint war. Im Verlauf des Projektes entstand die Idee, eine NoSQL Datenbank zu evaluieren. Diese Kapitel beschreibt was NOSQL ist, welche grundlegenden Konzepte dahinter stehen, wie diese konkret in CouchDB umgesetzt sind und warum wir "NO" zu NOSQL gesagt haben. 11.1 WAS IST NOSQL? Der Begriff NoSQL wird im Moment häufig übersetzt als "nicht nur SQL". Die Bewegung begann 2009 und unterzwischen sind schon unzählige nicht relationale NoSQL Datenbanksysteme entwickelt worden (NoSQL-Database, 2011). "Nötig geworden sind Alternativen zu den bisherigen tabellenorientierten Datenbanken durch die Anforderungen im Internet. Datendurchsatzstarke Dienste wie Onlineshops, Blogs, News und Foren und natürlich in erster Linie Suchmaschinen und soziale Netzwerke sind gierig nach riesigen Datenmengen und flexiblen Strukturen, die einem steten Wandel unterliegen" (Kurowski, 2011). Die NoSQL Datenbank Cassandra wurde zum Beispiel von Facebook entwickelt und Open Source gemacht wurde (Apache, 2011). Hauptmerkmale dieser neuen Art von Systemen sind die Schemafreiheit, die Verteiltheit, die hohe horizontale Skalierbarkeit, die einfache Schnittstellen und einer, im Vergleich zu relationalen Systemen, abgeschwächten Konsistenz (NoSQL-Database, 2011). Populäre Datenbanken sind zum Beispiel Hadoop, MongoDB, CouchDB, Redis und Cassandra. Es gibt grob vier Arten von NoSQL Datenbanken: Dokumentenorientierte, spaltenorientierte, KeyValue-Speicher und Graphendatenbanken (Janson, 2011). Die in dieser Arbeit verwendete CouchDB ist dokumentenorientiert. Im Abschnitt 11.3.1 wird näher darauf eingegangen, wie ein solches Dokument vorliegt. 11.2 WARUM NOSQL IN DIESEM PROJEKT? Die neuen ULC-Komponenten sind im jetzigen Stand darauf ausgelegt, die Daten von einer Tabelle einzulesen. Bisher wurden nur CSV-Files als Datenquelle verwendet. Die Stärke einer relationalen Datenbank ist, die Daten strukturiert in Tabellen zu speichern und für Anfragen eine tabellarische 69 Menge von Datensätzen zurückzuliefern. Es soll darum zuerst erklärt werden, was die Beweggründe waren eine NOSQL Datenbank überhaupt in Betracht zu ziehen. 11.2.1 SCHNELLE ANFRAGEN NOSQL Datenbanken versprechen sehr kurze Anfragezeiten. Die Komponenten sollen in der Lage sein, grosse Datenmengen zu analysieren und sind daher auf kurze Antwortzeiten von Seiten der Datenbank angewiesen. 11.2.2 SCHEMAFREIHEIT Die Daten, wie sie im Moment vorliegen, sind nicht der finale Stand. Es werden laufend neue Informationen dazukommen. Der Projektpartner wünschte daher eine einfache Erweiterbarkeit der Datenbankschemata. Durch die Schemafreiheit verfügen NOSQL Datenbanken über eine hohe Flexibilität bei der Speicherung von Daten. Im Kapitel 11.3.1 wird dies näher erklärt. 11.2.3 KATEGORISIERUNG AUF DER DATENBANK Die evaluierte NOSQL Datenbank CouchDB bietet die Möglichkeit, die Datendokumente in einer sogenannten Map-Funktion aufzubereiten. Dadurch wäre es möglich die Kategorisierung auf der Datenbank zu erledigen. Insbesondere bietet dies den Vorteil, dass der dafür angelegte B-Tree Index immer auf dem aktuellen Stand ist. 11.2.4 GRAILS PLUGIN Es besteht ein Grails-Plugin mit dessen Hilfe man schnell Daten in CouchDB speichern kann. Auch das Auslesen der Dokumente wird unterstützt. 11.2.5 KNOW-HOW NoSQL Datenbanken waren für den Autor der Arbeit und Canoo noch Neuland. Die Beantwortung der Frage, ob eine NOSQL Datenbank für den in dieser Arbeit beschriebenen Anwendungsfall geeignet ist, sollte auf beiden Seiten zu einem Know-How Gewinn führen. 11.3 KONZEPTE VON NOSQL 11.3.1 SCHEMAFREIHEIT Bei CouchDB wird vor der Speicherung kein Schema angelegt. CouchDB ist schemafrei. Die Daten werden in JSON (siehe 15.3) Dokumenten gespeichert. Beispiel: 70 Abbildung 14, Beispiel CouchDB Dokument im JSON Format Das oben dargestellte Dokument hat ein type Attribut mit dem Wert "couchkraftwerk". Dieses Attribut ist aber wie alle anderen (ausser _id und _rev) optional. Es wird nur eingefügt, um beim Verarbeiten oder Abfragen der Dokumente die Art des Datensatzes zu bestimmen. Es ist auch ersichtlich, dass bei einem JSON-Dokument komplexe Members möglich sind. So ist zum Beispiel der Wert des Attributs "karftwerkL" ein Array ([]) und die einzelnen Elemente davon Objekte ({}). Diese Objekte haben hier die gleiche Struktur. Sie könnten aber auch ganz andere Attribute haben. Beim Einfügen eines neuen Dokuments wird dessen Struktur und Inhalt nicht beachtet. Es können also völlig verschiedene Dokumente gespeichert werden. Das Konzept von Primär und Fremdschlüsseln kennt eine NOSQL Datenbank nicht. Wenn eine Referenz auf ein anderes Dokument nötig ist, wird dieses in einem Attribut gespeichert, wie im obigen Beispiel beim Attribut "gemeinde_id". Das Joining der Dokumente muss im Client geschehen, CouchDB und andere NoSQL Datenbanken bieten dies aus Gründen der Skalierbarkeit nicht an. 71 11.3.2 CAP THEOREM Die Abkürzung steht für Consistency, Availability und Partition Tolerance. Consistency Die Konsistenz von Daten ist eine zentrale Anforderung die normalerweise an ein Datenbanksystem gestellt wird. "Zusammengefasst geht es darum, dass zwei Nutzer immer denselben Datenbestand eines Systems sehen *…+" (Janson, 2011). In der NoSQL Welt ist diese Konsistenz bei gewissen Datenbanken, so auch CouchDB, abgeschwächt. Man spricht von "eventually consistent ", das (CouchDB, 2011) heisst eine konsistente Sicht wird nicht immer garantiert. Dies soll zu einer höheren Skalierbarkeit führen (Janson, 2011). Availability Die Availability ist die Verfügbarkeit eines Datenbanksystems. Eine Kopie des Datensatzes sollte also möglichst immer abrufbar sein. Partition Tolerance Die Datenbank kann einfach auf mehreren Servern verteilt werden. "In einem Netzwerk von Datenbanken muss gewährleistet sein, dass das ganze System auch dann funktioniert, wenn einige Nachrichten untereinander verloren gehen" (Kurowski, 2011). "Das CAP Theorem besagt, dass in verteilten Datenbanken immer nur zwei der drei Anforderungen (Consistency, Availability, Partition Tolerance) gleichzeitig erfüllt sein können (Janson, 2011)". In CouchDB wurde die Konsistenz abgeschwächt zu Gunsten der Verfügbarkeit und Partition Tolerance. CouchDB erstellt bei jedem Update eine Kopie des Dokuments, mit einer neuen Versionennummer. Die Clients die in der Updatephase zugreifen, bekommen das alte Dokument geliefert. CouchDB macht also keinerlei Locks auf die Dokumente. Somit haben die Updates wenig Einfluss auf die Anfrageperformanz. Dieses Konzept der Nebenläufigkeitskontrolle wird mit MVCC abgekürzt. Die Abkürzung steht für "Multi-Version Concurrency Control" (CouchDB, 2011). 11.3.3 MAP/ REDUCE Das Map/ Reduce Konzept wurde bei Google entwickelt um grosse Datenmengen zu verarbeiten, wie zum Beipiel beim Aufbauen eines Dokumentenindexes. Die Daten werden dabei auf vielen Rechnern parallel verarbeitet (Ghemawat, 2007). "Die Verteilte Verarbeitung erfolgt in zwei Schritten. Im 72 ersten Schritt berechnet eine Map-Funktion lokal Zwischenergebnisse und legt sie ab, im zweiten Schritt werden diese durch eine Reduce-Funktion zum Gesamtergebnis zusammenfasst" (Janson, 2011). In CouchDB wird Map/ Reduce eingesetzt, um Views zu generieren. An diese Views werden anschliessend Abfragen geschickt. Ad-Hoc Abfragen kennt CouchDB nicht. Das Prinzip lässt sich am Besten an einem Beispiel erklären. Diese Map-Funktion bekommt jedes Dokument als Eingabewert (Variable: doc). Hier wird überprüft, ob das type-Attribut des jeweiligen Dokuments den Wert "ogeodb" hat. Es sollen also nur Dokumente dieses Typs in den View eingefügt werden. Danach wird die implizit vorhandene emitFunktion aufgerufen. Diese "emittiert" ein Schlüssel/ Wert Paar pro Dokument. Abbildung 15 zeigt einen Ausschnitt der erzeugten Schlüssel Wert Paare. Abbildung 15, Beispiel CouchDB View In der emit-Funktion wurde der asciiGemeindename als Schlüssel angegeben. Als Wert wurde ein JSON-Objekt mit PLZ-Array und Gemeindename definiert. Beim Schlüssel ist standardmässig auch die ID des Dokuments gespeichert, von dem dieses Schlüssel/ Wert Paar emittiert wurde. Die View Einträge werden von CouchDB nach dem Schlüssel sortiert. Die Reduce-Funktion ist optional und wurde hier weggelassen. Der View kann nun mit einem HTTP-GET Request abgefragt werden. http://localhost:5984/eeg/_design/eeg/_view/ogeodb_asciiname?key="AACH" Hier wird nach dem Schlüssel "AACH" abgefragt. Das Resultat sieht wie folgt aus: 73 {"total_rows":3801,"offset":0,"rows":[ {"id":"ce341e743bd99efb4595d0247d2fe2ed", "key":"AACH", "value":{"plz":[54298],"gemeindename":"Aach bei Trier"}} ]} Das Resultat wird auch im JSON Format zurückgeliefert. Da der Key auch immer die ID des Dokuments enthält, kann mittels dem URL-Parameter include_docs=true das vollständige Dokument geladen werden. http://localhost:5984/eeg/_design/eeg/_view/ogeodb_asciiname?key="AACH"& include_docs=true Resultat: {"total_rows":3801,"offset":0,"rows":[ {"id":"ce341e743bd99efb4595d0247d2fe2ed", "key":"AACH", "value":{"plz":[54298],"gemeindename":"Aach bei Trier"}, "doc":{"_id":"ce341e743bd99efb4595d0247d2fe2ed", "_rev":"10001c7549d90190b549dadcc284bc755", "asciiGemeindename":"AACH", "gemeindename":"Aach bei Trier", "gemeindeschluessel":7235001, "level":6,"locId":13351, "parentLocId":244, "plz":[54298], "type":"ogeodb"}} ]} Falls auf alle Keys bzw. Gemeindenamen abgefragt werden soll die mit A beginnen, muss dies mit der folgenden URL geschehen: http://localhost:5984/eeg/_design/eeg/_view/ogeodb_asciiname? startkey="A"&endkey="A\u9999" Es wird vom startkey A bis zum endkey A\u9999 abgefragt. \u9999 ist der letzte Unicode Codepoint. Dies wird als Collation bezeichnet (CouchDB, View Collation, 2011). Als Schlüssel können Map-Funktionen auch Arrays und Objekte emittieren. Das folgende Bespiel zeigt wie ein Array-Schlüssel und die Collation genutzt werden können. 74 Die Map-Funktion emittiert Dokumente mit dem Regionalschlüssel und dem Wert 1. Das Attribut rs der Dokumente ist ein Array der Länge 5. Darin sind die verschiedenen Teile des im Kapitel 5.3.1 bereits erläuterten Regionalschlüssels gespeichert. Die Reduce-Funktion sieht wie folgt aus: Die Funktion bekommt den Schlüssel (key) und alle Werte dieses Schlüssels (values) als Array. Die in CouchDB implizit vorhandene Methode sum() summiert die Werte auf. Dies ist möglich weil die Werte ja numerisch sind, nämlich immer 1. Da der Regionalschlüssel eindeutig ist, macht die Aufsummierung auf den ersten Blick keinen Sinn. Jeder übergebene Schlüssel hat ein values-Array mit dem einzigen Wert 1. Es gäbe also nicht aufzusummieren. Abbildung 16 zeigt dies. Abbildung 16, Beispiel Grouping CouchDB CouchDB bietet nun die Möglichkeit nur auf einen Teil des Array-Schlüssels abzufragen. Dazu muss der group_level angegeben werden. Hier ein Beispiel mit group_level=1: Abbildung 17, Beispiel 2 Grouping CouchDB 75 Hier wird die Anzahl der Schlüssel angegeben die mit "07" anfangen. Es gibt offensichtlich 2557 geographische Einheiten (Landkreise, Gemeinden…) inkl. dem Bundesland (Schlüssel ["07","","","",""]) in Rheinland Pfalz. Ein zweites Beispiel mit dem group_level=2 soll das Prinzip veranschaulichen. Abbildung 18, Beispiel 3 Grouping CouchDB Offensichtlich gibt es drei Regierungsbezirke in Rheinland Pfalz. Diese haben 1209, 592, 755 weitere geographische Einheiten. Die entsprechende Abfrage-URL wäre: http://localhost:5984/eeg/_design/eeg/_view/geo_counts?group_level=2 11.3.4 VOR- UND NACHTEILE VON COUCHDB GEGENÜBER RELATIONALEN SYSTEMEN Bei CouchDB müssen Joins von Dokumenten beim Client gemacht werden. Die Datenbank hat diese Funktionalität nicht. Dies ist ein fundamentaler Unterschied zu der relationalen Welt. Als Alternative würde sich anbieten, alle Daten die vorhanden sind in ein Dokument zu legen. Der Nachteil dieses Ansatzes ist, dass grundsätzlich immer das ganze Dokument geladen würde. Für bekannte Projektionen könnten allenfalls Views erstellt werden, in denen nur ein Teil der Attribute zurückgeliefert werden. Ein weiteres Problem ergibt sich beim Ändern eines Eintrags in einem grossen Dokument. In CouchDB wird durch die Verwendung von MVCC (siehe 11.3.2) bei jeder Änderung eine Kopie des Dokuments mit einer anderen Revisionsnummer angelegt. Bei einer Replikation führt dies zu erhöhtem Aufwand. Ein einzelnes neues Dokument mit einem Verweis auf ein anderes Dokument wäre einfacher zu replizieren (kleinere Datenmenge; noch keine Revisionen). Eine wichtige Einschränkung ergibt sich auch beim Abfragen von Daten. In CouchDB sind keine AdHoc Abfragen möglich. Für jede Abfrage, ausser derjenigen auf die ID und die kompletten Daten, müssen Views erstellt werden. 76 Ein wichtiger Unterschied zu relationalen Systemen ist, dass eine Multi-Range Abfrage nicht direkt möglich ist. Eine SQL-Abfrage wie zum Beispiel: SELECT * FROM Kraftwerksdaten WHERE kw >2 AND kw<= 5 AND (energietraeger = "SOL" OR energietraeger = "BIO"); wird in CouchDB nicht unterstützt. Auch mit einem Array-Schlüssel ist dies nicht möglich. Eine MapFunktion könnte die folgenden Schlüssel emittieren: ["BIO", 2.5] ["BIO", 6] ["SOL", 1.5] ["SOL", 3] ["SOL", 5.5] Die Abfrage mit einem startkey = ["BIO", 2] und einem endkey = ["SOL", 5] würde alle violetten Dokumente liefern. ["BIO", 6] und ["SOL", 1.5] dürften nach dem SQL-Ausdruck natürlich nicht zurückgeliefert werden. Auch das Drehen der Schlüssel bringt keine Lösung. Solange ich nur auf einen Attributwert, also zum Beispiel "BIO" abfrage, wäre ein Array-Schlüssel zielführend. Im hier gezeigten Fall müssten aber zwei Views erstellt werden. Einer würde die Abfrage des Energietyps und ein anderer die Abfrage eines kW-Ranges ermöglichen. Der Client müsste dann eine Schnittmenge der IDs bilden. Ein Array-Schlüssel ist auch nur möglich, wenn die Attribute die zusammen abgefragt werden, bekannt sind. Auch ein relationales System lässt sich aber nur schwer auf diese Situation optimieren. Multi-Key-Indices in MySQL nützen nur etwas, wenn die Attribute und deren Reihenfolge im SQL-Statement bei der Index-Generierung bekannt sind (siehe auch 10.6.10). 11.4 ERGEBNIS CouchDB wurde für das bestehende Projekt als zu wenig flexibel eingestuft. Es können wie beschrieben keine Ad-hoc und Multi-Range Abfragen gemacht werden. Insbesondere am Schluss des Projekts konnten, durch die Verwendung von MySQL, dem Projektpartner schnell einige Daten zusammengezogen und als Excel-File exportiert werden. Dies wäre mit CouchDB viel schwieriger gewesen. Für jede Abfrage muss ein View programmiert werden. Die Komponenten können der Datenanbindungsschicht im Moment noch nichts über die Kategorieauswahl mitteilen (siehe 10.6.1 und 10.6.10). Damit hätten die CouchDB Views noch nicht genutzt werden können. Die JOINs der zusammengehörenden Dokumente hätte im Client gemacht werden müssen. Diese Funktionalität bietet eine relationale Datenbank "out-of-the-box". 77 Der Projektpartner wollte nach dem Ende des Projekts die Datenbank weiterverwenden. Er hat bereits Erfahrung mit relationalen Systemen. CouchDB hätte es schwieriger gemacht die Daten weiterzuverwenden. Es gibt auch nur wenige Tools. Die Datenbank wurde dem Projektpartner unterzwischen bereits in Access eingespielt und zugestellt. Aus diesen Gründen haben wir NO zu NoSQL gesagt. 78 12 FAZIT 12.1 FACHLICHES Eine gemeinsame Nutzung des ULCBigTableExplorer und der ULCGeoMaps ist möglich. Die Komponenten sind schon weit entwickelt. Insbesondere ist die Bedienung sehr einfach. Die Arbeit konnte aufzeigen, dass die Integration mit einer Datenbank noch nicht sehr elegant möglich ist. Dies hat vor allem mit den unterschiedlichen Abfragecharakteristikas der Komponenten zu tun. Auch ist die Datenanbindungsschnittstelle noch sehr fileorientiert. Es fehlt eine direkte Möglichkeit SQL zu bilden. Die Integration in Grails war möglich. Die fehlende Performanz für die, von der Schnittstelle vorgegeben, Einzelabfragen ist sicherlich teilweise auf das "Object Relational Mapping" (ORM) des Frameworks zurückzuführen. Native SQL Abfragen wären schneller. Es sollte aber trotzdem die Unterstützung für Mengenabfragen geben, da der Zeitbedarf ausserhalb des optimierbaren Bereichs liegt. Grails war insbesondere bei der Datenintegration sehr hilfreich. Das Anlegen von Datenbanktabellen übernimmt das Framework. Auch konnten die Daten bzw. Objekte sehr einfach gespeichert und wieder ausgelesen werden. Der Prototyp hat gezeigt, dass die Auswertung der vorliegenden Energiedaten noch nicht in ausreichendem Mass, durch die Komponenten, unterstützt wird. Insbesondere fehlt die Möglichkeit eine Zeitreihenanalyse zu machen. Der ULCBigTableExplorer sollte ausserdem Aggregationen und Berechnungen erlauben und seine Charting-Möglichkeiten auch dahingehend erweitern. Das Exportieren der Analyseergnisse müsste in Zukunft ebenfalls möglich sein. Für den Prototyp wurden die Komponenten nur datenmässig integriert. Eine weitergehende Integration ist wichtig und auch schon in Planung. 12.2 PROJEKTABLAUF Es war möglich, das Projekt rechtzeitig und im geplanten Umfang abzuschliessen. Die Planung wurde aber nicht überall eingehalten. Insbesondere wurde die Datenintegration unterschätzt. Das Gemeindemapping war schwieriger als erwartet. Zeitweise musste zwischen den teilweise divergierenden Zielen des Projektpartners und des Auftraggebers eine Abwägung stattfinden. Bei der 79 Datenaufbereitung wären einige weitere Anpassungen möglich gewesen, es musste aber ein Schlusspunkt gesetzt werden, um den Zeitplan zu erfüllen. Eine weitere kritische Komponente bei diesem Projekt war die Abhängigkeit zu den anderen Projekten. Gemeint sind die Arbeiten an den Komponenten. Insbesondere der ULCBigTableExplorer war noch stark in Entwicklung. Auch war zu Beginn meines Projekts die gemeinsame Datenanbindungsschicht noch nicht vorhanden. Kurz vor dem Start der Prototyp Entwicklung wurde diese, in einer ersten Version, fertig. Dieses Projektrisiko wurde durch einen intensiven Austausch mit den anderen Studierenden beherrscht. Die grosse Hilfsbereitschaft der anderen Studierenden war hier spielentscheidend. Die Integration der Komponenten mit Grails dauerte länger als erwartet. Für die reine Komponentenintegration hätte der Verzicht auf Grails etwas mehr Zeit für die zusätzliche Entwicklung gelassen. Insbesondere ein Versuch direkt, aufgrund der Kategorieanwahl im GUI, Datenbankabfragen zu generieren wäre spannend gewesen. Am Schluss des Projekts kamen insbesondere vom Projektpartner teilweise zusätzliche Anforderungen, die sich aber vor allem auf die Funktionalität der Komponenten bezogen. Das in Kapitel 10.3 beschriebe Datenauswahl-GUI wurde noch umgesetzt, andere Wünsche mussten teilweise abgelehnt werden. 12.3 ZIELERREICHUNG Die Energiedaten konnten erfolgreich integriert werden. Bei einer Zwischenpräsentation mit dem Projektpartner wurde von diesem der Wert insbesondere der Gemeindemapping-Heuristik herausgehoben. Die Daten im Bereich der Energieberatung sind immer lokalisiert. Häufig fehlt aber ein eindeutiges Identifikationselement. Der Projektpartner erhielt bereits einige Excel-Auszüge aus der Datenbank und die Daten wurden in eine Access-Datenbank kopiert. Damit könne die Daten unabhängig vom Prototyp flexibel weiter verwendet werden. Insbesondere für die Programmierschnittstelle und die Funktionalität lieferte die Prototyperstellung neue Anforderungen. Auch konnten die Schwierigkeiten der Anbindung einer Datenbank aufgezeigt werden. 80 12.4 PERSÖNLICHES FAZIT Das Lernen von neuen Technologien war spannend. Die Programmierung in Groovy war zunächst eine Herausforderung. Die Lernkurve war aber flach, insbesondere dank den hilfsbereiten und kompetenten Canoo Mitarbeitenden. Bei bisherigen Entwicklungen startete ich meistens "auf der grünen Wiese". Hier war dies nicht so. Ich musste den Code der Komponenten kennenlernen. Dies dauerte seine Zeit und war eine spannende Erfahrung. Das Arbeiten bei Canoo hat Spass gemacht. Die unaufgeregte Art wie bei Canoo Software erstellt wird, hat mich beeindruckt. Was ich "Problem" nannte war für die Canooies eine spannende "Herausforderungen". 81 13 DANK Vielen Dank an Dieter Holz und Canoo Engineering in Basel für den spannenden Auftrag. Ich fühlte mich sehr gut betreut und kann einiges fachliches und persönliches vom Kirschgarten mitnehmen. Mein Dank geht insbesondere auch an die Mitarbeitenden von Canoo, genannt Canooies. Eure Kompetenz und Hilfsbereitschaft war umwerfend. Danke auch meinen beiden Mitstreitern Franz-Josef Wiszniewsky und Christoph Bräunlich für die Entwicklung der super Komponenten, die Hilfe beim Bug-Fixing und die Beantwortung meiner Fragen. Danke auch an Professor Dr. Bradley Richards für die Betreuung von Seiten der Fachhochschule. Danke auch meiner Partnerin Helena, und einen Kindern Milan und Hanna. Papa ist wieder verfügbar… 83 14 LITERATURVERZEICHNIS Apache. (2011). Cassandra. Abgerufen am 31. 08 2011 von http://cassandra.apache.org/ Bräunlich, W. (2011). Präsentationsunterlagen BigTableDataProvider. Basel. Burleson. (2011). Oracle Bitmap Index Techniques. Abgerufen am 31. 08 2011 von http://www.dbaoracle.com/oracle_tips_bitmapped_indexes.htm Canoo. (2011). ULCArchitectureGuide. Abgerufen am 19. 08 2011 von http://ulc.canoo.com/developerzone/ULCArchitectureGuide.pdf CouchDB. (2011). CouchDB Guide. Abgerufen am 22. 08 2011 von http://guide.couchdb.org/draft/consistency.html CouchDB. (2011). View Collation. Abgerufen am 29. 08 2011 von http://wiki.apache.org/couchdb/View_collation Fürst, M. (11 2006). Bluegate Communications. Abgerufen am 01. 08 2011 von Nested Sets verstehen und anwenden: http://www.bluegate.at/index.php?id=16&type=1 Ghemawat, J. D. (2007). Distributed Programming with MapReduce. In A. O. Wilson, Beautiful Code (S. 371-384). Sebastopol: O'Reilly. Janson, R. (01 2011). NoSQL Alternative zu relationalen Datenbanken. iX Developer , S. 132-136. json.org. (2011). JSON.org. Abgerufen am 29. 08 2011 von http://www.json.org/ Koenig, D. (2007). Groovy in Action. New York: Manning. Kurowski, O. (01 2011). NoSQL-Datenbanken, Teil 1: CouchDB. PHPMagazin , S. 52-58. Ledbrook, G. S. (2009). Grails in Action. Greenwich: Manning. Martin Theus, S. U. (2009). Interactive Graphics for Data Analysis. Boca Raton: Chapman & Hall. MySQL. (2011). MySQL Dokumentation. Abgerufen am 1. 08 2011 von Foreign Keys: http://dev.mysql.com/doc/refman/5.0/en/ansi-diff-foreign-keys.html 84 <Literaturverzeichnis MySQL. (2011). MySQL Mulit-Column Indices. Abgerufen am 26. 08 2011 von http://dev.mysql.com/doc/refman/5.0/en/multiple-column-indexes.html NoSQL-Database. (2011). NoSQL Database. Abgerufen am 23. 08 2011 von http://nosqldatabase.org/ OpenGeoDB. (2011). OpenGeoDB. Abgerufen am 01. 08 2011 von http://opengeodb.giswiki.org/wiki/OpenGeoDB Reber, A. (2011). Analyseprozesse in Datawarehouses, Vorlesung Entscheidungsunterstützung, File EUS06-DWH-Analyse.ppt. Abgerufen am 22. 08 2011 von Lernplattform Fachhochschule Nordwestschweiz: https://moodle.fhnw.ch/course/view.php?id=3620 Reber, A. (2010). Modellierung von Datawarehouses. Abgerufen am 22. 08 2011 von Lernplattform Moodle Fachhochschule Nordwestscheiz: https://moodle.fhnw.ch/mod/resource/view.php?id=87931 Stackoverflow. (2011). Abgerufen am 05. 08 2011 von http://stackoverflow.com/questions/4048151/what-are-the-options-for-storing-hierarchical-data-ina-relational-database Wikipedia. (2011). Amtlicher Gemeindeschlüssel. Abgerufen am 04. 08 2011 von http://de.wikipedia.org/wiki/Amtlicher_Gemeindeschl%C3%BCssel Wikipedia. (2011). Levenshtein-Distanz. Abgerufen am 19. 08 2011 von http://de.wikipedia.org/wiki/Levenshtein-Distanz Yahoo. (2011). Yahoo Placefinder. Abgerufen am 11. 07 2011 von http://developer.yahoo.com/geo/placefinder/guide/responses.html 85 15 GLOSSAR/ TECHNOLOGIEN 15.1 CLOSURE "Eine Closure ist ein als Objekt verpacktes Codestück. Sie verhält sich insofern wie eine Methode, als sie Parameter entgegennehmen und einen Wert zurückgeben kann, und sie ist insofern ein Objekt, als sie wie jedes Objekt als Referenz übergeben werden kann" (Koenig, 2007, S. 112). 15.2 LEVENSHTEIN-DISTANZ "Die Levenshtein-Distanz zwischen zwei Zeichenketten ist die minimale Anzahl von Einfüge-, Löschund Ersetz-Operationen, um die erste Zeichenkette in die zweite umzuwandeln. Benannt ist die Distanz nach dem russischen Wissenschaftler Wladimir Lewenstein, der sie 1965 einführte. *…+ Beispielsweise ist die Levenshtein-Distanz zwischen „Tier“ zu „Tor“ 2. Eine mögliche Folge von 2 Operationen ist: Tier, Toer (Ersetze i durch o), Tor (Lösche e) In der Praxis wird die Levenshtein-Distanz zur Bestimmung der Ähnlichkeit von Zeichenketten beispielsweise zur Rechtschreibprüfung oder bei der Duplikaterkennung angewandt" (Wikipedia, Levenshtein-Distanz, 2011). 15.3 JSON JSON ist ein leichtgewichtiges Datenaustauschformat. Es ist von Menschen einfach zu lesen. Es kann ausserdem einfach von Computern generiert und konsumiert werden (json.org, 2011). 15.4 GROOVY "Groovy is an agile dynamic language for the Java Platform with many features that are inspired by languages like Python, Ruby and Smalltalk, making them available to Java developers using a Java-like syntax" (Koenig, 2007, S. 4) . 15.5 GRAILS WEBFRAMEWORK Grails ist ein Webframework, dass ein Rapid Application Development von Webapplikationen ermöglicht. Es wurde in Anlehnung zum Ruby on Rails Framework entwickelt und baut auf den gleichen Konzepten auf, insbesondere "Convention over Configuration" und "DRY" (Don't Repeat 87 Glossar/ Technologien Yourself). Grails braucht sehr wenig Konfiguration, da Vorgabewerte vorhanden sind oder die Konfigurationswerte aus dem Quellcode abgeleitet werden. Ausserdem soll sich der Programmierer nicht wiederholen. Der Applikationsentwickler schreibt das Programm in der Sprache Groovy oder wahlweise auch in Java. Unter der Haube setzt Grails auf bekannte Java Frameworks: Hibernate, Spring, Log4J, Sitemesh, um einige zu erwähnen und ist damit auch für den Enterprise Einsatz attraktiv. Canoo nutzt Grails ausgiebig und trägt auch zu dessen Weiterentwicklung bei (Ledbrook, 2009). 15.6 CANOO ULTRA LIGHT CLIENT (ULC) Canoo Engineering AG hat ein Java-basiertes Framework zur Entwicklung von Rich Internet Applikationen (RIA) entwickelt. Ein reichhaltiges Set von GUI-Komponenten ermöglicht das schnelle Erstellen von leistungsfähigen und effizienten Applikationen (Canoo, 2011). 15.7 MYSQL MySQL ist eine Open Source Datenbank die vor allem im Webbereich grosse Verbreitung gefunden hat. 88 16 ANHANG 16.1 QUELLDATENFILES 16.1.1 GEMEINDEVERZEICHNIS RHEINLAND PFALZ Dies ist ein Auszug aus den Gemeindedaten des deutschen statistischen Bundesamtes. Filename: GV100AD Gemeindeverzeichnis Auszug Rheinland Pfalz.xlsx Stand: 31.03.2011 Quelle: Statistisches Bundesamt URL Quellen: <http://www.destatis.de/jetspeed/portal/cms/Sites/destatis/Internet/DE/Conte nt/Statistiken/Regionales/Gemeindeverzeichnis/Administrativ/AdministrativeUebersicht.ps ml> bzw. http://www.destatis.de/jetspeed/portal/cms/Sites/destatis/Internet/DE/Content/Statistiken /Regionales/Gemeindeverzeichnis/Administrativ/Archiv/GV2000VJ/1Q__31032011__Auszug ,property=file.xls Filegenerierung: GV100AD Gemeindeverzeichnis Auszug.xls: Filter auf den Regionalschlüssel von Rheinland Pfalz (Regionalschlüssel beginnt mit "07"). Filekonvertierung: Excel als csv gespeichert; erste sieben Zeilen gelöscht; neue Zeilen zwei und drei gelöscht: 50;50;07;0;00;9999;;Gemeinsames deutsch-luxemburgisches Hoheitsgebiet;;;;;;;; 60;66;07;0;00;9999;999;Gemeinsames deutsch-luxemburgisches Hoheitsgebiet; 6.20;31.12.2009; 0; 0; 0; 0;; File zu UTF-8 konvertiert (notepad++) Qualität: 1a 16.1.2 EEG-KRAFTWERKSDATEN RHEINLAND PFALZ Filename: EEGDatenRLP.xlsx Stand: Anlagenstammdaten: 19.5.2011, Ertragsdaten: 31.12.2009 89 Anhang Quelle: Amprion Gmbh, Unternehmenskommunikation Rheinlanddamm 24, 44139 Dortmund URL Quellen: Link Stammdaten: <http://www.amprion.net/eeg-anlagenstammdaten-aktuell> Link Ertragsdaten: <http://www.amprion.net/eeg-jahresabrechnung-2009> im einzelnen: <http://www.amprion.net/sites/default/files/zip/Anlagenstammdaten_20110519_PLZ_5000 0_54999.zip> <http://www.amprion.net/sites/default/files/zip/Anlagenstammdaten_20110519_PLZ_5500 0_59999.zip> <http://www.amprion.net/sites/default/files/zip/Anlagenstammdaten_20110519_PLZ_6000 0_79999.zip> sowie <http://www.amprion.net/sites/default/files/zip/Anlagendetaildaten%202009%20csv.zip> Filegenerierung: Verknüpfung von Stammdaten und Detaildaten über Anlagenschlüssel; Aufsummierung von Ertrag und Erlös je Anlage; Filter auf PLZ in Rheinland-Pfalz Filekonvertierung: xls als xlsx gespeichert; xlsx als csv gepeichert; im Texteditor (Notepad++) erste Zeile entfernt und zu UTF-8 konvertiert. Qualität: 2a 16.1.3 STROMDATEN VERBANDSGEMEINDEN RHEINLAND PFALZ Name: StromVerbrauchRWE.xls Stand: 31.12.2007 (vorläufig) Quelle: RWE Essen Be- und Umrechnungen durch Projektpartner: Orginal-Sheet ungeeignet; Umstrukturierung händisch notwendig; Ergänzung mit VG-Schlüssel; Zuordnung KA-Abgabe zu Nutzergruppen lt. RWE Vollständig: Nein Fehlend: Stadt Bitburg, Stadt Wittlich, Morbach Qualität: 1b 90 16.2 INHALT DER CD Der Quelltext des Prototyps wurde auf Wunsch von Canoo Engineering AG nicht beigelegt. 16.2.1 ARBEIT Bachelorarbeit_Menz_2011.pdf Kurzzusammenfassung_Bachelorarbeit_Menz_2011.docx 16.2.2 QUELLDATEN FILES GV100AD Gemeindeverzeichnis Auszug Rheinland Pfalz modified.csv StromVerbrauchRWEModified.xls StromVerbrauchRWEModified.csv opengeodbRheinlandPfalz.csv EEGDatenRLP.csv Metadaten.xlsx Strom_RWE_gesamt.xls 16.2.3 GEMEINDEMAPPING DATEIEN MappingHelper2011-08-05.xlsx MappingHelper.csv eegMaps.xlsx eegNoMapping.xlsx Xl0000004Korrekturen.xls Xl0000004KorrekturenModified.xlsx 16.2.4 DATENBANK OUTPUT FILES KraftwerksView2011-08-05.xlsx GemeindeverbandView2011-08-05.xlsx dump.accdb dump.mdb 16.2.5 GROOVY SKRIPTEN 91 kraftwerkImportService.groovy importFlaecheBevoelkerung.groovy Anhang importMappingHelper.groovy importStromDaten.groovy laengenBreitengrade.groovy importGemeindedaten.groovy importOpenGeoDB.groovy performanceMeasurements.groovy performanceSQLviaHibernate.groovy 16.2.6 SQL SKRIPTEN 92 createGemeindeverbandsview.sql plzCount.sql ertragVerguetung.sql gemeindenAdjazenzliste.sql dropTables.sql deleteFrom.sql createKraftwerksview.sql aggregationGemeindeGemeindeverband.sql countPerformanceTest.sql createMatGemeindeView.sql createTableMatGemeindeView.sql selectGemeindeverbandAggregation.sql dump.sql