Autor Thema: Vorteil von DBzugriffssprachen vers. Objekthierarchien: Aggregierungsfunktionen  (Gelesen 1346 mal)

Offline flaite

  • Gold Platin u.s.w. member:)
  • *****
  • Beiträge: 2.966
    • mein del.icio.us
Hi,

ich fand immer die vorhandenen Vergleiche zwischen LotusScript und Formelsprache seltsam oberflächlich.
Von einer Aufgabe aus Java gegen RDBMS ist mir ein Aspekt jetzt sehr deutlich geworden.
Objekte sind meist in Hierarchien angelegt (Objektgraphen). Ist ja in LotusScript auch so.
Von NotesDatabase springt man auf NotesView. Und aus der NotesView bekommt man eine NotesDocumentCollection. Über diese kann man dann über einzelne Dokumente iterieren.
Über diese hierarchische, baumartige Anordnung der Objekte in sogenannten Containment Beziehungen (NotesDocumentCollection contains lots_of_NotesDocuments, NotesDatabase contains lots of NotesViews, NotesSession contains NotesDatabase, etc.) kann man auf übersichtliche Art und Weise auf allemöglichen Operationen und Daten einer NotesDatenbank zugreifen. Und zwar auf sehr einfache Weise. Das ist das Geheimnis von LotusScript und allen Objektgraphen allgemein. (Hey. Das war jetzt ein guter Satz).
In dem Objektmodell einer Java Anwendung sind die Objekte typischerweise in ähnlichen baumartigen Strukturen angelegt.

Nun gibt es aber Fälle, die in diese baumartige Struktur nicht gut reinpassen.

Beispiel aus meinem Börsenspiel:
Ich möchte alle 60 Minuten eine Highscoreliste erstellen und diese in die Datenbank schreiben. Die Datenbank ist in dieser Anwendung eine Posgres Datenbank (SQL d.h. RDBMS). Die Objekte sind Java powered by Springframework aber das tut nicht so viel zur Sache. Ich komme auf Formelsprache vs. LotusScript zurück.

Was für Informationen brauche ich für diese HighScoreliste?
Um das vielleicht ein bischen anschaulicher zu machen hier die Resultsets mit Testdaten:
Code
fussi2=# select id, nameuser, money from Person where ID < 3 ORDER BY ID;
 id |   nameuser    |  money
----+---------------+----------
  1 | AXEL JAN├ƒEN   | 16031.00
  2 | LOTUS SCHMIDT | 23969.00
(2 Zeilen)

fussi2=# select id, longname, price from StockDescr ORDER BY ID;
 id |         longname         | price
----+--------------------------+-------
  1 | Bayern M├╝nchen           | 40.50
  2 | Borussia M├Ânchengladbach | 40.50
  3 | Schalke 04               |  0.00
(3 Zeilen)

fussi2=# select idUser, idStockDescr, amount from StockUser WHERE idUSER < 3 ORD
ER BY idUser, IdStockDescr;
 iduser | idstockdescr | amount
--------+--------------+--------
      1 |            1 |    548
      1 |            2 |    550
      1 |            3 |    500
      2 |            1 |    452
      2 |            2 |    450
      2 |            3 |    500
(6 Zeilen)

fussi2=#

Die Informationen stammen aus 3 Tabellen in der SQL Datenbank. NotesDokumente wären hier vermutlich ähnlich aufgebaut. Es sollte nicht schwer sein, sich diese ResultSets als Notes-Ansichten vorzustellen.

Ein User hat einen bestimmte Menge an Bargeld -> steht in Tabelle Person. Spalte money.
Ein User hat eine bestimmte Menge an Aktien verschiedenden Typs: steht in Tabelle StockUser (Spalten: idStockDescr->Typ Aktie, idUser-> der User (Fremdschlüssel auf Person-Tabelle), amount-> Menge der Aktie über die User verfügt).
Eine Aktie hat einen Preis (in Tabelle StockDescr.Money).

Wie bestimmt sich nun die Highscoreliste?
Ganz einfach: Der Wert des Aktienportfolios des Users + Bargeldbestand.

Unter der Annahme, dass die Objekte genau die Tabellen wiedergeben ist dies über eine hierarchisches Objektmodell nur über große Qualen herauszubekommen.
Ich schreib das mal in LotusScript Pseudosprache schnell runter, um den Punkt klar zu machen:

Code
Dim s as new NotesSession
dim db as NotesDatabase
Dim vwStockDescr as NotesView
Dim vwPerson As NotesView
Dim vwStockUser as NotesView

Dim colStockUser As NotesDocumentCollection
Dim docPerson As NotesDocument
Dim docStockDescr as NotesDocument
Dim docStockUser as NotesDocument
Dim totalAssetValuePerson As Double
Dim keyStockUser As String


set db = s.currentDatabase
set vwPerson = db.getView("Person")
set vwStockDescr = db.getView("StockDescr")
set vwStockUser = db.getView("StockUser")

set docPerson = vwPerson.getFirstDocument
' alle Personen iterieren
do while not docPerson is Nothing
totalAssetValuePerson = 0.00
' person.Money ist Teil des TotalAssetValuePerson
totalAssetValuePerson = totalAssetValuePerson + docPerson.getItemValue("Money")(0)

