Molaskes: Wegbereiter und Vorreiter

Innovationen von Molaskes:Das DDGDS-Dateisystem

DDGDS steht für "Dynamisch Definiertes Giganutzer Daten-System". Es ist eine Massen-Multinutzer-Datenbank (MMDB) für zum Beispil große soziale oder E-Commerce-Websites. Sie nutzt DDas GDS-Dateiformat (GDS = "Grouped Data String") auf besonders effiziente Art und Weise. Während Mediendateien mit ihrer jeweiligen Dateiendung (etwa *.jpg) gespeichert werden, haben die Datenbank-Dateien von DDGDS keine Dateiendung. Das DDGDS arbeitet mit GDS-kompatiblen Arrays, die Zahlen-Strings als Schlüssel verwenden (etwa "123") anstelle der tatsächlichen alphanumerischen Srins (etwa "Haupt-Text"), die der Programmierer verwendet und die in einem separaten, Dateitypen-Definitionen-Array _types vorgehalten werden, nur zu verwenden mit speziellen Schreib-/Lese-Funktionen, die dynamisch die Zuordnungen für den programmierer verwalten. Dies spart so einiges an Speicherplatz auf dem Server. Hier ist ein schematisches Beispiel einer _types-Definition:
0:Nutzer
  0:Name
  1:Auth
  2:Avatar
  3:Freunde
    0:NutzerID
    1:Spitzname
    2:xAvatar
  4:Gruppen
1:Gruppe
  0:Titel
  1:Logo
  2:Mitgliederzahl
  3:Admins
...
‌ Die Schlüsselnamen in einem Blocks müssen einzigartig sein, da die Software mit einer Rückwärts-Nachschlagetabelle arbeitet. In unserem Beispiel würde diese etwa wie folgt aussehen:
Nutzer:0
  Name:0
  Auth:1
  Avatar:2
  Freunde:3
    NutzerID:0
    Spitzname:1
    xAvatar:2
  Gruppen:4
Gruppe:1
  Titel:0
  Logo:1
  Mitgliederzahl:2
  Admins:3
...
‌ Keine zwei Schlüsselnamen im selben Block dürfen auf dieselbe blockspezifische Indexnummer zeigen, weshalb die Schlüsselnamen innerhalb ihres Blocks einzigartig sein müssen. Während man jederzeit neue Felder unten an einen Block anfügen kann, sollte man aus Gründen der Abwärtskompatibilität am besten niemals die Einträge innerhalb eines Blocks umsortieren, wenn er bereits in Benutzung ist, und man sollte man Einträge aus einem solchen Block auch niemals löschen. Einträge, die veraltet sind, kann man in einzigartige gesonderte Schlüsselnamen umbenennen, wie in diesem Beispiel (achte auf die zwei Felder "veraltet1" und "veraltet2"):
...
2:Brief
  0:von_NutzerID
  1:an_NutzerID
  2:veraltet1
  3:veraltet2
  4:Überschrift
  5:Textkörper
  6:gesendet_DT
  7:gelesen_DT
