M.Klein: RDBMS oder NoSQL

Hallo,

ich bin bei der Planung eines Projektes an einem Punkt, an dem ich mir nicht gänzlich sicher bin, welche Art der Datenhaltung angebracht wäre.

Es geht um einen Fragekatalog, der alle möglichen Antworten dynamisch abdecken können soll. Im einfachsten Fall gibt es eine MultipleChoice-Frage. In komplexesten Fall eine Frage mit einem frei konfigurierbaren Formular mit diversen Eingabefeldern - auch Select-Boxen.

Und genau hierbei stoße ich auf Probleme bei der Normalisierung der Datenbank.

Vereinfachtes Beispiel:
DB-Schema - Preview

BUILDER_INQUIRY besitzt einen reply_type (input, multiple_choice, etc). Anhand diesen könnte ich dann in der Anwendung die entpsrechende Referenztabelle joinen.

BUILDER_REPLY_INPUT und BUILDER_REPLY_MULTIPLE_CHOICE sind nur zwei Beispiele der möglichen Antwort-Typen.

Problembeschreibung Selectbox (Bsp):
Ein Inquiry könnte den Reply-Typen "INPUT" besitzen. Durch 1:n könnten dem Inquiry mehrere Inputs zugeordnet werden. Gesetz den Fall, dass davon eines eine Selectbox ist, müssten nun auch die Values und Keys entsprechend angegeben werden können. Das hieße ich müsste extra (=ausschließlich) für die Selectboxen weitere Felder hinzufügen. Oder eine weitere Tabelle erstellen.

Mir ist der Anwendungsfall irgendwie zu flexibel um ihn normalisiert zu halten.
Daher meine Frage, ob in diesem Fall nicht evtl. zu einer NoSQL-Datenbank zu raten wäre.

Über Eindrücke würde ich mich freuen.