' nun Summe aus Wert_der_Aktie + Menge_die_User_davon_hat errechnen
keyStockUser  = docPerson.id(0)
set colStockUser = vwStockUser.getAllDocumentsByKey(idUser)

set docStockUser = colStockUser.getFirstDocument
Do while not docStockUser is Nothing
amountOfStock = docStockUser.getItemValue("amount")(0)
' nun StockDescr-Dokument holen: 
docStockDescr = vwStockDescr.getDocumentByKey(docStockUser.idStockDescr(0))
valueOfStock = docStockDescr.getItemValue("price")(0)
' Wert amount * price dieser Aktienposition
totalAssetValuePerson = totalAssetValuePerson + (amountOfStock * valueOfSTock)
set docStockUser = colStockUser.getNextDocument(docStockUser)
end do while
print "Person " + docPerson.nameUser(0) + " besitzt Aktiva im Wert von " + totalAssetValuePerson
set docPerson = vwPerson.getNextDocument(docPerson)

end do while
Man sieht: Eine Meeeeeennnnnnge Code und zusätzlich eine Meeeeeennnnge an LookUps gegen den Server.
Und ich hab die Highscoreliste noch nicht mal sortiert. Ich hab nur unsortierte Informationen darüber, wieviel der Wert des Portfolio jedes einzelnen Users ist.

Mit naiven Java Code würde es genauso aussehen. Enterprise Java Beans leidet übrigens unter dem genau gleichen Problem -> heisst dort nur 1+ n select Dilemma oder so ähnlich.

Nun bietet aber SQL (und Notes-Formelsprache) Aggregierungsfunktionen, mit denen man diese Aufgabe sehr, sehr, sehr viel schneller erledigen kann.
Der entsprechende PosgresSQL Query lautet:
Code
select 
  StockUser.IDUSER, 
  Person.NameUser, 
  sum(STOCKUSER.AMOUNT * StockDescr.Price) + Person.Money AS totalAssetValuePerson 
  Where StockUser.IDStockDescr=StockDescr.ID AND StockUser.IDUser = Person.ID AND PERSON.ID < 3 
GROUP By StockUser.IDUser, Person.NameUser, PERSON.MONEY 
ORDER BY totalAssetValuePerson DESC;

Es ergibt diese Tabelle:
 iduser |   nameuser    | totalvaluestockperson
--------+---------------+-----------------------
      2 | LOTUS SCHMIDT |              60500.00
      1 | AXEL JAN├ƒEN   |              60500.00
(2 Zeilen)
Dieser SQL Code erfüllt die gestellte Aufgabe mit eindeutig weniger Zeilen als der obige LotusScript Code oder entsprechender Java-Code. Was noch wichtiger ist: Es wird nur 1 Query gegen die Datenbank gesandt und das ist seeeehhhhr gut für die Performance. Durch die Order-By Clause hat man auch noch eine absteigende Sortierung nach TotalValueStockPerson.

Was ist der Trick?
SQL ist eben nicht an starr verdrahtete Objekt-Hierarchien gebunden, sondern hat eigene Möglichkeiten Daten zu aggregieren. Die Arbeit leistet hier die arithmetischen Operatoren in der Spalte mit dem Label totalStockValuePerson, die Summenfunktion sowie die Group By Clause. Die Syntax des Queries selber ist imho komplexer als die Punktnotation bei hierarchischen Objektbäumen. Die Reihenfolge der Operationen ist wichtig und nicht unbedingt transparent. Für mich nach wie vor anstrengend, solche komplexeren Queries zu bauen. Nicht wegen der Syntax, sondern wegen der doch nicht unkomplexen Logik von Relationalen Datenbanken. Auf der anderen Seite hat man für diese Aufgabe eine sehr mächtige Flexibilität, die eben den Preis hat, dass solche Queries nicht so direkt einfach zu schreiben sind.

Was hat das mit Formelsprache zu tun?
Nun. Formelsprache besitzt auch Aggregierungsfunktionen und Listenoperationen. Ich bin mir ziemlich sicher, dass sich diese Aufgabe auch leicht mit Formelsprache lösen läßt. Wenn jemand Lust hat.

DAS SOLLTE JETZT KEINE VERÄPPELUNG SEIN. Ich hab jetzt einfach keine Kraft mehr und hole das später nach.
DER PUNKT IST: Ich glaub hier ist möglicherweise ein wirklich rational nachprüfbares Entscheidungskriterium, dass an dieser Stelle Formelsprache wirklich besser ist.
Oder besitzt für diese konkrete Aufgabe Formelsprache weniger Möglichkeiten als SQL.

Axel

« Letzte Änderung: 07.08.05 - 22:09:10 von kennwort »
Ich stimm nicht mit allen überein, aber mit vielen und sowieso unterhaltsam -> https://www.youtube.com/channel/UCr9qCdqXLm2SU0BIs6d_68Q

---

Aquí no se respeta ni la ley de la selva.
(Hier respektiert man nicht einmal das Gesetz des Dschungels)

Nicanor Parra, San Fabian, Región del Bio Bio, República de Chile

 

Impressum Atnotes.de  -  Powered by Syslords Solutions  -  Datenschutz