undso: Datenbank Verständnisfrage beim beschreiben

Hi Forum,

eine Verständnisfrage.

Ich habe DB Tabelle User mit ca. 50 Spalten. (Username, Passwort, Geschlecht, Geburtsdatum, Rechte, Bild, Avatar, Fontfarbe, Schriftart, Profilangaben, MitgliedSeit, usw. usw.)

Beim registrieren sieht die Query (Insert Into) übel aus (Lang und unübersichtlich)

Ich würde einige Spalten deshalb mit einem Defaultwert (Standart) anlegen und beim registrieren nur 5-6 Spalten beschreiben.

Meine Frage nun. Manche Spalten sind "Not Null" und haben einen Standartwert drin. Sollte ich nun andere Spalten updaten oder einen neuen Datensatz anlegen, ohne diese Spalten mitupzudaten oder in der Query zu erwähnen, würde das kein Problem machen ne?

Eine zweite andere Frage.
Spalte Test typ varchar.
Muss ich in der Query die Spalte immer maskieren? 'mein Eintrag'\ Würde die Eintragung ohne Maskierung trotzdem stattfinden?

Bei einem INT kann man natürlich nicht maskieren, sonst findet keine Eintragung statt. Bei Date und Time müsste man wahrscheinlich auch maskieren.

Geht dann die ganze Query (INSERT INTO oder UPDATE) in die Hose wenn eine Maskierung nicht passt oder nur die jeweilige Spalte?

Hoffe, dass mir jemand stichworthaltig kurz helfen könnte.