... 
‌ Alle DDGDS-Arrays werden ,ausschlieĺich indirekt verwendet von den Anwendungsprogrammierern, nämlich über Verwaltungsfunktionen, niemals als die direkten Roh-Arrays. Wir schauen uns nun Eas-Beispiele (siehe E→Molaskes.info/Eas) für diese Funktionen an, wobei wir annehmen, dass wir von der Festplatte eine wie oben definierte Nutzerdatei eingelesen haben. Das GDS-dekodierte Array wird in der Variablen NutzerVar vorgehalten. Um die oberste Ebene "leichter verdaulich" zu machen, rufen wir NutzerVarX DDGDS'Get:NutzerVar auf. Die Variable NutzerVarX wird dann ein reguläres Array mit Schlüsseln sein, mit vielleicht folgendem Inhalt:
"Name":"Lara Da Vinci"
"Auth":"0X2-7Wix_wU327UwxWj3-s3k"
"Avatar":"lara2.jpg"
"Freunde":35
"Gruppen":"i3Xu43F 93Wh_W2 wkSjwAx"
Die Gruppen hier sind eine Leerzeichen-separierte Liste von Eintrags-IDs (mehr dazu später), aber viel wichtiger für uns ist hier, dass die Freunde, die in der Format-Definition oben einen Unterblock bilden, nur als einzelner Zahlenwert zurückgegeben werden. Dies liegt daran, dass solche Unterblöcke immer eine schlüssellose Liste/Array implizieren, in der jeder Eintrag in seiner Struktur durch den Unterblock definiert ist. Der Wert, den wir erhalten, ist die Anzahl aller Elemente, also in diesem Fall die Anzahl von Laras Freunden. Alternativ kann man auch jeden beliebigen Wert direkt auslesen, etwa über DDGDS'Get:NutzerVar "Avatar", was hier "lara2.jpg" zurückgeben würde. Wenn wir nun die Daten zum 6. Freund auslesen wollten (beachte, dass Indizes mit 0 beginnen), würden wir einfach derFreund DDGDS'Get:NutzerVar "Freunde:5" aufrufen, was die Variable derFreund etwa wie folgt füllen könnte:
"NutzerID":"bZ3oSu9"
"Spitzname":"Pauli"
"xAvatar":"mein Pauli.jpg"
‌ Das Schreiben funktioniert nur mit direkten Feldbezügen; wenn Lara also ihr Avatar-Bild geändert hat, würden wir etwa DDGDS'Set:NutzerVar "Avatar" "Lara_am_Strand.jpg", aufrufen, und einen neuen Freund hinzufügen für sie würde beispielsweise erfolgen über:
DDGDS'Set:NutzerVar "Freunde:35:NutzerID" "wj3Dh0G"
DDGDS'Set:NutzerVar "Freunde:35:Spitzname" "Minna"
DDGDS'Set:NutzerVar "Freunde:35:xAvatar" "minna.jpg"
‌ Aus Gründen der Datensicherheit sollte das Schreiben von Leerwerten nicht zulässig sein, und man sollte vielmehr zum Löschen von Einträgen eine designierte Funktion nutzen müssen, welche alle wichtigen Schlüssel:Wert-Zuordnungen intakt lässt. Schlüssellose Listeneinträge jedoch werden auch in den Rohdaten einfach gelöscht. Hier ein paar Beispiele für das Löschen von Elementen:
DDGDS'Delete:NutzerVar "Avatar"
DDGDS'Delete:NutzerVar "Freunde:35:Spitzname"
DDGDS'Delete:NutzerVar "Freunde:20"
Beachte, dass beim Löschen schlüsselloser Listeneinträge alle Indizes der nachfolgenden Listen-Elemente um eins verringert werden. In unserem Beispiel würde der Eintrag "Freunde:35" nach dem Löschen von "Freunde:20" nun über "Freunde:34" anzusprechen sein. Alle Dateien im DDGDS erhalten eine Eintrags-ID, welche der Eas-BASE:64-encodierte DateTime-Wert ihrer Erstellzeit ist. Deren Einzigartigkeit pro Verzeichnis wird sichergestellt durch ein Datenbank-Sperrprotokoll (sperren durch Nutzer — Nutzer prüfen — schreiben — entsperren). (Eas BASE:64 unterscheidet sich von den meisten älteren Base64-Implementierungen, indem es vollständig kompatibel ist mit allen niederbasigeren mathematischen Notationen, mit 0–9 für die ersten zehn Ziffern (Dezimalzahlen), dann die Großbuchstaben A–Z (Hexadezimalzahlen und darüber hinaus, für Werte 10–35), dann der Unterstrich "_" für den Wert 36, dann die Kleinbuchstaben a–z für die Werte 37-62 und schließlich der Minusstrich "-" für den Wert 63.) Wenn wir die Nutzerdaten von Laras Freund "Pauli" laden wöllten, würden wir DDGDS'Load:"Nutzer" "bZ3oSu9" aufrufen, was tatsächlich die Datei mit dem Pfad ./Nutzer/b/Z/3/o/S/u/9/_ laden würde, wobei die Eintrags-ID Zeichen für Zeichen aufgesplittet würde in einen Unterverzeichnis-Pfad mit jeweils nicht mehr als 64 verschiedenenen Einträgen und die Kerndaten in einer einfach mit einem Unterstrich "_" benannten Datei gespeichert sind. Wenn Pauli nun vorhätte, Laras neueste Privatnachricht zu lesen, würde der Servercode beispielsweise DDGDS'Load:"Nutzer" "bZ3oSu9" "PN" "29D3-jX/w3Wkf31" aufrufen, was tatsächlich die Datei ./Nutzer/b/Z/3/o/S/u/9/PN/29D3-jX/w3Wkf31 laden würde, wobei 29D3-jX Laras Nutzer-ID und w3Wkf31 die ID der eigentlichen Nachricht wäre. Wenn Lara an ihrem Nutzerprofil Änderungen vorgenommen hat, können wir die Daten auf dem Server aktualisieren über DDGDS'Save:"Nutzer" "29D3-jX" NutzerVar. Dieselbe Funktion wird auch zum Erstellen neuer Einträge auf der Festplatte genutzt, etwa wenn eine neue Privatnachricht gesendet wird. Aus Gründen des Datenschutzes bzw. zur Wahrung der Privatsphäre sollte es die erweiterten Funktionen DDGDS'SaveX und DDGDS'LoadX geben, wobei erstere die Datei obfuskiert, was einfach nur bedeutet, dass sie für Menschen unleserlich gemacht wird, und letztere die Obfuskation wieder rückgängig macht, ehe die Datei zum Auslesen GDS-geparst wird. Dies ist etwa wichtig für Privatnachrichten. Admins mit Direktzugriff auf die Serverdaten (etwa über FTP) könnten dann beispielsweise nicht mehr lesen: Mist, Schatz, mein Test war positiv!!! Was nun??? …, sondern würden stattdessen nur etwas sehen wie Folgendes: 3Iaw_ "oW!s.JRxii74 w:icEFW+ 3qyY -19?k_ xEw76xzC …. Die tatsächliche Login-Authentifizierung sollte ein besonderes Verzeichnis nutzen mit Unterverzeichnissen, die aufgespreizte Login-Namen repräsentieren anstelle von Base64IDs. Nutzernamen müssten dann einzigartiges sein, wenn sie transformiert werden in eine vereinfachte Authentifizierungsfom, etwa wenn der Nutzername "René Knödel" in den Login-Namen "rene_knoedel" umgewandelt wird, für welchen die Login-Authentifizierungs-Daten (Passwort-Authentifizierungs-Siegel und Nutzer-ID) abgespeichert würden in ./Login/r/e/n/e/_/k/n/o/e/d/e/l/_. Wenn ein Nutzer seinen Nutzernamen und sein Passwort eingegeben hat, würde die Login-Authentifizierungs-Prüfung ungefähr so ablaufen:
Login Nutzername Passwort:
  n LoginName:Nutzername
  authDaten DDGDS'Load:"Login" n
  pwSiegel DDGDS'Get:authDaten "Siegel"
  ? pwSiegel#(AuthSeal:Passwort) << 0
  nutzerID DDGDS'Get:authDaten "Nutzer"
  nutzerDaten DDGDS'Load:"Nutzer" nutzerID
  lt NewLoginToken!
  DDGDS'Set:nutzerDaten "Auth" lt
  COOKIE:"Auth" nutzerID;":";lt
  << 1 — Login erfolgreich
/
(Das zufällige Login-Token wird verwendet, um bei jedem Zugriff zu verfizifieren, dass das Login-Cookie des Nutzers wirklich valide ist, das Ergebnis eines sauberen Logins mit dem korrekten Passwort.)
05. Das DDGDS-Dateisystem
K Startseite + Kontakt
Esc Suche / Inhaltsverzeichnis
Tab