docs/document-structure (#578)
Habe per toctree die verschiedenen Dokumente in die richtige Reihenfolge gebracht. --------- Co-authored-by: Tim Ronneburg <Tim-Ronneburg@users.noreply.github.com> Co-authored-by: Sebastian <94404394+SeZett@users.noreply.github.com> Co-authored-by: Philipp Horstenkamp <philipp@horstenkamp.de> Co-authored-by: SeZett <zeleny.sebastian@fh-swf.de>
4
documentations/Ergebnisse/1_Einleitung.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Einleitung
|
||||
```{toctree}
|
||||
Abschlussbericht_und_Praesentation/SaZh/S1.md
|
||||
```
|
4
documentations/Ergebnisse/2_Recherche.md
Normal file
@ -0,0 +1,4 @@
|
||||
# Recherche
|
||||
```{toctree}
|
||||
Abschlussbericht_und_Praesentation/TiRo/S2.md
|
||||
```
|
11
documentations/Ergebnisse/3_Grundlagen.md
Normal file
@ -0,0 +1,11 @@
|
||||
# Grundlagen und Basistechniken (Tim Ronneburg)
|
||||
In diesem Abschnitt sind die Zwischenberichte des Projekts zu finden. In diesen Berichten wurde die Recherche zu den einzelnen Kategorien durchgeführt und in den entsprechenden Jupyter Notebooks im Git-Repository bewertet. Dieses Kapitel präsentiert eine detaillierte Analyse der zuvor beschriebenen Recherche mit zusätzlichen Begründungen und Erläuterungen, warum bestimmte Technologien, Konzepte und Vorgehensweisen für das Projekt ausgewählt wurden.
|
||||
|
||||
Es ist zu beachten, dass die Zwischenberichte zu einem frühen Zeitpunkt des Projektes erstellt wurden und eine Hausarbeit darstellen, weshalb in einigen Abschnitten von zukünftigen Vorgehensweisen und Ausblick gesprochen wird.
|
||||
|
||||
```{toctree}
|
||||
Zwischenbericht_und_Praesentation/PhHo/dev-ops
|
||||
Zwischenbericht_und_Praesentation/TrNo/Ausarbeitung.md
|
||||
Zwischenbericht_und_Praesentation/SeZe/00_Datenspeicherung.md
|
||||
Zwischenbericht_und_Praesentation/TiRo/verflechtungsanalyse.md
|
||||
```
|
9
documentations/Ergebnisse/4_Umsetzung.md
Normal file
@ -0,0 +1,9 @@
|
||||
# Technische Realisation
|
||||
```{toctree}
|
||||
Abschlussbericht_und_Praesentation/PhHo/05-DEV-OPS
|
||||
Abschlussbericht_und_Praesentation/TrNo/S4-2.md
|
||||
Abschlussbericht_und_Praesentation/TrNo/S4-3-1.md
|
||||
Abschlussbericht_und_Praesentation/PhHo/4-4-2-database-generator
|
||||
Abschlussbericht_und_Praesentation/TiRo/S4-5-2.md
|
||||
Abschlussbericht_und_Praesentation/PhHo/04-data-visualisation-container.md
|
||||
```
|
@ -0,0 +1,6 @@
|
||||
## Zielsetzung
|
||||
|
||||
*TO BE CONTINUED*
|
||||
|
||||
## Projektorganisation
|
||||
Ein toller Platzhalter
|
After Width: | Height: | Size: 2.6 MiB |
@ -0,0 +1,75 @@
|
||||
## Zusammenfassung
|
||||
|
||||
Die erste Projektidee zum Transparenzregister umfasste die Entwicklung einer Lösung zur Extraktion, Aufbereitung, Analyse und Visualisierung von Metadaten von Unternehmen, wobei der Fokus auf den größten deutschen und europäischen Unternehmen lag.\
|
||||
Die ermittelten Daten sollten wichtige Unternehmenskennzahlen wie Umsatz, Gewinn, Bilanzsumme, Eigenkapital, Vorstand, Aufsichtsrat, Wirtschaftsprüfer, Besitzverhältnisse und mehr umfassen. Dabei stand die Verknüpfung und Visualisierung dieser Daten im Vordergrund.
|
||||
|
||||
Die Projektziele erstreckten sich über verschiedene Fragestellungen. Die Analyse von Unternehmensverflechtungen, die Identifikation der handelnden Personen im Vorstand und Aufsichtsrat, sowie die Bewertung von Berichten über Unternehmen waren zentrale Aspekte. \
|
||||
Die Auswertung von Berichten sollte klären, ob diese positiv oder negativ sind, beispielsweise anhand von Indikatoren wie häufigen Vorstandswechseln oder Meldungen über Zielerreichung.
|
||||
|
||||
Ein weiterer Schwerpunkt war die Visualisierung der erhobenen Daten. Hierbei war eine benutzerfreundliche Suche nach Unternehmen und Personen sowie eine detaillierte Ansicht gefordert. Besonderes Augenmerk lag auf der transparenten Darstellung von Verbindungen zwischen Unternehmen und Personen durch ein Netzwerkdiagramm.
|
||||
|
||||
Um diese Projektziele zu erreichen wurde ein 14-tägiger Regeltermin mit dem Product Owner (PO) und ein 7-tägiger Regeltermin mit dem Projektteam festgelegt. \
|
||||
Zur Festlegung der Anforderungen und Umfang des Projekts wurden Domänen identifiziert, welche notwendig sind, um die gestellten Aufgaben zu erreichen.\
|
||||
Zur Organisation wurden moderne Werkzeuge zur Softwareentwicklung und Projektmanagement eingesetzt, um das Projektteam jederzeit auf dem gleichen Wissensstand, Fortschritt und weiteren Verlauf zu halten.\
|
||||
Die Teammitglieder erarbeiteten sich in der ersten Projekthälfte Expertenwissen in den Bereichen DevOps, Data-Mining, Datenvisualisierung, Datenspeicherung, Netzwerk- und Sentimentanalyse, stellten dieses in Seminarvorträgen vor und überprüften die Umsetzbarkeit mit einem ersten Proof-of-Concept zum Transparenzregister.\
|
||||
Es wurden Metriken zur Bewertung von Unternehmen definiert und erste Mock-Ups für eine GUI erstellt. Diese Konzepte wurden mit dem PO diskutiert, um eine Architektur für die Implementierungsphase zu schaffen.
|
||||
|
||||
|
||||
Die zweite Projekthälfte konzentrierte sich auf die praktische Umsetzung der Produktidee in einer professionellen Umgebung.\
|
||||
Die notwendigen Funktionen zur Datenerfassung, -extraktion, -speicherung und Visualisierung wurden in Python geschrieben und über GitHub verwaltet, wobei vorab eine CI/CD Infrastruktur geschaffen wurde.\
|
||||
In einem Präsenztermin hat das Projektteam eine Containerarchitektur erarbeitet, in welcher die Funktionen organisiert werden.
|
||||
|
||||
Die benötigten Datenbanken zur Speicherung der Staging- und Produktivdaten wurden auf dem Kubernetes-Cluster der FH gehostet. \
|
||||
Die Dockerarchitektur und die Container wurden auf einer Portainerinstanz der FH deployed.\
|
||||
Zusätzlich wurde im Projekt ein lokales Deployment umgesetzt, welches mittels docker-compose die benötigten Datenbanken und Container lokal baut, mit einem Datenbank-Dump befüllt und das Frontend bereitstellt.
|
||||
|
||||
Die wichtigsten Erkenntnisse für die Teammitglider sind in der folgenden Tabelle zusammengefasst:
|
||||
|
||||
| Ergebnisse | Herausforderungen | Erfolge |
|
||||
|----------------------------------|-------------------------------------------|-----------------------------------------------------|
|
||||
| neue SW-Tools erlernt | heterogene Gruppe auf einen Stand bringen | Continuous Deployment auf FH-Cluster |
|
||||
| Projektmanagement | offenes Projektziel | gutes Aufgaben- und Zeitmanagement |
|
||||
| Umgang mit Github | Scope Creep | erfolgreiche Implementierung und Umsetzung der Idee |
|
||||
| praktische Anwendung von CI/CD | technische Infrastruktur | sehr hohe Code Qualität |
|
||||
| Softwaretesting | viel Domänenwissen notwendig | interdisziplinäres Arbeiten |
|
||||
| funktionsfähige Software | | lokales Deployment |
|
||||
| wartbarer Code | | |
|
||||
| Netzwerkanalyse | | |
|
||||
| Umgang mit SQL/NoSQL Datenbanken | | |
|
||||
| Methoden des Data-Minings | | |
|
||||
| Dashboard-/GUI Entwicklung | | |
|
||||
| Anwendung Docker | | |
|
||||
| Softwarearchitektur | | |
|
||||
|
||||
|
||||
### Lessons Learned
|
||||
|
||||
Während des Projektverlaufs wurden wichtige Erkenntnisse und Lektionen gewonnen, die das Team in zukünftigen Projekten berücksichtigt. \
|
||||
Eine der zentralen Lektionen war die Bedeutung einer klaren Zieldefinition und -setzung. Die Festlegung und Dokumentation des Projektziels wurde zu einem entscheidenden Faktor für den reibungslosen Fortschritt.\
|
||||
Das Team erkannte die Notwendigkeit eines regelmäßigen Team-Meetings, um Ideen, Herausforderungen, Probleme und Fortschritte zu besprechen.
|
||||
Der Regeltermin führte zu kontinuierlicher Kommunikation und unterstützte den Fortschritt positiv.
|
||||
|
||||
Durch die unterschiedlichen Hintergründe der Teammitglieder gab es die Herausforderung einen gemeinsamen technischen Stand zu erreichen, um auf dieser Basis das Projekt durchzuführen.\
|
||||
Die unterschiedlichen Eigenschaften, Fähigkeiten und Wissensstände lieferten aber auch alle wichtigen Kompetenzen für ein leistungsfähiges Team.
|
||||
|
||||

|
||||
|
||||
| Rolle | Stärken | Schwächen |
|
||||
|:--------------:|-------------------------------------------------|------------------------------------------------|
|
||||
| Perfektionist | Sorgfalt, Gewissenhaftigkeit | Kontrollsucht, kann nicht delegieren |
|
||||
| Umsetzer | praktisch veranlagt, zuverlässig | unflexibel, skeptisch gegenüber neuen Methoden |
|
||||
| Macher | Mut, Pragmatismus | ungeduldig, unsensibel |
|
||||
| Erfinder | kreativ, frische Ideen | Provokateur, hält Regeln nicht ein |
|
||||
| Spezialist | Expertise | verliert sich in Details |
|
||||
| Beobachter | skeptisch, kritisch | kann demotivieren und bremsen |
|
||||
| Weichensteller | lösungsorientiert, kommunikativ, offen | zu optimistisch, verliert schnell Interesse |
|
||||
| Teamarbeiter | einfühlsam, diplomatisch, kooperativ | unentschlossen, vermeidet Konfrontation |
|
||||
| Koordinator | selbstbewusst, zielorientiert, guter Netzwerker | wirkt manipulativ, übergibt Aufgaben an andere |
|
||||
|
||||
Wir haben im vorherigen Kapitel zahlreiche Methoden, Werkzeuge und vor allem deren praktische Anwendung kennengelernt. Die Implementierung verschaffte uns wertvolle Einblicke und Fähigkeiten in moderne Softwareentwicklungsmethoden und -werkzeuge. Die Planung der Architektur führte zu einer skalierbaren Plattform, die sowohl lokal als auch in der Cloud bereitgestellt werden kann.
|
||||
|
||||
Das Projekt war äußerst anspruchsvoll und herausfordernd, jedoch war der daraus resultierende Wissensgewinn von unschätzbarem Wert. Die interdisziplinäre Zusammenarbeit im Team funktionierte hervorragend, und die Herausforderungen, denen wir gegenüberstanden, wurden als Chancen für Wachstum und Lernen betrachtet.
|
||||
|
||||
Wir möchten unseren besonderen Dank an Professor Arinir richten, der uns nicht nur fachkundig betreute, sondern auch mit seiner Expertise in Softwareentwicklung, Methodik und Management entscheidende Impulse setzte. Seine konstruktive Kritik und Ratschläge waren von unschätzbarem Wert und trugen maßgeblich zum Erfolg des Projekts bei. Seine Unterstützung ermöglichte es uns, die gesteckten Ziele zu erreichen und darüber hinaus wertvolle Einblicke in die Welt der Softwareentwicklung zu gewinnen.
|
||||
|
||||
Trotz der Herausforderungen war das Projekt eine bereichernde Erfahrung, die nicht nur unser technisches Know-how erweiterte, sondern auch die Fähigkeit zur Zusammenarbeit und zum Problemlösen förderte. Wir blicken mit Stolz auf das, was wir erreicht haben, und freuen uns darauf, die gewonnenen Erkenntnisse in zukünftigen Projekten anzuwenden.
|
@ -1,4 +1,5 @@
|
||||
# Recherche zu benötigten Techniken (Tim Ronneburg)
|
||||
|
||||
In diesem Kapitel werden die Prämissen behandelt, welche zu Beginn des Projektes festgelegt und anhand derer eine Auswahl an benötigten Techniken getroffen wurde.
|
||||
|
||||
Die im Folgenden genannten Werkzeuge und Technologien werden an den entsprechenden Stellen später detaillierter behandelt. Dieses Kapitel dient daher als Zusammenfassung der Anforderungen mit nachfolgender Auswahl der Technologien. Diese Auswahl wird im anschließenden Kapitel 3, das die Zwischenberichte des Projekts umfasst, eingehender und ausführlicher behandelt.
|
||||
@ -18,7 +19,9 @@ Für die aufgelisteten Fragestellungen setzt sich jeweils ein Gruppenmitglied in
|
||||
Generell werden für sämtliche Aspekte die allgemeinen Leitlinien berücksichtigt. Die eingesetzten Werkzeuge und Technologien sollen Open Source sein, also frei verfügbar und ohne zusätzliche Kosten. Die Programmiersprache basiert auf Python, da sie von allen Gruppenmitgliedern beherrscht wird und die Verwendung mehrerer Sprachen das Projekt unnötig komplex machen würde. Die gewählten Technologien integrieren sich nahtlos in die Arbeitsweise mit DevOps und Git und sind durch automatisierte Tests überprüfbar. Dadurch wird eine einheitliche Arbeitsweise gewährleistet, und Engpässe durch isolierte Anwendungen werden vermieden. Schließlich legen wir Wert darauf, dass alle zu berücksichtigenden Werkzeuge einfach bedienbar sind, um einen reibungslosen Einstieg in die Technologie zu ermöglichen und die Beteiligung aller Teammitglieder zu erleichtern.
|
||||
|
||||
## Technische Anforderungen
|
||||
|
||||
Neben den allgemein geltenden Anforderungen wird in diesem Unterkapitel auf die technischen Anforderungen je Kategorie eingegangen. Die Kategorien wurden aus den oben ganannten Fragestellungen abgeleitet und entsprechen den Arbeitsbereichen der einzelnen Gruppenmitglieder sowie die Kernelemente des Projektes. Die Gruppen/Kategorien lauten:
|
||||
|
||||
- DevOps
|
||||
- Text Mining
|
||||
- Datenspeicherung
|
||||
@ -30,6 +33,7 @@ Diese Einteilung findet sich im Verlauf der Dokumentation immer wieder. Zusätzl
|
||||
Im Folgenden wird kurz auf die Kategorien eingegangen und die speziellen Anforderungen für den jeweiligen Bereich dargelegt, welche es bei der Rechereche zu betrachten galt.
|
||||
|
||||
### DevOps
|
||||
|
||||
Dieser Abschnitt befasst sich mit der Versionskontrolle des Quellcodes, automatisierten Tests und der automatisierten Bereitstellung der Anwendung auf einem Server. Im Kapitel 3.1 wird dieses Thema theoretisch und in Kapitel 4.2 praktisch behandelt, weshalb sich dieser Abschnitt auf die Anforderungen auf höchster Ebene konzentriert.
|
||||
|
||||
Bei der Implementierung von DevOps ist es entscheidend herauszufinden, welche Versionskontrollsoftware genutzt werden soll, wie DevOps darin integriert werden kann und für welche Aspekte des Projekts DevOps sinnvoll eingesetzt wird.
|
||||
@ -46,6 +50,7 @@ Unter Berücksichtigung der allgemeinen Vorgaben lauten die Prämissen für die
|
||||
- Die Technologie sollte mit Python kompatibel sein.
|
||||
|
||||
### Text Mining
|
||||
|
||||
Die Text Mining-Kategorie konzentriert sich auf das Sammeln von relevanten Unternehmensinformationen für das Projekt. Diese Daten werden im Abschnitt zur Datenspeicherung gesichert und der Projektgruppe zur Verfügung gestellt. Ähnlich wie im vorherigen Kapitel wurde dieses Thema in den Kapiteln 3.2 sowie 4.3 bis 4.4 eingehender behandelt.
|
||||
|
||||
In diesem Bereich ist es erforderlich, ein Werkzeug zu finden, das APIs aus dem Internet abfragt und die Daten entweder sichert oder transformiert. Dies betrifft insbesondere Beziehungsdaten aus dem Unternehmensregister für die Netzwerkanalyse, Stammdaten, verschiedene Nachrichten-APIs für die Stimmungsanalyse bezogen auf jedes einzelne Unternehmen sowie Finanzdaten aus dem Bundesanzeiger.
|
||||
@ -61,6 +66,7 @@ Zusammengefasst sind die Kriterien für die Technologie:
|
||||
- Die Technologie sollte mit Python kompatibel sein.
|
||||
|
||||
### Datenspeicherung
|
||||
|
||||
Für die Datenspeicherung ist die Entwicklung eines Schemas erforderlich, das nicht nur die durch Text Mining gewonnenen Daten sichert, sondern auch während der Analyse generierte Daten speichert. Zudem müssen die Daten für die Analyse und die Programm-Aufbereitung abrufbar sein. Dieser Aspekt wird im Kapitel 3.3 genauer behandelt.
|
||||
|
||||
Es wird also nach einer oder mehreren Datenbanken gesucht, die folgende Anforderungen abdecken:
|
||||
@ -77,7 +83,7 @@ Die Sentimentanalyse beinhaltet die Bewertung von Nachrichten im Hinblick auf di
|
||||
|
||||
Da eine manuelle Analyse aufgrund der großen Menge täglicher Nachrichten nicht durchführbar ist, wird nach einer Technologie gesucht, die automatisch die Daten analysiert, die Unternehmensnamen identifiziert, die Stimmung des Textes gegenüber dem Unternehmen bewertet und diese Informationen dann für die Speicherung weiterleitet. Eine weitere Schwierigkeit besteht in der Übersetzung der deutschen Nachrichten ins Englische, da für die Analyse KI-Modelle zum Einsatz kommen, die oft auf englische Texte ausgerichtet sind.
|
||||
|
||||
Zusätzlich muss der Unternehmensname standardisiert werden, sodass bei unterschiedlichen Schreibweisen dennoch dasselbe Unternehmen erkannt wird und die gewonnenen Informationen zu diesem Unternehmen angezeigt werden können. Beispielsweise wird in Artikeln häufig von VW, Volkswagen, Volkswagen AG oder dem Volkswagen Konzern gesprochen, was alles dasselbe Unternehmen repräsentiert.
|
||||
Zusätzlich muss der Unternehmensname standardisiert werden, sodass bei unterschiedlichen Schreibweisen dennoch dasselbe Unternehmen erkannt wird und die gewonnenen Informationen zu diesem Unternehmen angezeigt werden können. Beispielsweise wird in Artikeln häufig von VW, Volkswagen, Volkswagen AG oder dem Volkswagen Konzern gesprochen, was alles dasselbe Unternehmen repräsentiert.
|
||||
|
||||
Die Prämissen für die Lösungstechnologie lauten:
|
||||
|
||||
@ -89,6 +95,7 @@ Die Prämissen für die Lösungstechnologie lauten:
|
||||
- Die Technologie sollte mit Python kompatibel sein
|
||||
|
||||
### Verflechtungsanalyse
|
||||
|
||||
Die Verflechtungsanalyse konzentriert sich auf die Auswertung von Daten in Form eines Netzwerks, in dem Unternehmen und Akteure mit ihren Verbindungen zu anderen dargestellt werden. Ziel ist es, Gruppierungen zu identifizieren, die für weitere Analysen relevant sind. Diese Aspekte werden in den Kapiteln 3.5 und 4.5.2 näher erläutert.
|
||||
|
||||
Es wird daher nach einem Werkzeug gesucht, das die Akteure mit ihren Beziehungen visualisiert. Dabei ist es wichtig, dass das Tool die Positionen der Knoten und Kanten berechnet, um Überlappungen zu vermeiden. Bei großen Datenmengen können Performanzprobleme auftreten, die zu einer längeren Generierung führen. Das Tool sollte darauf ausgelegt sein, solche Probleme zu minimieren. Darüber hinaus muss es Metriken für die Analyse der Beziehungen berechnen können. Zusätzlich soll die Visualisierung des Tools in die grafische Benutzeroberfläche der Anwendung integrierbar sein.
|
||||
@ -104,6 +111,7 @@ Demnach ergeben sich folgende Anforderungen:
|
||||
- Die Technologie sollte mit Python kompatibel sein
|
||||
|
||||
### Visualisierung
|
||||
|
||||
Nachdem sich die anderen Bereiche um die Zulieferung und Aufbereitung der Daten gekümmert haben, steht in der Visualisierungsphase die Auswahl eines Frameworks für die ansprechende Darstellung der Ergebnisse im Fokus. Dies beinhaltet die Auswahl eines Frontends, das in der Lage ist, Daten in ansprechenden Grafiken zu präsentieren. Das Frontend soll auf Python basieren und webserverfähig sein. Zusätzlich sollte es benutzerfreundlich sein und nahtlos in die Netzwerkanalyse integriert werden können.
|
||||
|
||||
Die formulierten Anforderungen sind demnach:
|
||||
@ -116,6 +124,7 @@ Die formulierten Anforderungen sind demnach:
|
||||
- Die Technologie sollte kostenlos und frei verfügbar sein.
|
||||
|
||||
### Provisionierung
|
||||
|
||||
Die Provisionierung befasst sich mit der Bereitstellung der entstehenden Anwendung für die Benutzer. Dabei soll die Anwendung über das Internet erreichbar sein, jedoch durch ein Passwort geschützt werden. Aus finanziellen Gründen ist das Hosting kostenfrei und erfolgt über Container. Das Projektteam hat sich für den Container-Ansatz entschieden, um die Anwendung auf mehrere kleine Teilanwendungen zu verteilen. Diese können separat getestet und von einzelnen Projektentwicklern auch lokal ausgeführt werden.
|
||||
|
||||
Daraus ergeben sich die folgenden Prämissen:
|
||||
@ -125,9 +134,11 @@ Daraus ergeben sich die folgenden Prämissen:
|
||||
- Zugriff über das Internet für alle Projektteilnehmer mit Passwortschutz.
|
||||
|
||||
## Lösungsansätze: Überblick über relevante Technologien und Werkzeuge
|
||||
|
||||
Auf Basis der im vorherigen Kapitel festgelegten Prämissen erfolgt in diesem Abschnitt eine kurze Beschreibung der verfügbaren Technologien, gefolgt von der Auswahl der für dieses Projekt geeigneten Technologien. Wie bereits erwähnt, können detailliertere Informationen den Zwischenberichten im folgenden Kapitel 3 entnommen werden.
|
||||
|
||||
### DevOps
|
||||
|
||||
Basierend auf den oben beschriebenen Anforderungen besteht die Wahl zwischen GitHub und GitLab als Versionsverwaltungstool. Es wird auch entschieden , ob eine öffentliche Organisation verwendet wird, die Fachhochschule das Tool hostet oder ob es über einen Home Server erfolgt.
|
||||
|
||||
Nach sorgfältiger Prüfung der vorhandenen Optionen wurde die Entscheidung für die Lösung mit GitHub über die GitHub-Organisation der Fachhochschule getroffen. Diese Lösung ist naheliegend, da bereits alle Projektteilnehmenden einen GitHub-Account besitzen und gleichzeitig den Professoren und der Fachhochschule Zugriff auf den Quellcode gewährt werden kann. Darüber hinaus bleibt der Quellcode in der Verwaltung der Fachhochschule und kann späteren Studierenden zur Verfügung gestellt werden.
|
||||
@ -137,9 +148,11 @@ Diese Entscheidung bringt für das Projekt weitere Vorteile mit sich, da keine z
|
||||
GitLab steht über die Fachhochschule nicht zur Verfügung und bedeutet somit einen größeren Mehraufwand für das Projekt.
|
||||
|
||||
### Text Mining
|
||||
|
||||
Für das Text Mining konnte kein einsatzbereites, kostenloses Tool gefunden werden, das alle Anforderungen erfüllt. Daher wurde die Entscheidung getroffen, einen eigene Lösung zu entwickeln, der die erforderlichen APIs abfragt und die Daten entsprechend aufbereitet. Der Quellcode wurde in Python verfasst, und die genaue Vorgehensweise wird ausführlich im Kapitel 3.2 beschrieben.
|
||||
|
||||
### Datenspeicherung
|
||||
|
||||
Für die Datenspeicherung steht die gesamte Palette an SQL- und NoSQL-Datenbanken zur Verfügung. Basierend auf dem Kenntnisstand der Projektteilnehmer wird die Entscheidung getroffen, für den Data Lake die NoSQL-Datenbank MongoDB zu verwenden. Diese steht kostenfrei zur Verfügung, kann in Docker-Containern gehostet werden und eignet sich aufgrund ihres schemenlosen Designs gut für die unstrukturierte Speicherung von zahlreichen Daten. Außerdem kann über MongoDB Atlas eine kostenlose global verfügbare Instanz bezogen werden.
|
||||
|
||||
Für die aufbereiteten Daten wird, ebenfalls aufgrund des Kenntnisstands der Studierenden, PostgreSQL ausgewählt. Dies ist eine SQL-Datenbank, die ebenfalls in einem Docker-Container gehostet werden kann und einfach zu bedienen ist. Das Schema sowie weitere Details sind im Kapitel 3.3 nachzulesen.
|
||||
@ -147,9 +160,11 @@ Für die aufbereiteten Daten wird, ebenfalls aufgrund des Kenntnisstands der Stu
|
||||
Beide Technologien sind kostenfrei zugänglich und können mithilfe verfügbarer Bibliotheken leicht über Python angesprochen werden.
|
||||
|
||||
### Sentimentanalyse
|
||||
|
||||
Bei der Sentimentanalyse besteht eine kleinere Auswahl an möglichen Ansätzen bereit. Diese stellt unter anderem den KI Anteil des Projektes dar, weshalb hier die Analyse mithilfe eines Modells stattfindet.
|
||||
|
||||
### Verflechtungsanalyse
|
||||
|
||||
Für das Netzwerktool der Verflechtungsanalyse stehen mehrere Optionen zur Auswahl, darunter [NetworkX](https://networkx.org/), Scatter Graphen, NetworkX mit [Pyvis](https://pyvis.readthedocs.io/en/latest/), [Graphviz](https://graphviz.org/) und [Cytoscape](https://cytoscape.org/). Jedes dieser Frameworks hat seine Vor- und Nachteile. Cytoscape bietet beispielsweise ansprechende Visualisierungen, während Graphviz eine benutzerfreundliche Schnittstelle zur Erstellung von Graphen und Netzwerken bietet. Dennoch ließ sich NetworkX am besten integrieren. Es zeichnet sich durch eine einfache Bedienung aus und kann Metriken direkt berechnen. Im Vergleich dazu erfordert Graphviz, dass der Graph zuerst durch eine Methode in einen NetworkX-Graphen konvertiert wird, was zusätzliche Arbeit bedeutet.
|
||||
|
||||
Die Visualisierung mit Pyvis stellt die schönste Darstellung dar, da dem Nutzer direkte Interaktionen ermöglicht werden. Dieser kann die Nodes weiter auseinander ziehen oder in einzelne Bereiche hineinzoomen. Die Herausforderung besteht jedoch darin, dass bei großen Datenmengen die Generierung erheblich verlangsamt wird und teilweise Minuten dauert. Ein weiterer Nachteil besteht darin, dass Pyvis eine HTML-Seite mit JavaScript erstellt, die nicht nahtlos in das gewählte Visualisierungstool eingebunden werden kann. Es kann lediglich über ein IFrame eingefügt werden, was die Performance erheblich beeinträchtigt.
|
||||
@ -157,6 +172,7 @@ Die Visualisierung mit Pyvis stellt die schönste Darstellung dar, da dem Nutzer
|
||||
Daher wurde die Entscheidung getroffen, auf das native NetworkX zurückzugreifen, das mithilfe eines Plotly Scatter Graphen visualisiert wird. Hierbei werden die Positionen aus dem NetworkX-Graphen ausgelesen und in Punkte für einen Scatter Graphen transformiert.
|
||||
|
||||
### Visualisierung
|
||||
|
||||
Für das Visualisierungstool stehen verschiedene Optionen zur Auswahl, darunter Plotly Dash, Django sowie Webframeworks auf JavaScript-Basis wie Angular oder Vue.js. Da die Kenntnisse im Team hauptsächlich auf Python basieren, wurde sich trotz der vielen Vorteile von JavaScript-Frameworks gegen diese entschieden.
|
||||
|
||||
Schließlich wird aufgrund des vorhandenen Kenntnisstands und der geringeren Komplexität die Wahl auf Plotly Dash getroffen. Dieses Tool ist darauf ausgelegt, einfache Anwendungen für die Visualisierung von Graphen und Daten zu erstellen. Es kann zudem in einem Container gehostet werden und verwendet Python als Programmiersprache.
|
||||
@ -164,15 +180,18 @@ Schließlich wird aufgrund des vorhandenen Kenntnisstands und der geringeren Kom
|
||||
Die Einarbeitung in Django wäre erheblich umfangreicher und wurde daher zugunsten von Plotly Dash verworfen.
|
||||
|
||||
### Provisionierung
|
||||
|
||||
Bei der Provisionierung gilt es, zwischen der Nutzung eines der Hyperscaler (AWS, GCP oder Azure) mit ihren kostenfreien Kontingenten oder der Eignung der Server der Universität Südwestfalen zu unterscheiden. Als letzte Alternative besteht die Möglichkeit des Selbsthostings, wobei dies aufgrund des Aufwands, einen eigenen Server einzurichten und abzusichern, wirklich nur als allerletzte Option betrachtet wird.
|
||||
|
||||
Nach mehreren Gesprächen ergab sich die Möglichkeit, den Container-Cluster der Fachhochschule zu nutzen, was sich als kostengünstige Option für das Projekt herausstellte. Die Entscheidung fiel daher schnell. Obwohl das Hosting über einen Public Cloud Provider ebenfalls die Anforderungen erfüllt, birgt es das Risiko, dass eine Kreditkarte angegeben wird und bei Fehlverhalten oder falschen Einstellungen in der Cloud erhebliche Kosten verursacht werden können. Zudem ist das Team in Bezug auf Cloud-Ressourcen begrenzt geschult. Daher wurde eindeutig die Lösung des FH-Clusters bevorzugt.
|
||||
|
||||
## Proof-of-Concept mit Jupyter Notebooks
|
||||
|
||||
Die in diesem Abschnitt beschriebene Recherche ist am Projektbeginn durchgeführt worden in dem auf Basis der Prämissen für die einzelnen kategorien Jupyternotebooks erstellt wurden um die Technologien zu evaluieren und einen Eindruck für den Aufwand des Prjektes zu erhalten.
|
||||
|
||||
Dieses Vorgehen bezeichnet man als Proof-of-Concept (POC) und reduziert spätere Arbeitsaufwände die entstehen, wenn sich durch fehlende Evaluation für falsche Technologien oder Konzepte entschieden wurde.
|
||||
|
||||
Die Jupyternotebooks finden sich im Projekt unter den Ordnern
|
||||
- [research](documentations/research)
|
||||
- [Jupyter](Jupyter)
|
||||
|
||||
- [research](https://github.com/fhswf/aki_prj23_transparenzregister/tree/main/documentations/research)
|
||||
- [Jupyter](https://github.com/fhswf/aki_prj23_transparenzregister/tree/main/Jupyter)
|
||||
|
@ -1,4 +1,4 @@
|
||||
# Grundlagen und Basistechniken (Tim Ronneburg)
|
||||
In diesem Abschnitt sind die Zwischenberichte des Projekts zu finden. In diesen Berichten wurde die Recherche zu den einzelnen Kategorien durchgeführt und in den entsprechenden Jupyter Notebooks im Git-Repository bewertet. Dieses Kapitel präsentiert eine detaillierte Analyse der zuvor beschriebenen Recherche mit zusätzlichen Begründungen und Erläuterungen, warum bestimmte Technologien, Konzepte und Vorgehensweisen für das Projekt ausgewählt wurden.
|
||||
|
||||
Es ist zu beachten, dass die Zwischenberichte zu einem frühen Zeitpunkt des Projektes erstellt wurden und eine Hausarbeit darstellen, weshalb in einigen Abschnitten von zukünftigen Vorgehensweisen und Ausblick gesprochen wird.
|
||||
Es ist zu beachten, dass die Zwischenberichte zu einem frühen Zeitpunkt des Projektes erstellt wurden und eine Hausarbeit darstellen, weshalb in einigen Abschnitten von zukünftigen Vorgehensweisen und Ausblick gesprochen wird.
|
||||
|
@ -24,13 +24,13 @@ Dieses Figure Objekt wird in den folgenden Pages Dateien eingebunden:
|
||||
- company_elements.py
|
||||
- person_elements.py
|
||||
|
||||
Für das Aktualisieren des Netzwerks nach Benutzereingaben werden Callbacks verwendet. Diese werden durch die Interaktion mit einem HTML-Element wie einem Dropdown oder Radiobuttons ausgelöst. Da dem Benutzer mehrere Auswahlmöglichkeiten für die Betrachtung des Netzwerks gegeben werden, muss der Callback für das Netzwerk mehrere Inputs aufnehmen und verarbeiten. Dies ist erforderlich, da ein Callback immer nur einen Output haben kann und mehrere Callbacks nicht auf dasselbe HTML-Element verweisen sollten. Obwohl es mittlerweile eine Möglichkeit gibt, mehrere Outputs zu nutzen, bietet dies keine signifikanten Vorteile weshalb in diesem Projekt darauf verzichtet wurde.
|
||||
Für das Aktualisieren des Netzwerks nach Benutzereingaben werden Callbacks verwendet. Diese werden durch die Interaktion mit einem HTML-Element wie einem Dropdown oder Radiobuttons ausgelöst. Da dem Benutzer mehrere Auswahlmöglichkeiten für die Betrachtung des Netzwerks gegeben werden, muss der Callback für das Netzwerk mehrere Inputs aufnehmen und verarbeiten. Dies ist erforderlich, da ein Callback immer nur einen Output haben kann und mehrere Callbacks nicht auf dasselbe HTML-Element verweisen sollten. Obwohl es mittlerweile eine Möglichkeit gibt, mehrere Outputs zu nutzen, bietet dies keine signifikanten Vorteile weshalb in diesem Projekt darauf verzichtet wurde.
|
||||
|
||||
## Bedienung des Netzwerks auf der Homepage
|
||||
Die Homepage des Transparenzregisters sieht zur Vollendung des Projektes folgender Maßen aus:
|
||||

|
||||
|
||||
Auf der linken Seite befindet sich eine Tabelle mit den 10 "besten" Nodes aus dem Links abgebildetet Graphen. Mit "besten" sind hier die 10 Nodes mit dem höchsten Wert der oberhalb der Tabelle gewählten Metrik. Je nach gefilterten Daten ändert sich die Tabelle automatisch und zeigt immer den aktuellen Stand zum rechts erstellten Graphen.
|
||||
Auf der linken Seite befindet sich eine Tabelle mit den 10 "besten" Nodes aus dem Links abgebildetet Graphen. Mit "besten" sind hier die 10 Nodes mit dem höchsten Wert der oberhalb der Tabelle gewählten Metrik. Je nach gefilterten Daten ändert sich die Tabelle automatisch und zeigt immer den aktuellen Stand zum rechts erstellten Graphen.
|
||||
|
||||
Der Graph auf der rechten Seite repräsentiert die Verflechtung von Unternehmen und Akteuren. Dabei stellen orangene Punkte Personen wie Wirtschaftsprüfer oder Geschäftsführer dar, während dunkelgrüne Punkte Unternehmen symbolisieren. Die Bedienung des Graphen erfolgt über die oberen Bedienfelder. Die ersten beiden Dropdown-Menüs ermöglichen die Auswahl der Datenbasis, auf die sich der Graph beziehen soll. Hierbei ist auch eine Mehrfachauswahl möglich. Neben den Daten kann auch das Layout des Graphen eingestellt werden, wobei für die dreidimensionale Darstellung nur begrenzte Optionen verfügbar sind.
|
||||
|
||||
@ -38,18 +38,18 @@ Die initiale Erstellung eines Graphen kann mehrere Sekunden in Anspruch nehmen,
|
||||
|
||||
## Bedienung des Netzwerks auf der Company Page
|
||||
Nach Auswahl eines bestimmten Unternehmens kann auf der Unternehmensseite der Reiter "Verflechtung" gewählt werden, um die Verflechtungen des Unternehmens zu betrachten. Sollte das ausgewählte Unternehmen keine Verflechtungen aufweisen, wird dem Nutzer ein entsprechender Hinweistext angezeigt. Im Bild rot makiert.
|
||||
<!-- Bild mit Hinweistext -->
|
||||
|
||||

|
||||
|
||||
Bei ausreichend vorhandenen Daten wird ein kompakter Graph erstellt, der die Verflechtungen des betrachteten Unternehmens zeigt. Hierbei werden lediglich die engsten Verbindungen visualisiert. Auf dieser Seite ist keine Interaktion mit dem Graphen vorgesehen, da der Benutzer hier lediglich zusätzliche Informationen zum Unternehmen erhalten soll, ohne den gesamten Graphen durchzugehen. Diese Funktion ist für die Homepage vorgesehen.
|
||||
<!-- Bild Company Seite -->
|
||||
|
||||

|
||||
|
||||
## Bedienung des Netzwerks auf der Person Details Page
|
||||
Die Personen-Detailseite verhält sich in Bezug auf das Netzwerk analog zur Unternehmensseite. Auch hier erhält der Nutzer lediglich zusätzliche Informationen zur Person, kann jedoch nicht weiter mit dem Graphen interagieren.
|
||||
|
||||
Auf der Personen-Seite werden die Verflechtungen bis zur dritten Ebene abgebildet, und die jeweilige Anzahl der Verbindungen wird oben in den Containern mit den Kennzahlen dargestellt.
|
||||
<!-- Bild Personen Seite -->
|
||||
|
||||
|
||||
## Ausgelassene Features
|
||||
Im Kapitel 3.5 wurden neben den hier beschriebenen Funktionen auch weitere Aspekte betrachtet und evaluiert, insbesondere im Hinblick auf die Darstellung und Analyse unternehmerischer Kennzahlen wie EBIT, Umsatz, Gewinn, Aktienkurs usw. . Leider konnten im Zuge der Datenerfassung die hierfür benötigten Daten nicht zuverlässig und in ausreichender Menge generiert werden. Dies führte dazu, dass diese Funktionen aus dem Verflechtungsscope herausgenommen wurden.
|
||||
@ -61,4 +61,4 @@ Zuletzt ist die Verflechtungsanalyse einer der Bereiche, die abhängig von den E
|
||||
## Kurzes Resumee der Verflechtungsanalyse/Netzwerkanalyse
|
||||
Alles in allem konnte ein Netzwerk auf Basis der Unternehmensdaten erstellt werden, das Einblicke in die Verzweigungen einiger Unternehmensbeziehungen ermöglicht. Die Analyse wird dabei von klassischen Netzwerkanalyse-Kennzahlen unterstützt. Jedoch muss die Analyse weiterhin durch den Benutzer erfolgen und ist nur in einem eingeschränkteren Maße, als ursprünglich angedacht, durchführbar. Die Analyse hinsichtlich unternehmerischer Kennzahlen musste aufgrund mangelnder Daten aus dem Projekt ausgeschlossen werden.
|
||||
|
||||
Die Möglichkeit, ein Netzwerk basierend auf den vorliegenden Unternehmensdaten zu generieren, bietet einen Einblick in die Verästelungen bestimmter Unternehmensbeziehungen. Die Analyse wird durch klassische Netzwerkanalyse-Kennzahlen unterstützt. Dennoch ist die Durchführung der Analyse auf eine begrenztere Ebene beschränkt als ursprünglich geplant. Aufgrund unzureichender Daten im Projekt musste die Analyse bezüglich unternehmerischer Kennzahlen ausgeschlossen werden.
|
||||
Die Möglichkeit, ein Netzwerk basierend auf den vorliegenden Unternehmensdaten zu generieren, bietet einen Einblick in die Verästelungen bestimmter Unternehmensbeziehungen. Die Analyse wird durch klassische Netzwerkanalyse-Kennzahlen unterstützt. Dennoch ist die Durchführung der Analyse auf eine begrenztere Ebene beschränkt als ursprünglich geplant. Aufgrund unzureichender Daten im Projekt musste die Analyse bezüglich unternehmerischer Kennzahlen ausgeschlossen werden.
|
||||
|
@ -1,4 +1,4 @@
|
||||
### 4.2 Lösungsarchitektur
|
||||
### Lösungsarchitektur (Tristan Nolde)
|
||||
Im Verlauf der Entwicklung stellte sich heraus, dass eine zentrale Stelle zur Datenspeicherung benötigt wird, damit Entwickler Zugang zu den Daten sowohl im Staging-Bereich als auch in der Produktiv-Form haben. Die bereits in der ersten Phase des Projektes angelegte MongoDB im Atlas Hosting (internet-facing) wurde daher durch eine auf der FH-Infrastruktur gehostete Konstruktion ersetzt, die aus einer MongoDB und einer PostgreSQL-Datenbank besteht:
|
||||
|
||||
<img src="images/fh_swf_k8s.PNG" alt="Überblick über die Netzwerkarchitektur des FH K8s Clusters" width=600 height=350 />
|
||||
|
@ -1,4 +1,4 @@
|
||||
#### Data Extraction
|
||||
#### Data Extraction (Tristan Nolde)
|
||||
|
||||
Um die gewünschten Analysen und Visualisierungen zu ermöglichen, wurden verschiedene Implementierungen geschaffen. Diese übernehmen einerseits den Bezug von Rohdaten aus verschiedenen Quellen aber auch die ersten Aufbereitungsschritte und letztlich Persistierung in der Staging DB.
|
||||
|
||||
|
@ -0,0 +1,939 @@
|
||||

|
||||
|
||||
# Datenspeicherung
|
||||
|
||||
## Motivation: Warum speichern wird Daten?
|
||||
|
||||
Für die Speicherung von Daten gibt es verschiedene Motivationen:
|
||||
|
||||
- **Sammlung:** Zur Aufbewahrung von Wissen und Informationen über Objekte, Ereignisse oder Prozesse werden Daten
|
||||
gespeichert.
|
||||
- **Historisierung:** Durch die Speicherung von Daten in einem zeitlichen Zusammenhang, wird eine Historie erstellt, mit
|
||||
welcher Muster, Trends oder Zusammenhänge erkannt werden können. Historische Daten helfen ausserdem bei der
|
||||
Entscheidungsfindung.
|
||||
- **Bewertung:** Mit gespeicherten Daten können Systeme, Produkte und Prozesse nachvollzogen, bewertet und verbessert
|
||||
werden.
|
||||
|
||||
Im Projekt Transparenzregister ist die Datenspeicherung eine Kernkomponente, da die gesammelten Informationen die
|
||||
Grundlage für Analysen darstellen. \
|
||||
Mit geeigneten Pipelines werden aus diesen Daten Erkenntnisse extrahiert, um z.B. Verflechtungen zwischen Personen und
|
||||
Unternehmen oder den wirtschaftlichen Trend eines Unternehmens visualisieren und bewerten zu können.
|
||||
|
||||
## Allgemeine Anforderungen an Datenbank
|
||||
|
||||
- **Speicherung/Integrität**: Das verwendete System muss Daten, wie Unternehmenskennzahlen, Stammdaten und
|
||||
Verflechtungen speichern. Die Daten müssen korrekt und konsistent gespeichert werden. Konsistent bedeutet in einem
|
||||
gültigen und widerspruchsfreien Zustand und die Transaktionen sollen den ACID-Eigenschaften entsprechen.
|
||||
- **Atomarity:** Eine Transaktion wird atomar betrachte, d.h. es ist die kleinste unteilbare Einheit, wodurch eine
|
||||
Transaktion entweder vollständig durchgeführt und übernommen wird (Commit) oder bei einem Fehler rückgängig
|
||||
gemacht
|
||||
wird (Rollback).
|
||||
- **Consistency:** Konsistenz bedeutet, dass eine Transaktion den Datenbankzustand von einem gültigen in einen
|
||||
anderen
|
||||
gültihgen Zustand überführt. Sollte eine Transaktion eine Konsitenzverletzung verursachen, wird diese abgebrochen
|
||||
und die Änderungen zurückgesetzt.
|
||||
- **Isolation:** Isolation sorgt dafür, dass alle Transaktion unabhängig voneinander ausgeführt werden, damit sich
|
||||
diese bei der Ausführung nicht gegenseitig beeinflussen.
|
||||
- **Durability:** Dauerhaftigkeit bedeutet, dass die Ergebnisse einer Transaktion dauerhaft in der Datenbank
|
||||
gespeichert werden und auch nach einem Systemneustart oder Systemfehler erhalten bleiben.
|
||||
- **Skalierbarkeit:** Das System soll skalierbar sein, um zukünftige Daten weiterhin zu speichern und weitere
|
||||
Unternehmen hinzuzufügen. Durch Hinzufügen von Ressourcen kann das System an steigende Datenmengen und
|
||||
Benutzeranforderungen angepasst werden. Man spricht von horizontaler Skalierung, da die Last auf mehrere
|
||||
Datenbankserver verteilt wird.
|
||||
- **Sicherheit:** Die Datenbank muss Mechanismen bereitstellen, um die Daten vor unbefugtem Zugriff zu schützen.
|
||||
- **Authentifizierung:** Überprüfung der Identität eines Benutzers, durch Benutzername und Passwort. Meist wird eine
|
||||
Zwei-Faktor-Authentifizierung verwendet, um das Sicherheitslevel zu erhöhen.
|
||||
- **Autorisierung:** Der authentifizierte Benutzer erhält bei der Autorisierung Zugriffsrechte und Ressourcen,
|
||||
welche
|
||||
auf seiner Benutzerrolle basieren. Ein Benutzer mit Administratorrechten, erhält Zugriff auf alle
|
||||
Systemressourcen,
|
||||
wohingegen ein normaler Benutzer nur beschränkten Zugriff erhält.
|
||||
- **Verschlüsselung:** Durch Verschlüsselung werden Daten in ein nicht interpretierbaren Code umgewandelt, um den
|
||||
Inhalt vor unbefugtem Zugriff zu schützen. Dafür wird ein Algorithmus verwendet, welcher einen Schlüssel generiert
|
||||
und die Daten mit diesem verschlüsselt. Um die Daten wieder lesen zu können, müssen diese mit dem Schlüssel
|
||||
dechiffriert werden.
|
||||
- **Datensicherung- und Wiederherstellung:** Die Datenbank muss Funktionen zur Sicherung und Wiederherstellung
|
||||
unterstützen. Im Falle eines Ausfalls oder Fehlers muss sichergestellt sein, dass Mechanismen die Daten schützen und
|
||||
wiederherstellen.
|
||||
Die meisten Daten in einer Datenbank ändern sich nur langsam, manche allerdings schnell. Je nach Anwendungsfall muss
|
||||
eine geeignete Sicherungsstrategie ausgewählt werden, um nur die Daten zu sichern, die sich tatsächlich ändern.
|
||||
Jedes Datenbankmanagementsystem bietet unterschiedliche Mechanismen zur Datensicherung und Wiederherstellung, dessen
|
||||
Möglichkeiten nach Auswahl eines Systems
|
||||
- **vollständiges Backup:** Das vollständige Backup ist eine komplette Kopie der Datenbank inkl. aller Daten,
|
||||
Indizes,
|
||||
Tabellen und Metadaten. Es benötigt viel Speicherplatz und Zeit zur Erzeugung der Sicherung und auch zur
|
||||
Wiederherstellung.
|
||||
- **inkrementelles Backup:** Ein inkrementelles Backup sichert nur die Änderungen seit dem letzten vollständigem
|
||||
bzw.
|
||||
inkrementellen Backup. Durch den verringerten Datenbestand ist es deutlich schneller und datensparsamer, als das
|
||||
vollständige Backup. Zur Wiederherstellung wird das letzte vollständige und alle inkrementellen Backups benötigt.
|
||||
Allerdings entsteht eine Abhängigkeitskette, da jedes Backup seine Vorgänger zur Wiederherstellung benötigt.
|
||||
- **differentielles Backup:** Beim differentiellen Backup werden alle Änderungen seit dem letzten vollständigem
|
||||
Backup
|
||||
gesichert. D.h. je weiter die letzte vollständige Sicherung zurückliegt, desto größer und langsamer wird das
|
||||
Backup.
|
||||
Zur Wiederherstellung werden das letzte vollständige und differentielle Backup benötigt.
|
||||
|
||||
<script type="text/javascript" src="http://cdn.mathjax.org/mathjax/latest/MathJax.js?config=TeX-AMS-MML_HTMLorMML"></script>
|
||||
<script type="text/x-mathjax-config">
|
||||
MathJax.Hub.Config({ tex2jax: {inlineMath: [['$', '$']]}, messageStyle: "none" });
|
||||
</script>
|
||||
|
||||
**Backuphäufigkeit:**
|
||||
Die Backuphäufigkeit ist eine Abwägung aus Risiken, Kosten und Arbeitsaufwand. Dieses muss individuell abgeschätzt
|
||||
werden aufgrund des Datenbankumfangs und der Änderungshäufigkeit der Daten, um eine geeignete Backup-Strategie zu
|
||||
entwerfen. \
|
||||
*Beispiel:*
|
||||
|
||||
- Vorgabe: Datenbank mit 500GB Größe
|
||||
- Anforderungen
|
||||
- min. vierfache Backupkapazität → 2 TB
|
||||
- Backupdauer vollständig: \
|
||||
USB 2.0:$\frac {500GB}{\frac{60MB/s}{1024}} = 8533 sec. \approx 142Min. \approx 2,37 Std.$ \
|
||||
USB 3.0:$\frac {500GB}{\frac{625MB/s}{1024}} = 820 sec. \approx 13,6Min. \approx 0,23 Std.$ \
|
||||
VDSL 100:$\frac {500GB}{\frac{5MB/s}{1024}} = 102400 sec. \approx 1706Min. \approx 28,4 Std.$ \
|
||||
Glasfaser:$\frac {500GB}{\frac{62,5MB/s}{1024}} = 8192 sec. \approx 136,5Min. \approx 2,3 Std.$
|
||||
|
||||
- **Leistung:** Die Performanceanforderungen an die Datenbank ergibt sich aus verschiedenen Merkmalen. Diese können
|
||||
kombiniert gestellt werden und sind abhängig von den Anforderungen an das System. Eine Analyse der Anwendungsfälle ist
|
||||
notwendig, um die Anforderungen zu spezifizieren.
|
||||
- **Latenz:** Die Datenbank soll Anfragen effizient und in einer akzeptablen Antwortzeit verarbeiten. Typische
|
||||
Datenbankapplikationen, wie z.B. ein Webshop benötigen viele einzelne Zugriffe, wofür jedes Mal ein
|
||||
Kommunikationsprotokoll angewendet wird. Durch viele kleine Datenbankzugriffe wird die Applikation verlangsamt, da
|
||||
auf die Netzwerkkommunikation gewartet wird. Für das Benutzererlebnis eines Webshops ist die Latenz ein wichtiges
|
||||
Merkmal.
|
||||
- **Durchsatz:** Ist eine Metrik für die Anzahl an Transaktionen pro Zeiteinheit. Der Durchsatz ist wichtig bei
|
||||
großen
|
||||
Benutzeraufkommen in einem Webshop.
|
||||
- **Verfügbarkeit:** Eine hohe Verfügbarkeit, also Erreichbarkeit der Datenbank, wird durch Redundanz (mehrfaches
|
||||
Vorhandensein) und Wiederherstellungsmechanismen gewährleistet, damit Daten koninuierlich verfügbar sind.
|
||||
- **Wartbarkeit:** Eine einfach zu wartende Datenbank muss Funktionen zur Überwachung, Diagnose, Wartung,
|
||||
Datensicherung und Wiederherstellung bereitstellen. Durch diese automatisierten Pipelines können andere
|
||||
Eigenschaften, wie z.B. die Verfügbarkeit negativ beeinflusst werden, weil Prozesse die Datenbank blockieren.
|
||||
- **Integration:** Die Datenbank muss Schnittstellen bereitstellen, um die gespeicherten Daten für eine Anwendung
|
||||
bzw. Systeme zur Verfügung zu stellen.
|
||||
- **API:** Das *Application Programming Interface* ist eine definierte Schnittstelle, welche Methoden und Funktionen
|
||||
bereit stellt, um auf die Datenbank zuzugreifen bzw. um diese zu verwalten.
|
||||
- **REST:** REpresential State Transfer beschreibt eine Schnittstelle, die das http-Protokoll verwendet, wo mit
|
||||
den
|
||||
Methoden GET, POST, PUT, DELETE die Kommunikation realisiert wird.
|
||||
- **SOAP:** Simple Object Access Protocol ist eine Schnittstelle, welche auf XML basiert.
|
||||
- **ODBC:** Open Database Connectivity ist eine standardisierte Schnittstelle zum Austausch zwischen Anwendungen
|
||||
und
|
||||
Datenbanken.
|
||||
- **JDBC:** Java Database Connectivity
|
||||
|
||||
## Datenarten
|
||||
|
||||
Zur Beschreibung von Unternehmen, werden verschiedene Datenarten verwendet.
|
||||
Die folgenden Datenarten sind eine allgemeine Zusammenfassung und sollen das Brainstorming für die projektspezifischen
|
||||
Daten unterstützen.
|
||||
|
||||
- **Stammdaten:** Stammdaten beinhalten die grundsätzlichen Eigenschaften und
|
||||
Informationen von realen Objekten, welche für die periodische Verarbeitung notwendig sind. Ein Stammsatz für Personal
|
||||
besteht z.B. aus einer Personalnummer, dem Mitarbeiternamen, Anschrift und Bankverbindung. \
|
||||
Je nach Anwendungsfall bzw. Geschäftsprozess muss der Inhalt definiert werden, wie z.B. bei Unternehmens-, Kunden-,
|
||||
Material- oder Patientenstammdaten.
|
||||
|
||||
- **Metadaten:** Mit Metadaten werden weitere Daten beschrieben und vereinfachen das Auffinden und Arbeiten mit diesen.
|
||||
Metadaten beinhalten beispielsweise den Verfasser, das Erstellungs- oder Änderungsdatum, die Dateigröße oder den
|
||||
Ablageort. \
|
||||
Mit Metadaten können Datenbestände einfacher und effizienter verwaltet und abgefragt werden.
|
||||
|
||||
- **Transaktionsdaten:** Transaktionsdaten beschreiben eine Veränderung des Zustands, wie z.B. eine Kapitalbewegung oder
|
||||
eine Ein-/Auslieferung aus einem Lager.
|
||||
|
||||
- **Referenzdaten:** Referenzdaten sind eine Teilmenge von Stammdaten und beschreiben die zulässigen Daten. Diese werden
|
||||
nur selten geändert oder angepasst und gelten als konstant. Beispiele für Referenzdaten sind: Postleitzahlen,
|
||||
Kostenstellen, Währungen oder Finanzhierarchien.
|
||||
|
||||
- **Bestandsdaten:** Bestandsdaten sind dauerhafter Veränderung ausgesetzt, da diese z.B. die Artikelmenge in einem
|
||||
Lager oder das Guthaben auf einem Konto beschreiben. Diese korrelieren mit den Transaktionsdaten.
|
||||
|
||||
Diese Datenarten müssen im Kontext des Projektes betrachtet werden und sollen das Brainstorming unterstützen. \
|
||||
*Stammdaten:* Unternehmensname, Anschrift, Branche \
|
||||
*Metadaten:* Verfasser einer Nachricht - Veröffentlichungsdatum; Prüfungsunternehmen - Prüfdatum \
|
||||
*Transaktionsdaten:* Wer hat wann wo gearbeitet? \
|
||||
*Referenzdaten:* Einheit von Metriken (Umsatz, EBIT usw.) \
|
||||
*Bestandsdaten:* Vorstand, Geschäftsführer, Aufsichtsrat
|
||||
|
||||
### Welche Daten erwarten wir im Projekt?
|
||||
|
||||
Aus den vorangehenden, allgemeinen Datenarten haben wir Cluster identifiziert, welche im Projekt benötigt werden.
|
||||
Die Kombination aus den folgend aufgeführten Datenclustern ermöglicht eine ganzheitliche Betrachtung und Bewertung der
|
||||
Unternehmen.
|
||||
|
||||
- **Unternehmensstammdaten:** Die Stammdaten beinhalten grundlegende Informationen zu einem Unternehmen, wie z.B. Name,
|
||||
Anschrift, Gesellschaftsform und Branche.
|
||||
|
||||
- **Sentiment daten:** Die Sentiment- oder Stimmungsdaten beschreiben die Aussenwahrnehmung des Unternehmens
|
||||
hinsichtlich
|
||||
der Mitarbeiterzufriedenheit, Nachhaltigkeit und Umweltfreundlichkeit.
|
||||
|
||||
> Mit Sentiment daten können folgende Fragen beantwortet werden:
|
||||
>- Welchen Ruf hat das Unternehmen?
|
||||
>- Wie ist die Aussenwahrnehmung?
|
||||
>- Wie ist die Kundenbindung?
|
||||
|
||||
- **Finanzdaten:** Die Finanzdaten sind Metriken bzw, Indikatoren, um den wirtschaftlichen Erfolg des Unternehmens zu
|
||||
bewerten. Hierzu zählen z.B. Umsatz, EBIT, EBIT Marge, Bilanzsumme, Eigenkapitalanteil, Fremdkapitalanteil,
|
||||
Verschuldungsgrad, Eigenkapitalrentabilität, Umschlaghäufigkeit des Eigenkapitals.
|
||||
|
||||
> Mit Finanzdaten können folgende Fragen beantwortet werden:
|
||||
>- Wie rentabel wirtschaftet das Unternehmen?
|
||||
>- Wie ist der wirtschaftliche Trend?
|
||||
>- Bewerten anhand verschiedener Metriken.
|
||||
|
||||
- **Verflechtungsdaten/Social Graph:** Die Verbindungen bzw. Beziehungen zu Personen oder Unternehmen wird in den
|
||||
Verflechtungsdaten abgelegt. Beziehungen entstehen, wenn eine Person Geschäftsführer, Vorstand, Aufsichtsratmitglied,
|
||||
Prokurist oder Auditor ist und Unternehmen z.B. gemeinsam arbeiten, beliefert wird oder Anteile an einem anderen
|
||||
Unternehmen besitzt.
|
||||
|
||||
> Mit Verflechtungsdaten können folgende Fragen beantwortet werden:
|
||||
>- Gibt es strategische Partnerschaften?
|
||||
>- Wie sind die Lieferketten aufgebaut?
|
||||
>- Wie ist die Qualität der Geschäftsbeziehungen?
|
||||
>- Ist das Unternehmen widerstandsfähig aufgestellt?
|
||||
>- Gibt es Zusammenhänge zu Personen?
|
||||
|
||||
Die abgebildete Mindmap ist nicht vollständig und bildet nicht den finalen Datenumfang des Projekts ab. Es ist eine
|
||||
Momentaufnahme, bevor das relationale Schema entwickelt und die Implementierung begonnen wurde.
|
||||
|
||||

|
||||
|
||||
### Strukturierte Daten
|
||||
|
||||
Strukturierte Daten liegen in einem definierten Format. Vorab wird ein Schema definiert, um Felder, Datentypen und
|
||||
Reihenfolgen festzulegen und die Daten entsprechend abzulegen.
|
||||
Diese Art von Daten wird z.B. in relationalen Datenbanken verwendet, wobei jede Zeile einer Tabelle einen Datensatz
|
||||
repräsentiert. Die Beziehungen untereinander sind über die Entitäten definiert.
|
||||
Das Beispiel unten zeigt ein einfaches Beispiel, wie die Daten für die Klasse *Company* definiert sind. Mit diesem
|
||||
Schema kann die Datenaufbereitung umgesetzt werden.
|
||||
|
||||
```{mermaid}
|
||||
---
|
||||
title: Structured Data
|
||||
---
|
||||
classDiagram
|
||||
class Company:::styleClass {
|
||||
int ID
|
||||
string Name
|
||||
string Street
|
||||
int ZipCode
|
||||
}
|
||||
|
||||
|
||||
```
|
||||
|
||||
| Vorteile | Nachteile |
|
||||
|:---------------------------------------------:|:----------------------------------------------------------------:|
|
||||
| einfach nutzbar, da organisiert | Einschränkung der Verwendungsmöglichkeit durch Schema |
|
||||
| bei bekannten Schema sind Werkzeuge vorhanden | begrenze Speichermöglichkeit, da starre Schemata vorgegeben sind |
|
||||
| gut automatisierbar | |
|
||||
|
||||
### Unstrukturierte Daten
|
||||
|
||||
Unstrukturierte Daten unterliegen keinem Schema, wie z.B. E-Mails, Textdokumente, Blogs, Chats, Bilder, Videos oder
|
||||
Audiodateien.
|
||||
|
||||
- **Textanalyse:** Aus unstrukturierten Texten werden z.B. durch Analyse und Mining Informationen gewonnen, um diese zu
|
||||
extrahieren. Es wird das Vorkommen von bestimmten Wörtern mittels Named Entity Recognition ermittelt oder die Stimmung
|
||||
bzw. das Thema in einem Artikel.
|
||||
- **Audio-/Videoanalyse:** Bei der Verarbeitung unstrukturierter Audio- oder Videodateien werden Objekte, Gesichter,
|
||||
Stimmen oder Muster erkannt, um diese für Sprachassistenten oder autonome Fahrzeuge nutzbar zu machen.
|
||||
|
||||
Eine wichtige Informationsquelle sind unstrukturierte Daten für Explorations- und Analyseaufgaben. Dabei werden
|
||||
Datenquellen wie z.B. E-Mails, RSS-Feeds, Blogs durchsucht, um bestimmte Informationen zu finden oder Zusammenhänge
|
||||
zwischen verschiedenen Quellen herzustellen. Dies ermöglicht tiefe Einsicht in die Daten zu erhalten und unterstützt
|
||||
die Entscheidungsfindung bei unklaren Sachverhalten und die Entdeckung neuer Erkenntnisse.
|
||||
|
||||
| Vorteile | Nachteile |
|
||||
|:-----------------------------------------------------------------:|:-------------------------------------------------------------:|
|
||||
| großes Potenzial Erkenntnisse zu erlangen | aufwändige Bearbeitung notwendig, um Daten nutzbar zu machen |
|
||||
| unbegrenzte Anwendungsmöglichkeiten, da kein Schema vorhanden ist | spezielle Tools zur Aufbereitung notwendig |
|
||||
| | Expertenwissen über die Daten und Datenaufbereitung notwendig |
|
||||
|
||||
## Arten von Datenbanken
|
||||
|
||||
### Relationale Datenbank
|
||||
|
||||
Eine relationale Datenbank speichert und verwaltet strukturierte Daten. Dabei werden die Daten in Tabellen organisiert,
|
||||
welche aus Zeilen und Spalten bestehen. \
|
||||
In den Zeilen der Tabellen sind die Datensätze gespeichert, d.h. jede Zeile repräsentiert einen Datensatz. Durch
|
||||
logisches Verbinden der Tabellen können die Beziehungen zwischen den Daten abgebildet werden. \
|
||||
Die wichtigsten Elemente einer relationalen Datenbank werden folgend erklärt:
|
||||
|
||||
**Tabelle:** Eine Tabelle repräsentiert eine Entität bzw. Objekt, wie z.B. Unternehmen, Kunde oder Bestellung. Die
|
||||
Tabelle besteht aus Spalten, welche die Attribute der Entität speichern. \
|
||||
Jede Zeile ist eine Instanz des Objekts und enthält konkrete Werte.
|
||||
|
||||
**Table_Person**
|
||||
|
||||
| **ID** | **Name** | **Age** | **Salary** | **Height** |
|
||||
|--------|----------|---------|------------|------------|
|
||||
| 1 | Tim | 31 | 300.00 | 191.20 |
|
||||
| 2 | Tom | 21 | 400.00 | 181.87 |
|
||||
| 3 | Tam | 51 | 500.00 | 176.54 |
|
||||
|
||||
https://www.sqlservercentral.com/articles/creating-markdown-formatted-text-for-results-from-sql-server-tables
|
||||
|
||||
**Primärschlüssel:** Der Primärschlüssel ist ein eindeutiger Bezeichner für jede einzelne Zeile einer Tabelle und wird
|
||||
zur Identifikation einer einzelnen Zeile benötigt. Im oberen Beispiel ist die Spalte *ID* der Primärschlüssel.
|
||||
|
||||
**Fremdschlüssel:** Ein Fremdschlüssel verweist auf einen Primärschlüssel einer anderen Tabelle, um eine Beziehung
|
||||
zwischen den Tabellen herzustellen. \
|
||||
Im Beispiel bezieht sich die Spalte *customer_id* auf den Primärschlüssel der Tabelle *Table_Person*.
|
||||
|
||||
**Table_Orders**
|
||||
|
||||
| **ID** | **Product** | **total** | **customer_id** |
|
||||
|--------|-------------|-----------|-----------------|
|
||||
| 1 | Paper | 12 | 2 |
|
||||
| 2 | Book | 3 | 2 |
|
||||
| 3 | Marker | 5 | 3 |
|
||||
|
||||
**Beziehungen:** Wie bereits beschrieben, können mit der Verwendung von Fremdschlüsseln Beziehungen zwischen den
|
||||
Tabellen hergestellt werden. \
|
||||
Es gibt verschiedene Beziehungstypen:
|
||||
|
||||
| **Typ** | **Beschreibung** |
|
||||
|:-------:|:---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| 1:1 | Jeder Primärschlüsselwert bezieht sich auf nur einen Datensatz. **Beispiel:** Jede Person hat genau eine Bestellung. |
|
||||
| 1:n | Der Primärschlüssel ist eindeutig, tritt in der bezogenen Tabelle 0..n mal auf. **Beispiel:** Jede Person kann keine, eine oder mehrere Bestellungen haben. |
|
||||
| n:n | Jeder Datensatz von beiden Tabellen kann zu beliebig vielen Datensätzen (oder auch zu keinem Datensatz) stehen. Meist wird für diesen Typ eine dritte Tabelle verwendet, welche als Zuordnungs- bzw. Verknüpfungstabelle angelegt wird, da andernfalls keine direkte Verbindung hergestellt werden kann. |
|
||||
|
||||
https://www.ibm.com/docs/de/control-desk/7.6.1.2?topic=structure-database-relationships
|
||||
|
||||
#### Anlegen von Tabellen
|
||||
|
||||
Der Umgang von relationalen Datenbanken erfolgt mittels SQL. Folgend ein Beispiel zum Anlegen einer Tabelle mit
|
||||
Attributen.
|
||||
|
||||
```sql
|
||||
CREATE TABLE Bildungsstaette
|
||||
(
|
||||
ID INT PRIMARY KEY NOT NULL,
|
||||
Name VARCHAR(255) NOT NULL,
|
||||
Anschrift VARCHAR(255),
|
||||
Art VARCHAR(100)
|
||||
);
|
||||
```
|
||||
|
||||
#### SQL - Abfrage von relationalen Datenbanken
|
||||
|
||||
Für die Verwaltung und Abfrage wird SQL (Structured Query Language) verwendet.
|
||||
Mit dieser Syntax können Tabellen erstellt, Daten eingefügt, aktualisiert und gelöscht und Daten abgefragt werden.
|
||||
|
||||
**Anzeige aller Attribute einer Tabelle:**
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM table_name;
|
||||
```
|
||||
|
||||
**Anzeige definierter Attribute einer Tabelle:**
|
||||
|
||||
```sql
|
||||
SELECT column1, column2
|
||||
FROM table_name;
|
||||
```
|
||||
|
||||
**Gefilterte Anzeige einer Tabelle:**
|
||||
|
||||
```sql
|
||||
SELECT *
|
||||
FROM table_name
|
||||
WHERE condition;
|
||||
```
|
||||
|
||||
**Daten aus mehreren Tabellen abrufen (Join):**
|
||||
|
||||
```sql
|
||||
SELECT t1.column1, t2.column2
|
||||
FROM table1 t1
|
||||
JOIN table2 t2 ON t1.id = t2.id;
|
||||
```
|
||||
|
||||
### Graphdatenbank
|
||||
|
||||
Eine Graphdatenbank basiert auf dem Graphenkonzept. \
|
||||
Ein Graph besteht aus Knoten und Kanten (Beziehungen), welche die Verbindungen zwischen den Knoten darstellen. \
|
||||
Die Stärke der Graphdatenbank liegt in der Darstellung von komplexen Beziehungen.
|
||||
|
||||
**Knoten:** Jeder Knoten repräsentiert eine Entität bzw. Objekt. Jeder Knoten hat eine eindeutige ID oder Bezeichner, um
|
||||
auf diesen zugreifen zu können. Es können auch Attribute hinterlegt werden, um zusätzliche Informationen zu speichern,
|
||||
wie z.B. Geburtsjahr, Wohnort einer Person.
|
||||
|
||||
**Kanten:** Die Kanten verbinden die Knoten und repräsentieren damit die Beziehungen unter den Objekten. Die Kanten
|
||||
können gerichtet und ungerichtet sein. Bei einer gerichteten Beziehung muss die Richtung vom Quell- zum Zielknoten
|
||||
beachtet werden, wohingegen eine ungerichtete Kante eine symmetrische Beziehung darstellt. \
|
||||
*gerichtete Beziehung:* Ein Unternehmen ist abhängig vom Bericht des Wirtschaftsprüfers. \
|
||||
*ungerichtete Beziehung:** Unternehmen A arbeitet gemeinsam mit Unternehmen B an einem Projekt.
|
||||
|
||||
**Label:** Label werden verwendet, um die Knoten zu kategorisieren/gruppieren. Ein Knoten kann auch mehrere Label
|
||||
besitzen, um die Zugehörigkeit an verschiedenen Kategorien darzustellen (z.B. Unternehmensbranche).
|
||||
|
||||
#### Erstellung eines Datensatzes
|
||||
|
||||
1. Knotenerstellung: Es wird zuerst ein Knoten erstellt, der die Entität repräsentiert.
|
||||
2. ID: Der Knoten benötigt eine eindeutige Identifikationsnummer, welche automatisch erzeugt oder manuell festgelegt
|
||||
werden kann.
|
||||
3. Knoten einfügen: Wenn die beiden notwendigen Elemente (Knoten und ID) festgelegt sind, kann der Knoten eingefügt
|
||||
werden.
|
||||
4. Beziehungen/Kanten festlegen: Wenn der Knoten Beziehungen zu anderen Knoten hat, können diese hinzugefügt werden.
|
||||
|
||||
**Beispiel:**
|
||||
Folgender Code legt in neo4j zwei Knoten und die entsprechenden Beziehungen an.
|
||||
|
||||
```
|
||||
CREATE
|
||||
(:University {id: 4711, name: 'FH SWF - Iserlohn'}),
|
||||
(:University {id: 1234, name: 'FH SWF - Meschede'})
|
||||
WITH *
|
||||
MATCH (u1:University {id: 4711}), (u2:University {id: 1234})
|
||||
CREATE
|
||||
(u1)-[:cooparates_with]->(u2),
|
||||
(u2)-[:cooparates_with]->(u1)
|
||||
```
|
||||
|
||||

|
||||
|
||||
#### Cypher - Abfrage von Graphdatenbanken
|
||||
|
||||
Um Daten abzufragen wird die Abfragesprache Cypher verwendet.
|
||||
Es werden folgend nur einige grundlegende Befehle gezeigt.
|
||||
|
||||
**Abfrage aller Knoten**
|
||||
|
||||
```
|
||||
MATCH (n)
|
||||
RETURN n
|
||||
```
|
||||
|
||||
**Abfrage aller Kanten/Beziehungen**
|
||||
|
||||
```
|
||||
MATCH ()-[r]-()
|
||||
RETURN r
|
||||
```
|
||||
|
||||
**Abfrage von Knoten mit definierten Eigenschaften**
|
||||
|
||||
```
|
||||
MATCH (n:Label)
|
||||
WHERE n.property = value
|
||||
RETURN n
|
||||
```
|
||||
|
||||
**Beziehung zwischen zwei Knoten abfragen**
|
||||
|
||||
```
|
||||
MATCH (n1)-[r]->(n2)
|
||||
WHERE n1.property = value1 AND n2.property = value2
|
||||
RETURN r
|
||||
```
|
||||
|
||||
### Zeitseriendatenbank
|
||||
|
||||
Zeitserien fallen überall dort an, wo eine Metrik zeitlich betrachtet wird, wie z.B. Umsatz oder EBIT.
|
||||
D.h. zu jedem Messwert gibt es einen zeitlich zugeordneten Zeitstempel, wobei die einzelnen Zeitpunkte zu einer Serie
|
||||
zusammengefasst werden, um den Zusammenhang zu betrachten. \
|
||||
Diese Datenbanken sind spezialisiert auf die Speicherung, Verwaltung und Abfrage von Zeitserien. \
|
||||
Die folgenden Erklärungen beziehen sich auf die InfluxDB.
|
||||
|
||||
**Bucket:** Der Bucket separiert Daten in verschiedene Speicher und ist mit der Datenbank bei relationalen Datenbanken
|
||||
vergleichbar.
|
||||
|
||||
**Datapoint:** Unter dem Bucket werden die Datenpunkte gespeichert. Ein Datapoint setzt sich aus mehreren Elementen
|
||||
zusammen, welche erforderlich oder optional sind:
|
||||
|
||||
| **Element** | **Eigenschaft** |
|
||||
|-------------|----------------------------------------------------------------------------------------------------------------------------------------------------|
|
||||
| Measurement | Datentyp: String<br>Leerzeichen sind verboten<br>Max. 64kB |
|
||||
| Tags | Sind optional<br> Bestehen aus einem Key/Value-Paar <br> Datentyp: String <br>Leerzeichen sind verboten <br> Max. 64 kB |
|
||||
| Fields | Min. 1 Field=value Paar wird benötigt <br> Nicht alle Felder müssen in jedem Punkt vorhanden sein <br> Datentypen: Float, String, Integer, Boolean |
|
||||
| Timestamp | Sind optional <br>Influx schreibt standardmäßig die Systemzeit als Zeitstempel <br>Genauigkeit kann eingestellt werden (Default: Nanosekunden) |
|
||||
|
||||
#### Erstellung eines Datensatzes
|
||||
|
||||
Die Einrichtung von Zeitseriendatenbanken erfolgt mit der CLI von Influx.
|
||||
|
||||
**Anlegen eines Buckets:**
|
||||
|
||||
```
|
||||
CREATE DATABASE finance
|
||||
```
|
||||
|
||||
#### FluxQuery
|
||||
|
||||
Zur Abfrage von Datenpunkten gibt es FluxQuery, welche sich stark an SQL orientiert. \
|
||||
|
||||
**Abrufen aller Daten aus Bucket:**
|
||||
|
||||
```
|
||||
from(bucket: "my-bucket")
|
||||
```
|
||||
|
||||
**Festlegen des Zeitbereichs:**
|
||||
|
||||
```
|
||||
range(start: -1h, stop: now())
|
||||
```
|
||||
|
||||
**Filtern nach Bedingungen:**
|
||||
|
||||
```
|
||||
filter(fn: (r) => r._measurement == "temperature")
|
||||
```
|
||||
|
||||
**Transformieren von Datenpunkten:**
|
||||
|
||||
```
|
||||
map(fn: (r) => ({r with temperatureF: r.temperature * 2.34 + 123}))
|
||||
```
|
||||
|
||||
### Dokumenten Datenbank <a name="3.4"></a>
|
||||
|
||||
Eine Dokumentendatenbank ist ein System, welches für das Speichern von Dokumenten entwicklet wurde. Es gibt verschiedene
|
||||
Arten von Dokumenten, wie z.B. Textdateien (JSON, HTML, XML) oder PDF.
|
||||
Es muss kein Schema für die Dokumente festgelegt werden, dadurch ist es möglich Dokumente mit verschiedenen Datenfeldern
|
||||
zu speichern.
|
||||
Gleiche oder ähnliche Dokumente werden gemeinsam in *Collections* gespeichert.
|
||||
Die wichtigsten Elemente einer Dokumentendatenbank sind:
|
||||
|
||||
**Database:** Unter Database versteht man einen Container, unter welchem Dokumente gespeichert werden. Dies dient der
|
||||
Isolierung bzw. logischen Trennung von Daten.
|
||||
|
||||
**Collection:** Collections werden verwendet, um Dokumente mit ähnlichen Eigenschaften zusammenzufassen. Da
|
||||
Dokumenten-Datenbanken schemenlos sind, dienen die Collections der Organisation.
|
||||
|
||||
**Document:** Das Dokument ist ein einzelnes Datenobjekt und die kleinste Einheit in einer Dokumenten-DB. Ein Dokument
|
||||
kann z.B. ein JSON mit einer eigenen internen Struktur.
|
||||
|
||||

|
||||
|
||||
#### Erstellen einer Collection / Ablegen von Dokumenten
|
||||
|
||||
Folgend ein Code-Snippet zum Verbinden mit der Datenbank, Anlegen einer Collection und ablegen von Dokumenten.
|
||||
|
||||
``` python
|
||||
from pymongo import MongoClient
|
||||
|
||||
# Verbindung zur MongoDB-Datenbank herstellen
|
||||
client = MongoClient('mongodb://localhost:27017')
|
||||
|
||||
# erstelle ein Cleint-Objekt zur Datenbank
|
||||
db = client['transparenz']
|
||||
|
||||
# Collection erstellen
|
||||
collection = db['Tagesschau_API']
|
||||
|
||||
# Beispiel-Dokumente einfügen
|
||||
doc1 = {
|
||||
'title': 'BASF wird verkauft!',
|
||||
'content': 'BASF wird an Bayer AG verkauft',
|
||||
'date': '2023-06-22'
|
||||
}
|
||||
|
||||
doc2 = {
|
||||
'title': 'Bayer Aktie erreicht Rekordniveau',
|
||||
'content': 'Aufgrund des Zukaufs von BASF.....',
|
||||
'date': '2023-06-23'
|
||||
}
|
||||
|
||||
# Dokumente in die Collection einfügen
|
||||
collection.insert_one(doc1)
|
||||
collection.insert_one(doc2)
|
||||
|
||||
# Verbindung zur Datenbank schließen
|
||||
client.close()
|
||||
|
||||
```
|
||||
|
||||
### Aufbau einer Datenbank
|
||||
|
||||
Vor dem Aufbau einer relationalen Datenbank sollten planerische Schritte durchgeführt werden, um ein System zu
|
||||
entwerfen, dass den Anforderungen gerecht wird. \
|
||||
Die wichtigsten Schritte sind:
|
||||
|
||||
**Anforderungsanalyse:** Identifikation und Definition von Anforderungen an die Datenbank durch Betrachtung des
|
||||
Anwendungsfalls.
|
||||
|
||||
**Datenmodell:** Analysieren der Strukturen und Beziehungen, die sich aus der Anforderungsanalyse ergeben. Auswahl eines
|
||||
Datenbankmodells, welches am besten geeignet ist.
|
||||
|
||||
**Tabellenentwurf:** Basierend auf den identifizierten Anforderungen wird die Tabellenstruktur der Datenbank entworfen.
|
||||
Für jede Tabelle werden Spaltennamen, Datentyp und mögliche Einschränkungen wie Primärschlüssel und Fremdschlüssel
|
||||
definiert.
|
||||
|
||||
**Erstellung der Tabellen:** Wenn der Tabellenentwurf schlüssig ist und bereits diskutiert wurde, können die Tabellen
|
||||
erstellt werden. Es werden die zuvor festgelegten Bezeichner, Datenytpen und Constraints hinzugefügt.
|
||||
|
||||
**Beziehungen festlegen:** Um die Beziehungen zwischen Tabellen festzulegen, werden Fremdschlüssel verwendet. Mit
|
||||
Fremdschlüsseln verknüpft man Tabellen mit den Primärschlüsseln anderer, abhängiger Tabellen.
|
||||
|
||||
## Datenbanken Transparenzregister
|
||||
|
||||
Nachdem die Datencluster identifiziert wurden, welche für das Transparenzregister notwendig sind, wurde Rechereche zu
|
||||
den benötigten Datenquellen betrieben. \
|
||||
Es gibt verschiedene Quellen, mit unterschiedlichen Schnittstellen bzw. Zugriff auf die Daten, z.B. mit API´s oder über
|
||||
Web Scrapping.
|
||||
|
||||
Es wurde eine Architektur definiert, welche den Aufbau der späteren Software skizziert:
|
||||

|
||||
|
||||
Mittels geeigneter Techniken werden Daten aus diversen Quellen extrahiert (Data Extraction) und in der Staging DB
|
||||
gespeichert.
|
||||
Mit unterschiedlichen Daten-Extraktionspipelines (Dazta Loader, Sentiment Analysis, Graph Analysis) werden die Daten aus
|
||||
der Staging DB verarbeitet und die strukturierten und aufbereiteten Daten in der Production DB abgelegt. \
|
||||
Das Frontend kann auf diese strukturierten Daten zugreifen, um diese zu visualisieren.
|
||||
|
||||
### Production DB - relationales Datenbankmodell
|
||||
|
||||
Für die Production DB ist eine relationale Datenbank vorgesehen, da diese die Daten organisiert und durch Verwendung von
|
||||
definierten Schemata strukturiert. \
|
||||
Diese Strukturen erleichtern die Wartung und Integration zwischen Back- und Frontend.
|
||||

|
||||
|
||||
Zentrales Element ist die Stammdatentabelle **company**, welche einen zusammengesetzten Primärschlüssel aus der Nummer
|
||||
des Handelsregisters und dem zuständigen Amtsgericht bildet. \
|
||||
Die Handelsregisternummer ist nicht eindeutig und wird deutschlandweit mehrfach vergeben, allerdings nur einfach unter
|
||||
einem Amtsgericht.
|
||||
|
||||
Es schließt sich die Tabelle **finance** an, in welcher die Finanzdaten persistiert werden. Diese steht in einer 1:n
|
||||
Beziehung zur Unternehmenstabelle, da ein Unternehmen viele Finanzdaten haben kann und jeder Datensatz genau einem
|
||||
Unternehmen zugewiesen ist. \
|
||||
Die einzelnen Metriken wurden als Attribute definiert, wodurch es viele NULL-Werte in jeder Zeile gibt. Vorteilhaft bei
|
||||
dieser Notation ist allerdings, dass die Metriken durch den Spaltenbezeichner eindeutig sind.
|
||||
|
||||
Die Tabelle **Sentiment** speichert die Stimmungsdaten zu einem Unternehmen. Auch hier besteht eine 1:n Beziehung zu der
|
||||
Unternehmenstabelle. Es gibt einen eigenen Enumeration-Typ, der die Art der Stimmungsdaten festlegt.
|
||||
|
||||
Die Tabelle **district_court** speichert das Amtsgericht, unter welchen die Unternehmen registriert sind. Diese
|
||||
Information ist wichtig, um mit der Handelsregisternummer und dem Amtsgericht ein Unternehmen eindeutig zu
|
||||
identifizieren.
|
||||
|
||||
Die Tabelle **person** speichert Personen, welche unterschiedliche Beziehungen zu Unternehmen haben können. Daraus
|
||||
ergibt sich eine n:m Beziehung (many-to-many), da jede Person mehrere Beziehungen zu einem Unternehmen haben kann bz.
|
||||
jedes Unternehmen mehrfach mit einer Person in Verbindung steht. \
|
||||
Um diese Relation aufzulösen, wird eine Beziehungstabelle **person_relation** benötigt, um die n:m Beziehung auf zwei 1:
|
||||
n Beziehungen zu reduzieren. Diese enthält die Fremdschlüssel der bezogenen Tabellen, um die Beziehung zu modellieren.
|
||||
|
||||
Abschließend gibt es noch die Tabelle **company_relation**, welche die Verbindung zwischen Unternehmen modelliert.
|
||||
Hierfür wurde ein Enumaration-Typ erzeugt, welcher die Art der Beziehung angibt (wird_beliefert_von, arbeitet_mit,
|
||||
ist_beteiligt_an, hat_Anteile_an).
|
||||
|
||||
### Staging DB
|
||||
|
||||
Die Staging DB ist eine dokumentbasierte Datenbank zu Speicherung von unstrukturierten und semi-strukturierten Daten.
|
||||
Sie dient als Zwischenspeicher oder "Rohdatenbank" für die Extraktions-Pipelines.
|
||||
Aufgaben der Staging-DB:
|
||||
|
||||
1. **Datenvorbereitung:** Sammlung und Speicherung von Rohdaten aus verschiedenen Quellen
|
||||
2. **Überprüfung:** Entsprechen die Daten den Anforderungen ggfs. Ermittlung von Fehlern oder Inkonsistenzen
|
||||
3. **Testumgebung:** Die Rohdaten aus der Staging DB können mehrfach verwendet werden, um verschiedene Szenarien und
|
||||
Funktionalitäten der Extraktionspipelines zu erproben
|
||||
4. **Backup:** Wenn sich im Laufe des Projekts eine Datenquelle ändert (z.B. Struktur oder Zugang zum Bundesanzeiger)
|
||||
sind die Daten weiterhin verfügbar oder wenn es Änderungen am Schema der Production DB gibt, kann durch eine Änderung
|
||||
am Data Loader das neue Tabellenschema implementiert werden
|
||||
|
||||
Die Staging DB erhält Collections der unterschiedlichen Quellen, unter welchen die Dokumente gespeichert werden.
|
||||
|
||||

|
||||
|
||||
### SQL Alchemy
|
||||
|
||||
SQL Alchemy ist eine Python Bibliothek, um mit relationalen Datenbanken zu kommunizieren.
|
||||
Dieses ORM (Object-Relational-Mapping) Framework bildet die Datenbanktabellen als Pythonklassen an und vereinfacht damit
|
||||
das Erstellen, Lesen, Aktualisieren und Löschen von Daten aus Pythonanwendungen.\
|
||||
wichtige Eigenschaften:
|
||||
|
||||
- erleichterte Entwicklung: durch die Abbildung von Datenbanktabellen als Pythonklassen wird durchgängig Pythoncode
|
||||
verwendet
|
||||
- Flexibilität: Durch Verwendung eines Backend-Treibers für die unterschiedlichen Datenbanken, muss der Code nicht
|
||||
geändert werden. Wenn eine andere Datenbank zum Einsatz kommt, muss nur der Treiber ausgetauscht werden (
|
||||
Plattformunabhängigkeit)
|
||||
- Erhöhung der Produktivität: Es werden keine Kompetenzen für SQL Programierung und Wartung benötigt.
|
||||
|
||||
## Proof of Concept
|
||||
|
||||
### Docker
|
||||
|
||||
Für die Umsetzung der bisher vorgestellten theoretischen Betrachtungen wird ein Docker Container verwendet. Dieser
|
||||
Container beinhaltet eine relationale und eine dokumentbasierte Datenbank. \
|
||||
Mit Jupyter Notebooks soll die Implementierung und Befüllung der Datenbank erprobt werden, um als Startpunkt für die
|
||||
anstehende Softwareentwicklung zu dienen.
|
||||
|
||||
```yaml
|
||||
version: "3.8"
|
||||
services:
|
||||
db:
|
||||
image: postgres:14.1-alpine
|
||||
container_name: postgres
|
||||
restart: always
|
||||
ports:
|
||||
- "5432:5432"
|
||||
environment:
|
||||
POSTGRES_USER: postgres
|
||||
POSTGRES_PASSWORD: postgres
|
||||
volumes:
|
||||
- ./PostgreSQL:/var/lib/postgresql/data
|
||||
pgadmin:
|
||||
image: dpage/pgadmin4:7.2
|
||||
container_name: pgadmin4_container
|
||||
restart: always
|
||||
ports:
|
||||
- "5050:80"
|
||||
environment:
|
||||
PGADMIN_DEFAULT_EMAIL: admin@fh-swf.de
|
||||
PGADMIN_DEFAULT_PASSWORD: admin
|
||||
volumes:
|
||||
- ./pgadmin:/var/lib/pgadmin
|
||||
|
||||
mongodb:
|
||||
image: mongo:7.0.0-rc4
|
||||
ports:
|
||||
- '27017:27017'
|
||||
volumes:
|
||||
- ./mongo:/data/db
|
||||
```
|
||||
|
||||
| Eintrag | Beschreibung |
|
||||
|----------|--------------------------------------------------|
|
||||
| version | Version von docker-compose |
|
||||
| services | Definition der Services, welche gestartet werden |
|
||||
|
||||
| Option | Beschreibung |
|
||||
|-------------|---------------------------------------------------------------------|
|
||||
| image | Angabe des zu verwendenden Image |
|
||||
| restart | Option, um Container erneut zu starten, falls dieser gestoppt wurde |
|
||||
| environment | Umgebungsvariablen, wie z.B. Username und Passwort |
|
||||
| Ports | Mapping des Containerports zum Port der Hostmaschine |
|
||||
| volumes | Angabe eines Volumes zum Persistieren der Containerdaten |
|
||||
|
||||
Beim Ausführen der docker-compose werden in diesem Verzeichnis Ordner für die Datenablage angelegt. Da zum
|
||||
Verfassungszeitpunkt noch nicht feststeht, wie im Projekt der Datenaustausch stattfindet, könnten diese Ordner bzw. die
|
||||
Volumes einfach untereinander ausgetauscht werden.
|
||||
|
||||
Zum Starten des Containers den folgenden Befehl ausführen:
|
||||
|
||||
```console
|
||||
docker-compose -f docker-compose.yml up
|
||||
```
|
||||
|
||||
### PG Admin
|
||||
|
||||
PG Admin ist ein grafisches Administartionstool für Postgres. Wenn der Container gestartet ist, kann man sich
|
||||
über http://localhost:5050/browser/ mit dem Web-UI verbinden. \
|
||||
Dieses Tool dient lediglich der Überprüfung von Commits der Tabellen und daten.
|
||||
|
||||
Die Anmeldedaten lauten:
|
||||
|
||||
```
|
||||
> User: admin@fh-swf.de
|
||||
> Passwort: admin
|
||||
```
|
||||
|
||||

|
||||
|
||||
Zuerst muss der Server angelegt werden, dafür einen Rechtsklick auf Server und den Button „Register“ auswählen. Im
|
||||
geöffneten Dialog muss die Konfiguration festgelegt werden.
|
||||
|
||||
| Reiter | Parameter | Wert |
|
||||
|------------|-------------------|---------------------------------|
|
||||
| General | Name | postgres |
|
||||
| Connection | Host name/address | postgres (siehe docker-compose) |
|
||||
| Connection | Username | postgres (siehe docker-compose) |
|
||||
| Connection | Password | postgres (siehe docker-compose) |
|
||||
|
||||

|
||||
|
||||
### Erstellen von Mock Daten
|
||||
|
||||
**Unternehmensstammdaten:**
|
||||
|
||||
Um das Konzept und den Umgang mit den ausgewählten Datenbanken zu überprüfen, sollen Daten in die Datenbank geschrieben
|
||||
werden. Hierfür wurde auf Statista recherchiert, welches die größten deutschen Unternehmen sind, um einen kleinen Stamm
|
||||
an Unternehmensdaten zu generieren (01_Stammdaten_Unternehmen_HR.csv). /
|
||||
Die Relation zu den Amtsgerichten ist frei erfunden und wurde nicht recherchiert.
|
||||

|
||||
|
||||
**Amtsgerichte:**
|
||||
Die Amtsgerichte sind aus https://www.gerichtsverzeichnis.de/ extrahiert, wobei lediglich 12 Amstgerichte eingefügt
|
||||
wurden (Amtsgerichte.csv).
|
||||
|
||||
**Finanzdaten:** Es wurden für drei Unternehmen (EON, Telekom, BASF) die Finanzdaten bezüglich Umsatz, Ebit und Ebitda
|
||||
auf Statista ermittelt und als separate Dateien gespeichert (BASF_data.csv, Telekom_data.csv, EON_data.csv).
|
||||
|
||||
**Personen:** Die Personentabelle ist frei erfunden. Mit einer Onlinebibliothek wurde 1000 Vor- und Nachnamen erzeugt
|
||||
und gespeichert (Person1000.csv).
|
||||
|
||||
**Personen-Unternehmens-Beziehung:** Diese Tabelle ist zufällig erzeugt und dient lediglich für weitere Experimente.
|
||||
Hierfür wurde ein Python-Skript erstellt, welches mit der mehreren Random-Funktionen die Beziehungen zufälloig
|
||||
generiert.
|
||||
|
||||
**Sentiment:** keine Mock-Daten vorhanden
|
||||
|
||||
**Unternehmens-Unternehmens-Beziehung:** keine Mock-Daten vorhanden
|
||||
|
||||
### Anlegen der relationalen Tabellen
|
||||
|
||||
Für das Verbinden zu der Postgre Datenbank und das Anlegen der Tabellen wird ein Jupyter Notebooks verwendet (
|
||||
11_Create_Tables_with_SQL-Alchemy.ipynb).
|
||||
|
||||
Die benötigten Bibliotheken werden importiert und das Erstellen von Tabellen als Python-Objekte beschrieben. \
|
||||
Nach dem Anlegen der Tabellen werden die Mock-Daten in die Datenbank geschrieben. \
|
||||
Eine Überprüfung, ob die Daten abgelegt worden ist sehr einfach mit PGAdmin möglich.
|
||||

|
||||
|
||||
Das grundsätzliche Vorgehen bei der Verwendung von SQLAlchemy ist:
|
||||
|
||||
1. Verbindung zur Datenbank herstellen
|
||||
```python
|
||||
from sqlalchemy import create_engine
|
||||
# Connection URL für postgres
|
||||
url = URL.create(
|
||||
drivername="postgresql",
|
||||
username="postgres",
|
||||
password="postgres",
|
||||
host="localhost",
|
||||
database="postgres")
|
||||
|
||||
# Verbindung zur Datenbank
|
||||
engine = create_engine(database_url)
|
||||
```
|
||||
2. Erstellen einer Klasse als Repräsentation der Tabelle.
|
||||
> Es ist üblich und empfehlenswert die Klassendefinitionen in einer separaten Datei vorzunehmen (model.py), damit
|
||||
diese auch in andere Modulen importiert und verwendet werden können
|
||||
```python
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Integer, String
|
||||
|
||||
Base = declarative_base()
|
||||
|
||||
class MyClass(Base):
|
||||
__tablename__ = 'company'
|
||||
|
||||
id = Column(Integer, primary_key=True)
|
||||
name = Column(String)
|
||||
city = Column(String)
|
||||
```
|
||||
3. Starten einer Session/Verbindung, um Daten lesen und schreiben zu können
|
||||
```python
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
|
||||
# starte die Verbindung
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
```
|
||||
4. Daten abfragen
|
||||
```python
|
||||
# Alle Daten der Klasse/Tabelle abrufen
|
||||
data = session.query(MyClass).all()
|
||||
```
|
||||
5. Daten speichern, wenn z.B. Datensätze in die Datenbank geschrieben werden, muss dies mit der **commit()**-Funktion
|
||||
ausgeführt werden. Das folgende Snippet iteriert durch einen Dataframe, um jede Zeile in die Datenbank zu schreiben.
|
||||
```python
|
||||
for i in range(len(df)):
|
||||
# get data from dataframe
|
||||
myNewData=MyClass(
|
||||
name = str(df['Name'].iloc[i]),
|
||||
city = str(df['Surname'].iloc[i])
|
||||
)
|
||||
session.add(myNewData)
|
||||
session.commit()
|
||||
```
|
||||
|
||||
### Abfragen der Datenbank
|
||||
|
||||
Das folgende Code-Snippet zeigt, wie man eine Abfrage gestaltet.
|
||||
|
||||
```python
|
||||
from sqlalchemy import create_engine
|
||||
from sqlalchemy.orm import sessionmaker
|
||||
from sqlalchemy.ext.declarative import declarative_base
|
||||
from sqlalchemy import Column, Integer, String
|
||||
|
||||
# Erstelle eine SQLite-Datenbankdatei oder gib den Pfad zur vorhandenen Datei an
|
||||
url = URL.create(
|
||||
drivername="postgresql",
|
||||
username="postgres",
|
||||
password="postgres",
|
||||
host="localhost",
|
||||
database="postgres"
|
||||
)
|
||||
|
||||
# Erstelle eine Engine zur Verbindung mit der Datenbank
|
||||
engine = create_engine(url)
|
||||
|
||||
# Erstelle eine Klasse, die eine Tabelle repräsentiert
|
||||
Base = declarative_base()
|
||||
|
||||
|
||||
class Company(Base):
|
||||
__tablename__ = 'company'
|
||||
|
||||
hr = Column(Integer(), nullable=False, primary_key=True)
|
||||
court_id = Column(Integer, ForeignKey("district_court.id"), nullable=False, primary_key=True)
|
||||
name = Column(String(100), nullable=False)
|
||||
street = Column(String(100), nullable=False)
|
||||
zip = Column(Integer(), nullable=False)
|
||||
city = Column(String(100), nullable=False)
|
||||
sector = Column(String(100), nullable=False)
|
||||
|
||||
__table_args__ = (
|
||||
PrimaryKeyConstraint('hr', 'court_id', name='pk_company_hr_court'),
|
||||
)
|
||||
|
||||
|
||||
# starte die Verbindung zur Datenbank
|
||||
Session = sessionmaker(bind=engine)
|
||||
session = Session()
|
||||
|
||||
# Abfrage aller Spalten der Tabelle/Klasse Company
|
||||
Comps = session.query(Company).all()
|
||||
|
||||
# Gebe die Spalten name, hr und court_id der Tabelle company aus
|
||||
for comp in Comps:
|
||||
print(comp.name, comp.hr, comp.court_id)
|
||||
```
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
## Zusammenfassung
|
||||
|
||||
Die vorliegende Seminararbeit behandelt das Thema der Datenspeicherung mit Fokus auf dem Projekt Transparenzregister. Es
|
||||
wurde erläutert, warum Daten gespeichert werden und welche Art von Daten es gibt.
|
||||
|
||||
Für das Projekt sind Daten und die Speicherung eine Kernkomponente, um die geforderten Analysen bezüglich
|
||||
Verflechtungen, unternehmerischen Erfolgs und Aussenwahrnehmung zu ermöglichen.
|
||||
|
||||
Es wurden Datencluster definiert und entsprechende Quellen gefunden, welche über geeignete Extraktionspipelines die
|
||||
erforderlichen Informationen extrahieren. Zum Speichern dieser extrahierten Daten wurde ein relationales Modell
|
||||
erarbeitet, um ein Konzept für die folgende Implementierung zu haben.
|
||||
|
||||
Um das Konzept zu überprüfen, wurde ein Proof of Concept durchgeführt, um geeignete Werkzeuge zu erproben und das Modell
|
||||
auf seine Tauglichkeit zu überprüfen.
|
||||
|
||||
Hierbei wurde ein Dockercontainer eingesetzt, um die Datenbankumgebung bereitzustellen. Mithilfe der
|
||||
SQL-Alchemy-Bibliothek, wurde die Tabellen innerhalb der Datenbank erstellt.
|
||||
|
||||
Anschließend wurden die Tabellen mit eigenen Mock-Daten befüllt, um die Funktionalität der Datenbank zu testen.
|
||||
|
||||
Insgesamt bietet die Seminararbeit einen umfassenden Überblick über die Bedeutung der Datenspeicherung und die
|
||||
verschiedenen Arten von Datenbanken.
|
||||
Es wurde ein erstes relationales Modell und ein High level design für die Softwarearchitektur erarbeitet.
|
||||
Diese Arbeit hat grundsätzliche Fragen geklärt und Verständnis für die Datenspeicherung im Zusammenhang mit dem Projekt
|
||||
Transparenzregister geschaffen und unterstützt die weitere Entwicklung.
|
||||
|
||||
<div style="page-break-after: always;"></div>
|
||||
|
||||
## Quellen
|
||||
|
||||
- Klug, Uwe: SQL-Der Einstieg in die deklarative Programmierung, 2. Auflage, Dortmund, Springer, 2017
|
||||
- Steiner, Rene: Grundkurs relationale Datenbanken, 10. Auflage, Wiesbaden, Springer, 2021
|
||||
- https://backupchain.de/daten-backup-tipps-3-wie-oft-daten-sichern/
|
||||
- https://www.talend.com/de/resources/strukturierte-vs-unstrukturierte-daten/
|
||||
- https://www.sqlservercentral.com/articles/creating-markdown-formatted-text-for-results-from-sql-server-tables
|
||||
- https://www.sqlalchemy.org/
|
||||
- https://medium.com/@arthurapp98/using-sqlalchemy-to-create-and-populate-a-postgresql-database-with-excel-data-eb6049d93402
|
@ -0,0 +1,13 @@
|
||||
HR;Amtsgericht;Name;Strasse;PLZ;Stadt;Branche
|
||||
12334;2;Volkswagen;Berliner Ring 2;38440;Wolfsburg;Automobil
|
||||
64566;2;Mercedes-Benz Group;Mercedesstra<72>e 120;70372;Stuttgart;Automobil
|
||||
5433;3;Allianz;Reinsburgstra<72>e 19;70178;Stuttgart;Versicherung, Finanzdienstleistung
|
||||
12435;4;BMW Group;Petuelring 130;80809;M<>nchen;Automobil
|
||||
12336;5;Deutsche Telekom;Landgrabenweg 151;53227;Bonn;Telekommunikation, Informationstechnologie
|
||||
559;6;Deutsche Post DHL Group;Charles-de-Gaulle-Str. 20;53113;Bonn;Logistik
|
||||
555;7;Bosch Group;Robert-Bosch-Platz 1;70839;Gerlingen-Schillerh<72>he;Kraftfahrzeugtechnik, Industrietechnik, Gebrauchsg<73>ter, Energie- und Geb<65>udetechnik
|
||||
12384;8;BASF;Carl-Bosch-Stra<72>e 38;67056;Ludwigshafen;Chemie
|
||||
64345;9;E.ON;Arnulfstra<72>e 203;80634;M<>nchen;Energie
|
||||
4344;10;Munich Re Group;K<>niginstr. 107;80802;M<>nchen;Versicherung
|
||||
866;11;Siemens;Werner-von-Siemens-Stra<72>e 1;80333;M<>nchen;Automatisierung, Digitalisierung
|
||||
9875;12;Deutsche Bahn;Potsdamer Platz 2;10785;Berlin;Transport, Logistik
|
|
@ -0,0 +1,13 @@
|
||||
HR;Amtsgericht;Name;Strasse;PLZ;Stadt;Branche
|
||||
12334;2;Volkswagen;Berliner Ring 2;38440;Wolfsburg;Automobil
|
||||
64566;2;Mercedes-Benz Group;Mercedesstra<72>e 120;70372;Stuttgart;Automobil
|
||||
5433;3;Allianz;Reinsburgstra<72>e 19;70178;Stuttgart;Versicherung, Finanzdienstleistung
|
||||
12334;4;BMW Group;Petuelring 130;80809;M<>nchen;Automobil
|
||||
12336;5;Deutsche Telekom;Landgrabenweg 151;53227;Bonn;Telekommunikation, Informationstechnologie
|
||||
555;6;Deutsche Post DHL Group;Charles-de-Gaulle-Str. 20;53113;Bonn;Logistik
|
||||
555;7;Bosch Group;Robert-Bosch-Platz 1;70839;Gerlingen-Schillerh<72>he;Kraftfahrzeugtechnik, Industrietechnik, Gebrauchsg<73>ter, Energie- und Geb<65>udetechnik
|
||||
12384;8;BASF;Carl-Bosch-Stra<72>e 38;67056;Ludwigshafen;Chemie
|
||||
64345;9;E.ON;Arnulfstra<72>e 203;80634;M<>nchen;Energie
|
||||
4344;1;Munich Re Group;K<>niginstr. 107;80802;M<>nchen;Versicherung
|
||||
866;1;Siemens;Werner-von-Siemens-Stra<72>e 1;80333;M<>nchen;Automatisierung, Digitalisierung
|
||||
9875;1;Deutsche Bahn;Potsdamer Platz 2;10785;Berlin;Transport, Logistik
|
|
@ -0,0 +1,15 @@
|
||||
Stadt;Name
|
||||
Aschaffenburg;Amtsgericht Aschaffenburg
|
||||
Bamberg;Amtsgericht Bamberg
|
||||
Bayreuth;Amtsgericht Bayreuth
|
||||
Duesseldorf;Amtsgericht Duesseldorf
|
||||
Duisburg;Amtsgericht Duisburg
|
||||
Duisburg;Amtsgericht Duisburg-Hamborn
|
||||
Duisburg;Amtsgericht Duisburg-Ruhrort
|
||||
Oberhausen;Amtsgericht Oberhausen
|
||||
Wuppertal;Amtsgericht Wuppertal
|
||||
Berlin;Amtsgericht Mitte
|
||||
Berlin;Amtsgericht Ost
|
||||
Berlin;Amtsgericht West
|
||||
Berlin;Amtsgericht Nord
|
||||
Berlin;Amtsgericht Sued
|
|
@ -0,0 +1,25 @@
|
||||
Company_HR;Company_Court;Jahr;Umsatz;Ebit;EBITDA
|
||||
;12384;8;1999;29473;;
|
||||
;12384;8;2000;35946;;
|
||||
;12384;8;2001;32500;;
|
||||
;12384;8;2002;32216;;
|
||||
;12384;8;2003;33361;;
|
||||
;12384;8;2004;37537;;
|
||||
;12384;8;2005;42745;5830;
|
||||
;12384;8;2006;52610;6750;
|
||||
;12384;8;2007;57951;7316;
|
||||
;12384;8;2008;62304;6463;9562
|
||||
;12384;8;2009;50693;3677;7388
|
||||
;12384;8;2010;63873;7761;11131
|
||||
;12384;8;2011;73497;8586;11993
|
||||
;12384;8;2012;72129;6742;10009
|
||||
;12384;8;2013;73973;7160;10432
|
||||
;12384;8;2014;74326;7626;11043
|
||||
;12384;8;2015;70449;6248;10649
|
||||
;12384;8;2016;57550;6275;10526
|
||||
;12384;8;2017;61223;7587;10765
|
||||
;12384;8;2018;60220;5974;8970
|
||||
;12384;8;2019;59316;4201;8185
|
||||
;12384;8;2020;59149;-191;6494
|
||||
;12384;8;2021;78598;7677;11355
|
||||
;12384;8;2022;87327;6548;10748
|
|
@ -0,0 +1,17 @@
|
||||
Company_HR;Company_Court;Jahr;Umsatz;Ebit;EBITDA
|
||||
;64345;9;2007;66912;;
|
||||
;64345;9;2008;84873;;
|
||||
;64345;9;2009;79974;;
|
||||
;64345;9;2010;92863;;
|
||||
;64345;9;2011;112954;;
|
||||
;64345;9;2012;132093;7010;
|
||||
;64345;9;2013;119615;5640;
|
||||
;64345;9;2014;113095;4700;
|
||||
;64345;9;2015;42656;3600;
|
||||
;64345;9;2016;38173;3100;
|
||||
;64345;9;2017;37965;3100;
|
||||
;64345;9;2018;30084;2990;4840
|
||||
;64345;9;2019;41284;3220;5558
|
||||
;64345;9;2020;60944;3780;6905
|
||||
;64345;9;2021;77358;4720;7889
|
||||
;64345;9;2022;115660;5200;8059
|
|
@ -0,0 +1,13 @@
|
||||
Name;Straße;PLZ;Stadt;Branche
|
||||
Volkswagen;Berliner Ring 2;38440;Wolfsburg;Automobil
|
||||
Mercedes-Benz Group;Mercedesstraße 120;70372;Stuttgart;Automobil
|
||||
Allianz;Reinsburgstraße 19;70178;Stuttgart;Versicherung, Finanzdienstleistung
|
||||
BMW Group;Petuelring 130;80809;München;Automobil
|
||||
Deutsche Telekom;Landgrabenweg 151;53227;Bonn;Telekommunikation, Informationstechnologie
|
||||
Deutsche Post DHL Group;Charles-de-Gaulle-Str. 20;53113;Bonn;Logistik
|
||||
Bosch Group;Robert-Bosch-Platz 1;70839;Gerlingen-Schillerhöhe;Kraftfahrzeugtechnik, Industrietechnik, Gebrauchsgüter, Energie- und Gebäudetechnik
|
||||
BASF;Carl-Bosch-Straße 38;67056;Ludwigshafen;Chemie
|
||||
E.ON;Arnulfstraße 203;80634;München;Energie
|
||||
Munich Re Group;Königinstr. 107;80802;München;Versicherung
|
||||
Siemens;Werner-von-Siemens-Straße 1;80333;München;Automatisierung, Digitalisierung
|
||||
Deutsche Bahn;Potsdamer Platz 2;10785;Berlin;Transport, Logistik
|
|
@ -0,0 +1,480 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "dbd6eae9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"\n",
|
||||
"pd.options.plotting.backend = \"plotly\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "8b447b09",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.read_csv(\"Telekom_Data_NewOrder.csv\", sep=\";\", decimal=\",\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "5fc7b7d2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Metrik</th>\n",
|
||||
" <th>Datum</th>\n",
|
||||
" <th>Summe [Milliarden €]</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2005</td>\n",
|
||||
" <td>59.600</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2006</td>\n",
|
||||
" <td>61.300</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2007</td>\n",
|
||||
" <td>62.500</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2008</td>\n",
|
||||
" <td>61.700</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2009</td>\n",
|
||||
" <td>64.600</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>5</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2010</td>\n",
|
||||
" <td>62.420</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2011</td>\n",
|
||||
" <td>58.650</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>7</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2012</td>\n",
|
||||
" <td>58.170</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>8</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2013</td>\n",
|
||||
" <td>60.130</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>9</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2014</td>\n",
|
||||
" <td>62.660</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>10</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2015</td>\n",
|
||||
" <td>69.230</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>11</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2016</td>\n",
|
||||
" <td>73.100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>12</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2017</td>\n",
|
||||
" <td>74.950</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>13</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>75.660</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>14</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>80.530</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>15</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>99.950</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>16</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>107.610</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>17</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>114.200</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>18</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2005</td>\n",
|
||||
" <td>7.600</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2006</td>\n",
|
||||
" <td>5.300</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>20</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2007</td>\n",
|
||||
" <td>5.300</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>21</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2008</td>\n",
|
||||
" <td>7.000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>22</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2009</td>\n",
|
||||
" <td>6.000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>23</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2010</td>\n",
|
||||
" <td>5.510</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>24</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2011</td>\n",
|
||||
" <td>5.560</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>25</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2012</td>\n",
|
||||
" <td>-3.960</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>26</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2013</td>\n",
|
||||
" <td>4.930</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>27</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2014</td>\n",
|
||||
" <td>7.250</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>28</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2015</td>\n",
|
||||
" <td>7.030</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>29</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2016</td>\n",
|
||||
" <td>9.160</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>30</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2017</td>\n",
|
||||
" <td>9.380</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>31</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>8.000</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>32</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>9.460</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>33</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>12.370</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>34</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>12.580</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>35</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>15.410</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>36</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>23.333</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>37</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>24.731</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>38</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>35.017</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>39</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>37.330</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>40</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>40.208</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Metrik Datum Summe [Milliarden €]\n",
|
||||
"0 Umsatz 01.01.2005 59.600\n",
|
||||
"1 Umsatz 01.01.2006 61.300\n",
|
||||
"2 Umsatz 01.01.2007 62.500\n",
|
||||
"3 Umsatz 01.01.2008 61.700\n",
|
||||
"4 Umsatz 01.01.2009 64.600\n",
|
||||
"5 Umsatz 01.01.2010 62.420\n",
|
||||
"6 Umsatz 01.01.2011 58.650\n",
|
||||
"7 Umsatz 01.01.2012 58.170\n",
|
||||
"8 Umsatz 01.01.2013 60.130\n",
|
||||
"9 Umsatz 01.01.2014 62.660\n",
|
||||
"10 Umsatz 01.01.2015 69.230\n",
|
||||
"11 Umsatz 01.01.2016 73.100\n",
|
||||
"12 Umsatz 01.01.2017 74.950\n",
|
||||
"13 Umsatz 01.01.2018 75.660\n",
|
||||
"14 Umsatz 01.01.2019 80.530\n",
|
||||
"15 Umsatz 01.01.2020 99.950\n",
|
||||
"16 Umsatz 01.01.2021 107.610\n",
|
||||
"17 Umsatz 01.01.2022 114.200\n",
|
||||
"18 EBIT 01.01.2005 7.600\n",
|
||||
"19 EBIT 01.01.2006 5.300\n",
|
||||
"20 EBIT 01.01.2007 5.300\n",
|
||||
"21 EBIT 01.01.2008 7.000\n",
|
||||
"22 EBIT 01.01.2009 6.000\n",
|
||||
"23 EBIT 01.01.2010 5.510\n",
|
||||
"24 EBIT 01.01.2011 5.560\n",
|
||||
"25 EBIT 01.01.2012 -3.960\n",
|
||||
"26 EBIT 01.01.2013 4.930\n",
|
||||
"27 EBIT 01.01.2014 7.250\n",
|
||||
"28 EBIT 01.01.2015 7.030\n",
|
||||
"29 EBIT 01.01.2016 9.160\n",
|
||||
"30 EBIT 01.01.2017 9.380\n",
|
||||
"31 EBIT 01.01.2018 8.000\n",
|
||||
"32 EBIT 01.01.2019 9.460\n",
|
||||
"33 EBIT 01.01.2020 12.370\n",
|
||||
"34 EBIT 01.01.2021 12.580\n",
|
||||
"35 EBIT 01.01.2022 15.410\n",
|
||||
"36 EBITDA 01.01.2018 23.333\n",
|
||||
"37 EBITDA 01.01.2019 24.731\n",
|
||||
"38 EBITDA 01.01.2020 35.017\n",
|
||||
"39 EBITDA 01.01.2021 37.330\n",
|
||||
"40 EBITDA 01.01.2022 40.208"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d5c6c68d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---------------------------------\n",
|
||||
"# Schreibe Unternehmensdaten in PostgreSQL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 4,
|
||||
"id": "6c09bdca",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import psycopg2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "383fb9a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Verbinde zur Datenbank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "3e1ea224",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Database connected successfully\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"conn = psycopg2.connect(\n",
|
||||
" host=\"localhost\", database=\"transparenz\", user=\"postgres\", password=\"postgres\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Database connected successfully\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "22b9ab1d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Iteriere durch Dataframe und schreibe Datensätze in Tabelle *Company*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "961ac836",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"cur = conn.cursor()\n",
|
||||
"\n",
|
||||
"PK_ID = 5 # BASF hat den PK 8, deshalb wird dieser manuell hinzugefügt\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"for i in range(len(df)):\n",
|
||||
" # get data from dataframe\n",
|
||||
" kind_of = str(df[\"Metrik\"].iloc[i])\n",
|
||||
" date = str(df[\"Datum\"].iloc[i])\n",
|
||||
" amount = float(df[\"Summe [Milliarden €]\"].iloc[i])\n",
|
||||
"\n",
|
||||
" postgres_insert_query = (\n",
|
||||
" \"\"\" INSERT INTO finance (company_id,kind_of, date, sum) VALUES (%s,%s,%s,%s)\"\"\"\n",
|
||||
" )\n",
|
||||
" record_to_insert = (PK_ID, kind_of, date, amount)\n",
|
||||
" cur.execute(postgres_insert_query, record_to_insert)\n",
|
||||
" # print(postgres_insert_query, record_to_insert)\n",
|
||||
"\n",
|
||||
"conn.commit()\n",
|
||||
"conn.close()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "46b5be7c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
@ -0,0 +1,417 @@
|
||||
{
|
||||
"cells": [
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 1,
|
||||
"id": "dbd6eae9",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import numpy as np\n",
|
||||
"import pandas as pd\n",
|
||||
"import ipywidgets as widgets\n",
|
||||
"\n",
|
||||
"pd.options.plotting.backend = \"plotly\""
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 2,
|
||||
"id": "8b447b09",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"df = pd.read_csv(\"EON_Data_NewOrder.csv\", sep=\";\", decimal=\",\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 3,
|
||||
"id": "5fc7b7d2",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"data": {
|
||||
"text/html": [
|
||||
"<div>\n",
|
||||
"<style scoped>\n",
|
||||
" .dataframe tbody tr th:only-of-type {\n",
|
||||
" vertical-align: middle;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe tbody tr th {\n",
|
||||
" vertical-align: top;\n",
|
||||
" }\n",
|
||||
"\n",
|
||||
" .dataframe thead th {\n",
|
||||
" text-align: right;\n",
|
||||
" }\n",
|
||||
"</style>\n",
|
||||
"<table border=\"1\" class=\"dataframe\">\n",
|
||||
" <thead>\n",
|
||||
" <tr style=\"text-align: right;\">\n",
|
||||
" <th></th>\n",
|
||||
" <th>Metrik</th>\n",
|
||||
" <th>Datum</th>\n",
|
||||
" <th>Summe [Milliarden €]</th>\n",
|
||||
" </tr>\n",
|
||||
" </thead>\n",
|
||||
" <tbody>\n",
|
||||
" <tr>\n",
|
||||
" <th>0</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2007</td>\n",
|
||||
" <td>66.912</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>1</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2008</td>\n",
|
||||
" <td>84.873</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>2</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2009</td>\n",
|
||||
" <td>79.974</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>3</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2010</td>\n",
|
||||
" <td>92.863</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>4</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2011</td>\n",
|
||||
" <td>112.954</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>5</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2012</td>\n",
|
||||
" <td>132.093</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>6</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2013</td>\n",
|
||||
" <td>119.615</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>7</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2014</td>\n",
|
||||
" <td>113.095</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>8</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2015</td>\n",
|
||||
" <td>42.656</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>9</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2016</td>\n",
|
||||
" <td>38.173</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>10</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2017</td>\n",
|
||||
" <td>37.965</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>11</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>30.084</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>12</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>41.284</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>13</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>60.944</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>14</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>77.358</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>15</th>\n",
|
||||
" <td>Umsatz</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>115.660</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>16</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2012</td>\n",
|
||||
" <td>7.010</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>17</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2013</td>\n",
|
||||
" <td>5.640</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>18</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2014</td>\n",
|
||||
" <td>4.700</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>19</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2015</td>\n",
|
||||
" <td>3.600</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>20</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2016</td>\n",
|
||||
" <td>3.100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>21</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2017</td>\n",
|
||||
" <td>3.100</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>22</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>2.990</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>23</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>3.220</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>24</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>3.780</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>25</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>4.720</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>26</th>\n",
|
||||
" <td>EBIT</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>5.200</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>27</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2018</td>\n",
|
||||
" <td>4.840</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>28</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2019</td>\n",
|
||||
" <td>5.558</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>29</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2020</td>\n",
|
||||
" <td>6.905</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>30</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2021</td>\n",
|
||||
" <td>7.889</td>\n",
|
||||
" </tr>\n",
|
||||
" <tr>\n",
|
||||
" <th>31</th>\n",
|
||||
" <td>EBITDA</td>\n",
|
||||
" <td>01.01.2022</td>\n",
|
||||
" <td>8.059</td>\n",
|
||||
" </tr>\n",
|
||||
" </tbody>\n",
|
||||
"</table>\n",
|
||||
"</div>"
|
||||
],
|
||||
"text/plain": [
|
||||
" Metrik Datum Summe [Milliarden €]\n",
|
||||
"0 Umsatz 01.01.2007 66.912\n",
|
||||
"1 Umsatz 01.01.2008 84.873\n",
|
||||
"2 Umsatz 01.01.2009 79.974\n",
|
||||
"3 Umsatz 01.01.2010 92.863\n",
|
||||
"4 Umsatz 01.01.2011 112.954\n",
|
||||
"5 Umsatz 01.01.2012 132.093\n",
|
||||
"6 Umsatz 01.01.2013 119.615\n",
|
||||
"7 Umsatz 01.01.2014 113.095\n",
|
||||
"8 Umsatz 01.01.2015 42.656\n",
|
||||
"9 Umsatz 01.01.2016 38.173\n",
|
||||
"10 Umsatz 01.01.2017 37.965\n",
|
||||
"11 Umsatz 01.01.2018 30.084\n",
|
||||
"12 Umsatz 01.01.2019 41.284\n",
|
||||
"13 Umsatz 01.01.2020 60.944\n",
|
||||
"14 Umsatz 01.01.2021 77.358\n",
|
||||
"15 Umsatz 01.01.2022 115.660\n",
|
||||
"16 EBIT 01.01.2012 7.010\n",
|
||||
"17 EBIT 01.01.2013 5.640\n",
|
||||
"18 EBIT 01.01.2014 4.700\n",
|
||||
"19 EBIT 01.01.2015 3.600\n",
|
||||
"20 EBIT 01.01.2016 3.100\n",
|
||||
"21 EBIT 01.01.2017 3.100\n",
|
||||
"22 EBIT 01.01.2018 2.990\n",
|
||||
"23 EBIT 01.01.2019 3.220\n",
|
||||
"24 EBIT 01.01.2020 3.780\n",
|
||||
"25 EBIT 01.01.2021 4.720\n",
|
||||
"26 EBIT 01.01.2022 5.200\n",
|
||||
"27 EBITDA 01.01.2018 4.840\n",
|
||||
"28 EBITDA 01.01.2019 5.558\n",
|
||||
"29 EBITDA 01.01.2020 6.905\n",
|
||||
"30 EBITDA 01.01.2021 7.889\n",
|
||||
"31 EBITDA 01.01.2022 8.059"
|
||||
]
|
||||
},
|
||||
"execution_count": 3,
|
||||
"metadata": {},
|
||||
"output_type": "execute_result"
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"df"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "d5c6c68d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"---------------------------------\n",
|
||||
"# Schreibe Unternehmensdaten in PostgreSQL"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 5,
|
||||
"id": "6c09bdca",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"import psycopg2"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "383fb9a9",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"### Verbinde zur Datenbank"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 6,
|
||||
"id": "3e1ea224",
|
||||
"metadata": {},
|
||||
"outputs": [
|
||||
{
|
||||
"name": "stdout",
|
||||
"output_type": "stream",
|
||||
"text": [
|
||||
"Database connected successfully\n"
|
||||
]
|
||||
}
|
||||
],
|
||||
"source": [
|
||||
"conn = psycopg2.connect(\n",
|
||||
" host=\"localhost\", database=\"transparenz\", user=\"postgres\", password=\"postgres\"\n",
|
||||
")\n",
|
||||
"\n",
|
||||
"print(\"Database connected successfully\")"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "markdown",
|
||||
"id": "22b9ab1d",
|
||||
"metadata": {},
|
||||
"source": [
|
||||
"## Iteriere durch Dataframe und schreibe Datensätze in Tabelle *Company*"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": 7,
|
||||
"id": "961ac836",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": [
|
||||
"cur = conn.cursor()\n",
|
||||
"\n",
|
||||
"PK_ID = 9 # BASF hat den PK 8, deshalb wird dieser manuell hinzugefügt\n",
|
||||
"\n",
|
||||
"\n",
|
||||
"for i in range(len(df)):\n",
|
||||
" # get data from dataframe\n",
|
||||
" kind_of = str(df[\"Metrik\"].iloc[i])\n",
|
||||
" date = str(df[\"Datum\"].iloc[i])\n",
|
||||
" amount = float(df[\"Summe [Milliarden €]\"].iloc[i])\n",
|
||||
"\n",
|
||||
" postgres_insert_query = (\n",
|
||||
" \"\"\" INSERT INTO finance (company_id,kind_of, date, sum) VALUES (%s,%s,%s,%s)\"\"\"\n",
|
||||
" )\n",
|
||||
" record_to_insert = (PK_ID, kind_of, date, amount)\n",
|
||||
" cur.execute(postgres_insert_query, record_to_insert)\n",
|
||||
" # print(postgres_insert_query, record_to_insert)\n",
|
||||
"\n",
|
||||
"conn.commit()\n",
|
||||
"conn.close()"
|
||||
]
|
||||
},
|
||||
{
|
||||
"cell_type": "code",
|
||||
"execution_count": null,
|
||||
"id": "46b5be7c",
|
||||
"metadata": {},
|
||||
"outputs": [],
|
||||
"source": []
|
||||
}
|
||||
],
|
||||
"metadata": {
|
||||
"kernelspec": {
|
||||
"display_name": "Python 3",
|
||||
"language": "python",
|
||||
"name": "python3"
|
||||
},
|
||||
"language_info": {
|
||||
"codemirror_mode": {
|
||||
"name": "ipython",
|
||||
"version": 3
|
||||
},
|
||||
"file_extension": ".py",
|
||||
"mimetype": "text/x-python",
|
||||
"name": "python",
|
||||
"nbconvert_exporter": "python",
|
||||
"pygments_lexer": "ipython3",
|
||||
"version": "3.8.8"
|
||||
}
|
||||
},
|
||||
"nbformat": 4,
|
||||
"nbformat_minor": 5
|
||||
}
|
@ -0,0 +1,10 @@
|
||||
Stadt;Name
|
||||
Aschaffenburg;Amtsgericht Aschaffenburg
|
||||
Bamberg;Amtsgericht Bamberg
|
||||
Bayreuth;Amtsgericht Bayreuth
|
||||
Duesseldorf;Amtsgericht Duesseldorf
|
||||
Duisburg;Amtsgericht Duisburg
|
||||
Duisburg;Amtsgericht Duisburg-Hamborn
|
||||
Duisburg;Amtsgericht Duisburg-Ruhrort
|
||||
Oberhausen;Amtsgericht Oberhausen
|
||||
Wuppertal;Amtsgericht Wuppertal
|
|
@ -0,0 +1,58 @@
|
||||
Metrik;Datum;Summe [Milliarden €]
|
||||
Umsatz;01.01.1999;29,473
|
||||
Umsatz;01.01.2000;35,946
|
||||
Umsatz;01.01.2001;32,5
|
||||
Umsatz;01.01.2002;32,216
|
||||
Umsatz;01.01.2003;33,361
|
||||
Umsatz;01.01.2004;37,537
|
||||
Umsatz;01.01.2005;42,745
|
||||
Umsatz;01.01.2006;52,61
|
||||
Umsatz;01.01.2007;57,951
|
||||
Umsatz;01.01.2008;62,304
|
||||
Umsatz;01.01.2009;50,693
|
||||
Umsatz;01.01.2010;63,873
|
||||
Umsatz;01.01.2011;73,497
|
||||
Umsatz;01.01.2012;72,129
|
||||
Umsatz;01.01.2013;73,973
|
||||
Umsatz;01.01.2014;74,326
|
||||
Umsatz;01.01.2015;70,449
|
||||
Umsatz;01.01.2016;57,55
|
||||
Umsatz;01.01.2017;61,223
|
||||
Umsatz;01.01.2018;60,22
|
||||
Umsatz;01.01.2019;59,316
|
||||
Umsatz;01.01.2020;59,149
|
||||
Umsatz;01.01.2021;78,598
|
||||
Umsatz;01.01.2022;87,327
|
||||
EBIT;01.01.2005;5,83
|
||||
EBIT;01.01.2006;6,75
|
||||
EBIT;01.01.2007;7,316
|
||||
EBIT;01.01.2008;6,463
|
||||
EBIT;01.01.2009;3,677
|
||||
EBIT;01.01.2010;7,761
|
||||
EBIT;01.01.2011;8,586
|
||||
EBIT;01.01.2012;6,742
|
||||
EBIT;01.01.2013;7,16
|
||||
EBIT;01.01.2014;7,626
|
||||
EBIT;01.01.2015;6,248
|
||||
EBIT;01.01.2016;6,275
|
||||
EBIT;01.01.2017;7,587
|
||||
EBIT;01.01.2018;5,974
|
||||
EBIT;01.01.2019;4,201
|
||||
EBIT;01.01.2020;-0,191
|
||||
EBIT;01.01.2021;7,677
|
||||
EBIT;01.01.2022;6,548
|
||||
EBITDA;01.01.2008;9,562
|
||||
EBITDA;01.01.2009;7,388
|
||||
EBITDA;01.01.2010;11,131
|
||||
EBITDA;01.01.2011;11,993
|
||||
EBITDA;01.01.2012;10,009
|
||||
EBITDA;01.01.2013;10,432
|
||||
EBITDA;01.01.2014;11,043
|
||||
EBITDA;01.01.2015;10,649
|
||||
EBITDA;01.01.2016;10,526
|
||||
EBITDA;01.01.2017;10,765
|
||||
EBITDA;01.01.2018;8,97
|
||||
EBITDA;01.01.2019;8,185
|
||||
EBITDA;01.01.2020;6,494
|
||||
EBITDA;01.01.2021;11,355
|
||||
EBITDA;01.01.2022;10,748
|
|
@ -0,0 +1,33 @@
|
||||
Metrik;Datum;Summe [Milliarden €]
|
||||
Umsatz;01.01.2007;66,912
|
||||
Umsatz;01.01.2008;84,873
|
||||
Umsatz;01.01.2009;79,974
|
||||
Umsatz;01.01.2010;92,863
|
||||
Umsatz;01.01.2011;112,954
|
||||
Umsatz;01.01.2012;132,093
|
||||
Umsatz;01.01.2013;119,615
|
||||
Umsatz;01.01.2014;113,095
|
||||
Umsatz;01.01.2015;42,656
|
||||
Umsatz;01.01.2016;38,173
|
||||
Umsatz;01.01.2017;37,965
|
||||
Umsatz;01.01.2018;30,084
|
||||
Umsatz;01.01.2019;41,284
|
||||
Umsatz;01.01.2020;60,944
|
||||
Umsatz;01.01.2021;77,358
|
||||
Umsatz;01.01.2022;115,66
|
||||
EBIT;01.01.2012;7,01
|
||||
EBIT;01.01.2013;5,64
|
||||
EBIT;01.01.2014;4,7
|
||||
EBIT;01.01.2015;3,6
|
||||
EBIT;01.01.2016;3,1
|
||||
EBIT;01.01.2017;3,1
|
||||
EBIT;01.01.2018;2,99
|
||||
EBIT;01.01.2019;3,22
|
||||
EBIT;01.01.2020;3,78
|
||||
EBIT;01.01.2021;4,72
|
||||
EBIT;01.01.2022;5,2
|
||||
EBITDA;01.01.2018;4,84
|
||||
EBITDA;01.01.2019;5,558
|
||||
EBITDA;01.01.2020;6,905
|
||||
EBITDA;01.01.2021;7,889
|
||||
EBITDA;01.01.2022;8,059
|
|
@ -0,0 +1,42 @@
|
||||
Metrik;Datum;Summe [Milliarden €]
|
||||
Umsatz;01.01.2005;59,6
|
||||
Umsatz;01.01.2006;61,3
|
||||
Umsatz;01.01.2007;62,5
|
||||
Umsatz;01.01.2008;61,7
|
||||
Umsatz;01.01.2009;64,6
|
||||
Umsatz;01.01.2010;62,42
|
||||
Umsatz;01.01.2011;58,65
|
||||
Umsatz;01.01.2012;58,17
|
||||
Umsatz;01.01.2013;60,13
|
||||
Umsatz;01.01.2014;62,66
|
||||
Umsatz;01.01.2015;69,23
|
||||
Umsatz;01.01.2016;73,1
|
||||
Umsatz;01.01.2017;74,95
|
||||
Umsatz;01.01.2018;75,66
|
||||
Umsatz;01.01.2019;80,53
|
||||
Umsatz;01.01.2020;99,95
|
||||
Umsatz;01.01.2021;107,61
|
||||
Umsatz;01.01.2022;114,2
|
||||
EBIT;01.01.2005;7,6
|
||||
EBIT;01.01.2006;5,3
|
||||
EBIT;01.01.2007;5,3
|
||||
EBIT;01.01.2008;7
|
||||
EBIT;01.01.2009;6
|
||||
EBIT;01.01.2010;5,51
|
||||
EBIT;01.01.2011;5,56
|
||||
EBIT;01.01.2012;-3,96
|
||||
EBIT;01.01.2013;4,93
|
||||
EBIT;01.01.2014;7,25
|
||||
EBIT;01.01.2015;7,03
|
||||
EBIT;01.01.2016;9,16
|
||||
EBIT;01.01.2017;9,38
|
||||
EBIT;01.01.2018;8
|
||||
EBIT;01.01.2019;9,46
|
||||
EBIT;01.01.2020;12,37
|
||||
EBIT;01.01.2021;12,58
|
||||
EBIT;01.01.2022;15,41
|
||||
EBITDA;01.01.2018;23,333
|
||||
EBITDA;01.01.2019;24,731
|
||||
EBITDA;01.01.2020;35,017
|
||||
EBITDA;01.01.2021;37,33
|
||||
EBITDA;01.01.2022;40,208
|
|
@ -0,0 +1,20 @@
|
||||
Mohammed;Klein
|
||||
Myriam;Koch
|
||||
Dorothe;Zerusedemeiner
|
||||
Emine;Puviplau
|
||||
Galina;Tosewede
|
||||
Hans-Walter;M<>didostein
|
||||
Ludmilla;Krause
|
||||
Jessica;Lesibedemeiner
|
||||
Franz;Lowufohein
|
||||
Krzysztof;Gaselatem<65>ller
|
||||
Gerolf;Navusedeson
|
||||
Sibylla;Sutedihein
|
||||
Nina;Golebede
|
||||
Alicja;Revibodomeiner
|
||||
Meryem;Kadeduhein
|
||||
Janina;Zimmermann
|
||||
Hendrik;Kr<4B>ger
|
||||
Oskar;Podadi
|
||||
Maria-Luise;Nelaflodeson
|
||||
Nadine;Niwogatemeiner
|
|
@ -0,0 +1,19 @@
|
||||
Company_HR;Company_Court;Jahr;Umsatz;Ebit;EBITDA
|
||||
;12336;5;2005;59600;7600;
|
||||
;12336;5;2006;61300;5300;
|
||||
;12336;5;2007;62500;5300;
|
||||
;12336;5;2008;61700;7000;
|
||||
;12336;5;2009;64600;6000;
|
||||
;12336;5;2010;62420;5510;
|
||||
;12336;5;2011;58650;5560;
|
||||
;12336;5;2012;58170;-3960;
|
||||
;12336;5;2013;60130;4930;
|
||||
;12336;5;2014;62660;7250;
|
||||
;12336;5;2015;69230;7030;
|
||||
;12336;5;2016;73100;9160;
|
||||
;12336;5;2017;74950;9380;
|
||||
;12336;5;2018;75660;8000;23333
|
||||
;12336;5;2019;80530;9460;24731
|
||||
;12336;5;2020;99950;12370;35017
|
||||
;12336;5;2021;107610;12580;37330
|
||||
;12336;5;2022;114200;15410;40208
|
|
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 7.0 KiB |
After Width: | Height: | Size: 39 KiB |
After Width: | Height: | Size: 19 KiB |
After Width: | Height: | Size: 16 KiB |
After Width: | Height: | Size: 59 KiB |
After Width: | Height: | Size: 29 KiB |
After Width: | Height: | Size: 54 KiB |
After Width: | Height: | Size: 30 KiB |
After Width: | Height: | Size: 100 KiB |
@ -24,7 +24,7 @@ Werken anderer Autoren entnommen sind, habe ich als solche kenntlich
|
||||
gemacht. Die Arbeit wurde bisher weder gesamt noch in Teilen einer
|
||||
anderen Prüfungsbehörde vorgelegt und auch noch nicht veröffentlicht.
|
||||
|
||||
2023-10-01
|
||||
2023-10-01
|
||||
|
||||
<img src="abbildungen/unterschrift.PNG" alt="image" />
|
||||
|
||||
@ -413,7 +413,7 @@ Für die Erstellung der Daten wird mit der Python Bibliothek Pandas aus
|
||||
einer Excel Datei Mockup-Daten zu verschiedenen Automobilherstellern
|
||||
geladen.
|
||||
|
||||
``` {.python language="Python" breaklines="true"}
|
||||
```python
|
||||
# import pandas
|
||||
import pandas as pd
|
||||
|
||||
@ -429,7 +429,7 @@ node_color = {
|
||||
'Automobilhersteller': ' #729b79ff',
|
||||
'Automobilzulieferer': '#475b63ff',
|
||||
'Branche 3': '#f3e8eeff',
|
||||
'Branche 4': '#bacdb0ff',
|
||||
'Branche 4': '#bacdb0ff',
|
||||
'Branche 5': '#2e2c2fff',
|
||||
}
|
||||
df_nodes['color'] = df_nodes['branche'].map(node_color)
|
||||
@ -447,11 +447,11 @@ print(df_nodes.head())
|
||||
Als Ergebnis erhält man ein Dataframe mit den verschiedenen
|
||||
Automobilherstellern.
|
||||
|
||||
| **ID** | **Name** | **Typ** |
|
||||
|--------|---------------------------|---------|
|
||||
| 1 | Porsche Automobil Holding | Company |
|
||||
| 2 | Volkswagen AG | Company |
|
||||
| 3 | Volkswagen | Company |
|
||||
| **ID** | **Name** | **Typ** |
|
||||
|--------|----------|---------|
|
||||
| 1 | Porsche Automobil Holding | Company |
|
||||
| 2 | Volkswagen AG | Company |
|
||||
| 3 | Volkswagen | Company |
|
||||
|
||||
*Tabelle 1: Tabelle der Automobilhersteller.*
|
||||
|
||||
@ -463,7 +463,7 @@ erstellt, aus welchem mit der Bibliothek NetworkX ein Graph erstellt
|
||||
wird. Dafür wird die Methode from_pandas_edgelist genutzt - diese
|
||||
erstellt aus einem Dataframe einen Graphen.
|
||||
|
||||
``` {.python language="Python" breaklines="true"}
|
||||
```python
|
||||
# import networkx
|
||||
import networkx as nx
|
||||
|
||||
@ -539,7 +539,7 @@ Netzwerks zugegriffen werden. Diese wird zu Nutze gemacht, um in einer
|
||||
for-Schleife die Größe der Ecken neu zu setzen. Der Quellcodes sieht wie
|
||||
folgt aus:
|
||||
|
||||
``` {.python language="Python" breaklines="true"}
|
||||
```python
|
||||
adj_list = net.get_adj_list()
|
||||
|
||||
measure_vector = {}
|
||||
@ -840,4 +840,4 @@ Springer Fachmedien Wiesbaden, 2020, S. 269–300, isbn: 9783658265236.
|
||||
|
||||
- **[7]** A. Disney,https://cambridge-intelligence.com/keylines-faqs-social-network-analysis/.
|
||||
|
||||
- **[8]** C. Intelligence, https://cambridge-intelligence.com/social-network-analysis/.
|
||||
- **[8]** C. Intelligence, https://cambridge-intelligence.com/social-network-analysis/.
|
||||
|