Grüße

  1. Hallo
    schwer das alles zu beantworten.

    Zuerst:
    Mache dir mal Gedanken ob es wirklich Sinn macht eine Tabelle mit 50! Spalten.
    Stichwort: erste Normalform.
    Meistens ist es besser (auch später zur Pflege) man teil das in mehrere Tabellen auf.

    2. <<Muss ich in der Query die Spalte immer maskieren? 'mein Eintrag'>>
    Du musst deine Einträge immer mit '' maskieren, Denke bitte auch an das Thema Sicherheit und validiere deine Daten.
    Stichwort: mysql_real_escape_string

    Wenn nur eine Spalte bzw. ein Eintrag deines Inserts falsch ist wird der ganze Befehl nicht ausgeführt.

    Gruss
    Hawk

    1. Hi, danke für die Antwort.

      Mache dir mal Gedanken ob es wirklich Sinn macht eine Tabelle mit 50! Spalten.
      Stichwort: erste Normalform.
      Meistens ist es besser (auch später zur Pflege) man teil das in mehrere Tabellen auf.

      ja da ahst du recht. Ich teile die 50 Felder dann gleich jetzt auf, bevor ich das naher mache und somit Mehrarbeit habe. In der Tabelle "User" belasse ich dann nur die gängingsten Sachen, und die die ich am meißten abfrage: ID, NAME, PASSWORT, GB-DATUM, WOHNORT, GESCHLECHT und ONLINESTATUS

      1. <<Muss ich in der Query die Spalte immer maskieren? 'mein Eintrag'>>
        Du musst deine Einträge immer mit '' maskieren, Denke bitte auch an das Thema Sicherheit und validiere deine Daten.
        Stichwort: mysql_real_escape_string

      Ich habe gedacht, dass man Spalten mit dem Typ "INT" nicht maskiert, bzw. dachte, dass es ein Fehler gibt, wenn man maskiert. (Wie bei String)
      Mal schauen, wie ich das "mysql_real_escape_string" in JSP einsetze.

      Wenn nur eine Spalte bzw. ein Eintrag deines Inserts falsch ist wird der ganze Befehl nicht ausgeführt.

      Aja, oki geht klar.

      Viele Grüße

  2. echo $begrüßung;

    Ich habe DB Tabelle User mit ca. 50 Spalten. (Username, Passwort, Geschlecht, Geburtsdatum, Rechte, Bild, Avatar, Fontfarbe, Schriftart, Profilangaben, MitgliedSeit, usw. usw.)
    Beim registrieren sieht die Query (Insert Into) übel aus (Lang und unübersichtlich)

    Wenn das Programm erst einmal steht bekommt es kein Mensch mehr mit, was hinter den Kulissen läuft.

    Meine Frage nun. Manche Spalten sind "Not Null" und haben einen Standartwert drin. Sollte ich nun andere Spalten updaten oder einen neuen Datensatz anlegen, ohne diese Spalten mitupzudaten oder in der Query zu erwähnen, würde das kein Problem machen ne?

    (Standard mit d am Ende.) Einzelne Spalten upzudaten ist überhaupt kein Problem.

    Spalte Test typ varchar.
    Muss ich in der Query die Spalte immer maskieren? 'mein Eintrag'\

    Generell gilt: Jeder Wert, der in einen bestimmten Kontext gebracht werden soll, muss die Gegebenheiten dieses Kontexts beachten und entsprechend behandelt werden.
    Du hast hier ein SQL-Statement. Das hat die Eigenart, Anweisungsteile und Daten zu einem einzigen Text zusammenzumischen. Damit die Daten von den Anweisungen unterschieden werdne können, muss man sie besonders kennzeichnen. Hier erfolgt das durch Quotierung, also Einrahmen in " oder '. Wenn nun innerhalb des Wertes ein ' oder " auftaucht, wird das als Ende des Wertes gedeutet, was ja aber nicht sein soll. Deshalb muss man diese Zeichen mit besonderer Bedeutung maskieren. Man stellt ihnen in dem Fall ein \ davor. Damit ist auch der \ zu einem Sonderzeichen geworden, das ebenfalls beachtet werden muss. Es gibt noch ein paar weitere Zeichen. Alle zu maskierende Zeichen werden von mysql_real_escape_string() beachtet. (Ich gehe mal davon aus, dass du MySQL verwendest.) Diese Funktion gibt es mit gleichem Namen unter PHP. Und auch andere Systeme bieten solch eine Funktion an.

    Würde die Eintragung ohne Maskierung trotzdem stattfinden?

    Nein, das ergibt im günstigsten Fall einen Syntaxfehler, im ungünstigsten eine SQL-Injection.

    Bei einem INT kann man natürlich nicht maskieren, sonst findet keine Eintragung statt.

    Doch, man kann. MySQL ist es egal, ob es Zahlenwerte als String gekennzeichnet oder ohne Quotierung bekommt. Da der SQL-String immer Text ist, muss in jedem Fall eine Konvertierung in eine Zahl erfolgen, bevor der Wert gespeichert werden kann.

    Bei Date und Time müsste man wahrscheinlich auch maskieren.

    Ja.

    Geht dann die ganze Query (INSERT INTO oder UPDATE) in die Hose wenn eine Maskierung nicht passt oder nur die jeweilige Spalte?

    Bei einem Syntaxfehler wird das SQL-Statement nicht ausgeführt. Bei einer SQL-Injection geht noch mehr in die Hose als dir lieb ist.

    Setz dir doch am besten ein Testsystem auf. Daran kannst du solche Problemfälle nachstellen, ohne Angst zu haben, etwas kaputt zu machen, siehst wie sich das System verhält und lernst damit umzugehen.

    echo "$verabschiedung $name";

    1. hi dedlfix,

      (Standard mit d am Ende.)

      Sorry ;)

      Generell gilt: Jeder Wert, der in einen bestimmten Kontext gebracht werden soll, muss die Gegebenheiten dieses Kontexts beachten und entsprechend behandelt werden.
      Du hast hier ein SQL-Statement. Das hat die Eigenart, Anweisungsteile und Daten zu einem einzigen Text zusammenzumischen. Damit die Daten von den Anweisungen unterschieden werdne können, muss man sie besonders kennzeichnen. Hier erfolgt das durch Quotierung, also Einrahmen in " oder '. Wenn nun innerhalb des Wertes ein ' oder " auftaucht, wird das als Ende des Wertes gedeutet, was ja aber nicht sein soll. Deshalb muss man diese Zeichen mit besonderer Bedeutung maskieren. Man stellt ihnen in dem Fall ein \ davor. Damit ist auch der \ zu einem Sonderzeichen geworden, das ebenfalls beachtet werden muss. Es gibt noch ein paar weitere Zeichen. Alle zu maskierende Zeichen werden von mysql_real_escape_string() beachtet. (Ich gehe mal davon aus, dass du MySQL verwendest.) Diese Funktion gibt es mit gleichem Namen unter PHP. Und auch andere Systeme bieten solch eine Funktion an.

      mysql.real_escape? Da ich JSP verwende, wäre dann mein Begriff anstatt real_escape dann wahrscheinlich "PreparedStatement-Objekt".

      Bei einem INT kann man natürlich nicht maskieren, sonst findet keine Eintragung statt.

      Doch, man kann. MySQL ist es egal, ob es Zahlenwerte als String gekennzeichnet oder ohne Quotierung bekommt. Da der SQL-String immer Text ist, muss in jedem Fall eine Konvertierung in eine Zahl erfolgen, bevor der Wert gespeichert werden kann.

      Das muss ich mal testen. Irgendwie hatte ich im hinterkopf, dass ich keine Zahlen in ein INT-Feld speichert konnte, wenn es maskiert war. Aber, könnte sein, dass ich mir irre. Werde ich gleich mal testen.

      Bei einem Syntaxfehler wird das SQL-Statement nicht ausgeführt. Bei einer SQL-Injection geht noch mehr in die Hose als dir lieb ist.

      SQL-Injection's sind wohl sehr Übel. Muss da sehr aufpassen ;)

      Setz dir doch am besten ein Testsystem auf. Daran kannst du solche Problemfälle nachstellen, ohne Angst zu haben, etwas kaputt zu machen, siehst wie sich das System verhält und lernst damit umzugehen.

      Teste gerade eh alles Lokal auf meiner Festplatte, bevor ich alles aufspiele.

      Eine andere Frage hätte ich noch, da ich das nicht so ganz verstanden habe.
      Ich belege einige Spalten mit einem Standardwert. Beim registrieren spreche ich diese Felde dann nicht noch extra an.

      Ein Kollege hat nun gemeint, dass man Felder mit dem "mediumtext" egal ob Null oder NotNull nie Null sein darf. Vorbelegen möchte ich das Feld mit meinem Standardwert nicht, da es leer sein sollte.

      Stimmt das nun, dass ich bei einem Insert Into auch die Spalten mit dem Typ "mediumtext" befüllen oder ansprechen muss- Bsp ''?

      Was ich auch nicht so checke. Den Unterschied zwischen, NULL und eine leere Spalte? Könnte man das in einem kurzen Satz für mich etwas verdeutlichen?

      Not Null = Nein. Das Feld darf nicht NULL sein.
      Null = Ja. Das Feld darf NULL sein.

      Der Unterschied zwischen NULL und leerem Feld. Wenn ich die Spalte "Name" mit leerem Inhalt hole und in eine Variable zuweise, dann ist die Variable einfach leer. String Name="";
      Wenn man ein Feld holt mit dem Inhalt "NULL". Dann kommt einfach nichts zurück, weil nichts da ist? Habe ich das so richtig verstanden?

      Bsp. Wenn ich mehrere Felder hole und in ein Aaray speichere. Sobald im Datensatz ein paar Felder leer sind, also Not Null, habe ich leere Arrayfelder. Sobald ein Feld mit NULL belegt ist, habe ich ein Arrayfeld weniger, da ich es nicht deklariert habe?
      Ja, eventuell habe ich es verstanden, wenn mir dies jemand bestätigen kann, bzw. falls man meinen Gedankensgang nachvollziehen kann ;)

      Grüße

      1. echo $begrüßung;

        mysql.real_escape? Da ich JSP verwende, wäre dann mein Begriff anstatt real_escape dann wahrscheinlich "PreparedStatement-Objekt".

        Prepared Statements sind nochmal eine Ecke besser. Hier notiert man das SQL-Statement mit Platzhaltern anstelle der Werte. Die Werte übergibt man beim Execute oder davor. Um die gefahrlose Übertragung zur Datenbank kümmert sich der Prepared-Statement-Mechanismus. Für derart übergebene Werte benötigt man weder Quotierung noch Maskierung.

        Irgendwie hatte ich im hinterkopf, dass ich keine Zahlen in ein INT-Feld speichert konnte, wenn es maskiert war. Aber, könnte sein, dass ich mir irre. Werde ich gleich mal testen.

        Andere Datenbanksysteme halten es da möglicherweise strenger.

        Maskiert ist übrigens was anderes als quotiert. Quotieren ist das Einrahmen in Anführungszeichen (Quotes). Maskieren ist das Entsonderzeichnen der Sonderzeichen innerhalb eines quotierten Wertes. Maskieren wird auch als Escapen bezeichnet.

        Eine andere Frage hätte ich noch, da ich das nicht so ganz verstanden habe.
        Ich belege einige Spalten mit einem Standardwert. Beim registrieren spreche ich diese Felde dann nicht noch extra an.

        Welche Felder du ansprichst ist ja abhängig von deiner Anwendungslogik.

        Ein Kollege hat nun gemeint, dass man Felder mit dem "mediumtext" egal ob Null oder NotNull nie Null sein darf. Vorbelegen möchte ich das Feld mit meinem Standardwert nicht, da es leer sein sollte.

        Welche Begründung führte er dazu an?

        Stimmt das nun, dass ich bei einem Insert Into auch die Spalten mit dem Typ "mediumtext" befüllen oder ansprechen muss- Bsp ''?

        Von diesem Zwang ist mir nichts bekannt.

        Was ich auch nicht so checke. Den Unterschied zwischen, NULL und eine leere Spalte? Könnte man das in einem kurzen Satz für mich etwas verdeutlichen?

        Not Null = Nein. Das Feld darf nicht NULL sein.
        Null = Ja. Das Feld darf NULL sein.

        Wenn deine Temperaturmessung ausfällt, welchen Wert schreibst du dann in die Datenbank? 0 wäre falsch, das verfälscht beispielsweise die Mittelwertbildung. Die obere oder untere Intergergrenze hat das gleiche Problem. NULL-Werte hingegen werden bei Aggregatfunktionen (COUNT(spalte), SUM(spalte), usw.) unberücksichtigt gelassen.

        Der Unterschied zwischen NULL und leerem Feld. Wenn ich die Spalte "Name" mit leerem Inhalt hole und in eine Variable zuweise, dann ist die Variable einfach leer. String Name="";
        Wenn man ein Feld holt mit dem Inhalt "NULL". Dann kommt einfach nichts zurück, weil nichts da ist? Habe ich das so richtig verstanden?

        Es kommt ein Datenbank-NULL zurück, das je nach Umgebung in einen adäquaten Wert umgewandelt wird. Z.B. Python-None, PHP-null.

        Bsp. Wenn ich mehrere Felder hole und in ein Aaray speichere. Sobald im Datensatz ein paar Felder leer sind, also Not Null, habe ich leere Arrayfelder. Sobald ein Feld mit NULL belegt ist, habe ich ein Arrayfeld weniger, da ich es nicht deklariert habe?

        Das kommt drauf an. Unter PHP kann ein Array ja beliebige Werte, also auch null-Werte, aufnehmen. Pythons Listen lassen sich auch mit unterschiedlichen Werten (also auch None-Werte) füttern. Für typsichere Sprachen muss man sich vielleicht was anderes einfallen lassen, aber meist geht da auch zur Unterscheidung entweder ein Objekt vom Typ des Arrays oder ein Null-Wert.

        echo "$verabschiedung $name";