Danke & MfG
M.Klein

  1. Hallo,

    hier mal ein Beispiel wie ich mir eine dokumentenbasierte Konfiguration vorstelle:

      
    {  
      "_id": "id_builder_area_01",  
      "contract": "DBRef..",  
      "position" : 2,  
      "name" : "Beginn und Dauer",  
      "inquiries" : [  
          {  
            "_id": "id_builder_inquiry_01",  
            "name": "Vertragsart",  
            "phrase" : "Möchten Sie einen befristeten oder unbefristeten Arbeitsvertrag abschließen?",  
            "short_description": "Sie können sich hier direkt für einen befristeten...",  
            "long_description": "Einige Vorfragen zur Auswahl eines befristeten oder unbefristeten Arbeitsvertrags ...",  
            "reply": {  
              "type": "MULTIPLE_CHOICE",  
              "entities": [  
                {  
                  "option": "Unbefristeter Vertrag",  
                  "value": 0,  
                  "tooltip": "Lorem Ipsum",  
                  "next_inquiry": "id_builder_inquiry_03"  
                },  
                {  
                  "option": "Befristeter Vertrag",  
                  "value": 1,  
                  "tooltip": "Lorem Ipsum",  
                  "next_inquiry": "id_builder_inquiry_03"  
                },  
                {  
                  "option": "Vertragsart erörtern",  
                  "value": 2,  
                  "tooltip": "Lorem Ipsum",  
                  "next_inquiry": "id_builder_inquiry_02"  
                }  
              ]  
            }  
          },  
          {  
            "_id": "id_builder_inquiry_02",  
            "name": "Erörterung",  
            "phrase" : "Wählen Sie eine der folgenden Möglichkeiten aus.",  
            "short_description": "Anhand Ihrer Auswahl ermitteln wir automatisch, ob für Sie ein befristeter oder unbefristeten Arbeitsvertrag in Frage kommt",  
            "reply": {  
              "type": "MULTIPLE_CHOICE",  
              "entities": [  
                {  
                  "option": "Frage Nr.1",  
                  "value": 0,  
                  "next_inquiry": "id_builder_inquiry_03"  
                },  
                {  
                  "option": "Frage Nr. 2",  
                  "value": 1,  
                  "tooltip": "Lorem Ipsum",  
                  "next_inquiry": "id_builder_inquiry_03"  
                }  
              ]  
            }  
          },  
          {  
            "_id": "id_builder_inquiry_03",  
            "name": "Arbeitnehmerinformationen",  
            "phrase" : "Bitte fügen Sie die persönlichen Daten des Arbeitnehmers an.",  
            "reply": {  
              "type": "INPUT",  
              "next_inquiry": "id_builder_inquiry_04",  
              "entities": [  
                {  
                  "type": "SELECT",  
                  "name": "gender",  
                  "validator": "TODO",  
                  "required": true,  
                  "options": [  
                    {  
                      "value": "m",  
                      "text": "Herr"  
                    },  
                    {  
                      "value": "f",  
                      "text": "Frau"  
                    }  
                  ]  
                },  
                {  
                  "type": "DEFAULT",  
                  "name": "first_name",  
                  "validator": "TODO",  
                  "required": true,  
                  "tooltip": "Ihr Vorname"  
                },  
                {  
                  "type": "DEFAULT",  
                  "name": "last_name",  
                  "validator": "TODO",  
                  "required": true,  
                  "tooltip": "Ihr Nachname"  
                }  
              ]  
            }  
          }  
       ]  
    }  
    
    

    Wie man dort gut sieht bietet diese Art der Persistierung eine durchaus höhere Flexibilität. In einem RDBMS ließe sich dieses natürlich auch abbilden, aber es würde doch einer erheblichen Anzahl an Tabellen bedürfen.

    MfG
    M.Klein

    1. Hallo,

      hier mal ein Beispiel wie ich mir eine dokumentenbasierte Konfiguration vorstelle:

      [code lang=javascript]
      {
        "_id": "id_builder_area_01",
        "contract": "DBRef..",
        "position" : 2,
        "name" : "Beginn und Dauer",
        "inquiries" : [
            {
              "_id": "id_builder_inquiry_01",
              "name": "Vertragsart",
              "phrase" : "Möchten Sie einen befristeten oder unbefristeten Arbeitsvertrag abschließen?",
              "short_description": "Sie können sich hier direkt für einen befristeten...",
              "long_description": "Einige Vorfragen zur Auswahl eines befristeten oder unbefristeten Arbeitsvertrags ...",
              "reply": {
                "type": "MULTIPLE_CHOICE",
                "entities": [

      Das schreit nach sowas:
      Data storage model, Data abstraction

      Hostname:Port.Databasename.Tablename.Entityname.HashOfHashes
                                                         ^
                                Data Abstraction Layer   | Application

      D.h., es macht keinen Sinn, o.g. Strukturen in Relationalen RDBMS abbilden zu wollen, das würde eine unüberschaubare Anzahl an Tabellen ergeben. Hier ists besser, die Strukturen allein der Anwendung zu überlassen. Trozdem lohnt es sich, über eine Speicherung in einem RDBMS nachzudenken, weil somit bestimmte Daten gezielt abgefragt werden können mittels SQL. Dies wiederum schließt ein einfaches Serialisieren nach BLOB-Feldern jedoch aus.

      Horst Spelzenspülz

      --

  2. Tach!

    BUILDER_INQUIRY besitzt einen reply_type (input, multiple_choice, etc). Anhand diesen könnte ich dann in der Anwendung die entpsrechende Referenztabelle joinen.

    Was du joinen musst, weißt du erst, wenn du die Werte aus der einen Tabelle kennst. Du kannst nicht von Fall zu Fall zu jedem Datensatz einzeln eine andere Tabelle joinen. Das heißt, du kannst gar nicht joinen, oder für jeden Typ eine eigene Query erstellen. Was fragst du denn für Daten ab? Eine Frage und deren Antworten oder mehrere Fragen und deren Antworten? In beiden Fällen wäre zunächst die eine Tabelle zu befragen und dann passend die anderen Tabellen. Nur bei mehreren kann man dann eventuell noch was optimierne, indem man die Antworttypen zusammenfasst und dann gemeinsam deren Antworten abfragt.

    Mir ist der Anwendungsfall irgendwie zu flexibel um ihn normalisiert zu halten.
    Daher meine Frage, ob in diesem Fall nicht evtl. zu einer NoSQL-Datenbank zu raten wäre.

    Du siehst hier, es ist mit einigen Kopfständen verbunden, zu einer RDBMS-Lösung zu kommen (oder es gibt einen Weg, der mir grade nicht einfällt). Jedenfalls wäre hier wohl besser, die Antwortmöglichkeiten in einer anderen passenderen Struktur (verschachtelte Arrays, Objektgebilde) anzulegen und diese zu serialisieren. Ein RDBMS bringt dir hier wohl keinen Vorteil, weil du in den Antworten sicherlich nicht mit den Funktionen des DBMS suchen möchtest. Auf NoSQL umzusteigen muss auch nicht unbedingt sein, ein Serialized-LOB-Feld (also serialisierte Antworten-Gebilde) täte es im Prinzip auch.

    dedlfix.