SQL-Datenbanken und Datentypen

Tockra

Lt. Commander
Registriert
Dez. 2008
Beiträge
1.058
Guten Morgen Leute,

ich wollte mal eine kleine Wissenslücke schließen. Ich habe zwar Google bemüht, aber gerade bei einen so alten Thema wie Datenbanken weiß ich dann nie ob Seite XY nun über einen Status Quo von 2006 oder 2019 redet (unabhängig vom Zeitpunkt der Erstellung des Artikels).

Ich hatte bisher einige Male Kontakt mit Datenbanken (MySQL, Oracle Database, PostgreSQL, SQLLite), habe mich aber nie wirklich tief damit beschäftigt. Woran ich mich allerdings noch richtig gut erinnern kann sind die Datentypen der Datenbank. Es gab öfter doppelte Datentypen und mir hat sich nie erschlossen wann welcher Datentyp angebracht war und welche Einschränkung die "Länge" nun hatte (Zeichenlänge, Maximalwert, Bytes, Bits ?) .

Deswegen wollte ich mal nach den Äquivalenten von folgenden Datentypen fragen:

- integer (mit unterschiedlich vielen Bits)
  • float (mit unterschiedlich vielen Bits)
  • boolean
  • Strings mit beliebiger Länge (z.B. wenn Forenbeiträge oder ähnliches gespeichert werden sollen)
  • Strings mit bekannter Maximallänge
  • Characters
  • Listen


Gibt es überhaupt einen definierten Standart für Datentypen oder hat jede SQL-Datenbank ihre eigenen ?

Es wäre nett, wenn mir jemand meine Fragen beantworten würde und/oder jemand einen Link zuschicken würde.

Viele Grüße
Tim
 
Viele Datenbanken folgen einem Standard wie SQL92-SQL/MDA:2019. Dort sind dann auch die entsprechenden Datentypen hinterlegt. Wie die Datentypen dann verwendet und definiert werden, hängt von der jeweiligen Datenbank ab. Verwendet man beispielsweise varchar bei Oracle, sind das maximal 4000 Zeichen. Sobald aber UTF-8, und UTF-16 als Zeichensatz für die Datenbank verwendet werden, reduziert sich varchar auf 2000 Zeichen, und bei UTF-32 auf 1000.
 
  • Gefällt mir
Reaktionen: PHuV
Da muss man schon auf das jeweilige Ziel-RDBMS schauen und dann das ganze konkretisieren. Ich habe noch keine zwei RDBMS nebeneinander gesehen, die absolut identische Datentypen besaßen. Es gibt da sicherlich immer irgendwie gewisse Schnittmengen aber absolut identisch sind die wenigsten Datentypen zwischen den RDBMS.
 
ayngush schrieb:
Ich habe noch keine zwei RDBMS nebeneinander gesehen, die absolut identische Datentypen besaßen.
Evtl. MySQL und MariaDB direkt nach dem ersten Fork :D Aber sonst fällt mir da auch nichts ein.
 
Zunächst kann man bei einer Google Suche sagen wir "alt" das Ergebnis sein soll. Das ist sinnvoll da man inzwischen in der Tag mit alten Mist zugemüllt wird (gerade in der vergänglichen IT).
Nach Ausführung der Suche oben links "Tools" anklicken und in der erscheinenden Zeile statt "beliebige Zeit" einen passenden Zeitraum wählen (z. B. "letztes Jahr").

Alt ist das Thema - insbesondere RDBMS - auch überhaupt nicht.
Zwar wird ständig NoSQL/BigData geschrieen, aber ehrlich gesagt haben moderne SQL-Datenbanksysteme auch viele (nicht alle) Funktionen integriert.
Im Falle von PostgreSQL ist dies z. B. der HSTORE-Typ, der schon lange vor dem Begriff "NoSQL" die Möglichkeit zur Speicherung von Key=Value Paaren vorhanden war (HSTORE ist auch die Grundlage der JSON und JSONB-Typen die PostgreSQL seit 9.x besitzt und innerhalb der 9.x-er Versionen weiter ausgebaut wurde).

Am Ende gehe ich noch mal auf Detail zu NoSQL/BigData und meine Erfahrungen damit ein...im Zweifel überspringen, da es doch vom eigentlichen Thema abweicht.

Wie schon erwähnt gibt es den SQL-Standard und die verschiedenen Anbieter halten sich mal mehr oder weniger daran und unterstützen in der Regel auch nur eine Teilmenge (insbesondere bei neueren SQL-Standards).

Gefühlt ist PostgreSQL immer relativ nahe dran und hat als kostenloses Datenbank Managementsystem einen unerreichten Funktionsumfang (Replication, JSONB/JSON (JSONB erlaubt die Indexerstellung auf bestimmte Keys), XML, Volltextsuche, PostGIS als Geo-Erweiterung (wird von OpenStreetmap verwendet), Array, umfangreiche RegEx Funktionen, etc.).


Datentypen wurden ja oben schon verlinkt...aber hier dennoch noch einmal der Link auf PostgreSQL...
https://www.postgresql.org/docs/current/datatype.html

EDIT: Wegen der Maximallängen von Strings. Die folgende Variante solle man nicht nutzen (hat hier ein Kollege leider auch gerade gemacht):
CREATE TABLE xxx (
mytext VARCHAR(10) NOT NULL
);

Statt dessen sollte man diese Konstrukt verwenden:
CREATE TABLE mytable (
mytext VARCHAR NOT NULL,
CONSTRAINT mytable_mytext_max_length_check CHECK (LENGTH(mytext) <= 10)
);

Begründung:
Beide Varianten erzeugen das gleiche Ergebnis aber wenn man mal die Länge anpassen muss, dann ist nur der Check Constraint zu ändern und nicht die Tabellendefinition selbst.
Hat man eine richtig "große" Tabelle, kann das Sekunden bis Minuten dauern in denen die Datenbank blockiert ist (--> LOCK), weil der komplette Inhalt der Tabelle umkopiert werden muss (es mag DBs geben, bei denen das nicht das Fall ist).
Im Falle des Check Constraints muss nur der Constraint geupdated werden, was im Bruchteil einer Sekunde erledigt ist.
EDIT-END

Außerdem kann man bei manchen Datenbanken eigene Typen erstellen, was überaus hilfreich sein kann.
Ich habe bei meinem früheren Arbeitgeber einen Typ für "Öffnungszeiten" bzw. Spechzeiten von Arztpraxen erstellt.
Warum mag man sich vielleicht fragen...die Liste der Varianten verdeutlicht es glaube ich:
  1. Mo Vormittags von X bis Y
  2. Mo Nachmittag von X bis Y
  3. Di Vormittag von X bis Y
  4. [...]
Dazu pro Tag noch die Option "hat Abendsprechstunde" (nach Definition Öffnungszeiten ab 18 Uhr) Boolean Feld Ja/Nein.

Sprich man hätte 5 Spalten pro Tag (also Mo bis Fr + ggf. Sa möglicherweise auch So)
5x7 = max 35 Spalten

Mit PostgreSQL Create Type wurde daraus "eine Spalte" vom Typ "sprechzeiten", und mittels Trigger wurde das Flag Abendsprechstunde automatisch auf TRUE gesetzt wenn ein Wert ab 18:00 (Nachmittags bis) hinterlegt ist, sonst FALSE.
Alle Felder werden mit einem RegEx auf korrekten Inhalt überprüft dazu noch extra Checks und automatische Feldinhalte Ersetzung so das die "Bis Uhrzeit"nicht vor der "von Uhrzeit" liegt (18:00 < 12:00 = FALSE).
Intern verwendet PostgreSQL ein "Record" Konstrukt.
Mittels "sprechzeiten.mo_von_uhrzeit" greift man auf den Inhalt des Feldes Montag Vormittag ab X Uhr zu.

Mit dem XML-Typen in PostgreSQL habe ich gerade mit ein paar Zeilen SQL den Inhalt der ISO-Currency Codes (XML) in ein vernünftiges Tabellenformat importiert (1. CREATE TEMPORARY TABLE temp_currency....ON COMMIT DROP; 2. COPY FROM xxx --> temp_currency; 3. INSERT INTO iso4217_currency_detail SELECT xxx_viele_xpath FROM temp_currency ). Statt dies in einem SQL-Skript zu machen, wie ich es nun initial vorgenommen habe, kann man auch eine Funktion verwenden, was den Vorteil hat, das man den Pfad zu XML-Datei beim Funktionsaufruf mitgeben kann und bis zu einer Änderung in der XML-Format einfach die Daten aktualisieren kann (es gibt zusätzlich eine Versionspalte und ein aktiv-Flag, so dass man dafür sorgen kann das immer nur die aktuellen Daten aktiv und vom Benutzer auswählbar sind).

NoSQL/BigData
Persönlich sehe ich NoSQL/BigData kritisch, da NoSQL meistens nur das Problem sich eine ordentliche Datenstruktur zu überlegen auf den Entwickler abwälzt und dieser in der Regel die "für den Augenblick" einfachste Lösung zu werden (im Zweifel alles in einen JSON String werfen und in einer Spalte ablegen).

Das Problem ist am Ende häufig das es keine ausreichende Validierung bei den Daten gibt und die Strukturen wieder umgeworfen werden (hätte man auch gleich ordentlich machen können...am Ende "günstiger"). Grundsätzlich sollte das Prinzip sowie lauten "Trust nobody" und validiere jedes Feld - auch Kombinationen (Beispiel Geokoordinaten lat/long; beide ungültig wenn nur ein Wert aus dem Range läuft).
Wer hat schon BigData und ab wann kann man das überhaupt so bezeichnen.
Hier ist NoSQL auch nicht unbedingt die Lösung, dann auch mit Relationalen Datenbanksystemen können wirklich große Datenmengen verwaltet werden.
PostgreSQL und auch andere RDBMS können problemlos mehrere Millionen oder Milliarden Datensätze speichern und durchsuchen (auch schnell). Das Stichwort lautet "Partitionierung" von Daten (z. B. Aufteilung nach Zeiträumen). Dann werden selbst sehr große Datenmengen handhabbar. Es gibt sicher Randfälle in denen man auch hier an Grenzen kommen kann aber das dürften Spezialfälle sein (z. B. Google Suche).
Ähnlich ist es übrigens mit der Volltextsuche. Solr wird gerne genommen, aber ist es überhaupt nötig? Es erhöht die Komplexität (noch ein System zu warten + noch ein System das ausfallen kann). Daten können erst durchsucht werden wenn die Indizierung durch ist, was durchaus dauern kann, während die Datenbank Volltextsuche vermutlich schon reicht und instant den Index aktualisiert.
Ich habe bei einem größeren Projekt bereits eine Umstellung von MySQL (Cluster; 5 MySQL Instanzen) + Solr auf eine einzige PostgreSQL Instanz mit Volltextsuche vorgenommen. Dazu wurden einige Prozesse, die sich in der Vergangenheit als "Fehlertor" erwiesen ausgemerzt (Geodaten) und die Datenverarbeitung ging ohne Solr X-fach schneller bzw. war sofort nutzbar, während man zuvor noch Stunden auf die Solr-Indizierung warten musste. Dazu wie gesagt noch die Einsparung eines MySQL Clusters.
Die Daten konnte per großem SQL-Skript ohne den zuvor nötigen Umwege über ein XML-Austauschformat (noch ein Fehlerteufel im alten System) direkt in das für das Portal nötige "abfrageoptimierte" Tabellenschema überführt werden.
Das System läuft immer noch, aber jetzt war tatsächlich mal ein Update des Servers nötig, da weitere Daten dazu gekommen sind und der alte Server so langsam an die Grenze kam. Zusammen mit den neuesten PostgreSQL Erweiterungen aus v10+ (parallele Queries) kann man mehrere Kerne besser ausnutzen kann. Sollte auch das nicht reichen, wird die Replizierung angeworfen und man verteilt lesende Queries auf den Slave (Standby-Server).
 
Zuletzt bearbeitet:
  • Gefällt mir
Reaktionen: PHuV
xmarsx schrieb:
Dazu pro Tag noch die Option "hat Abendsprechstunde" (nach Definition Öffnungszeiten ab 18 Uhr) Boolean Feld Ja/Nein.

Sprich man hätte 5 Spalten pro Tag (also Mo bis Fr + ggf. Sa möglicherweise auch So)
5x7 = max 35 Spalten
Warum nicht einfach eine Tabelle:
Tag, Beginn, Ende

Hätte deine Anforderung sehr einfach und flexibel abgedeckt: du kannst beliebig oft öffnen am Tag, statt zweimal; du kannst an beliebigrn Wochentagen geöffnet haben, etc.

Warum überhaupt das Boolean Field abspeichern? Solche abgeleiteten Daten gehören doch sowieso nicht in eine DB.
 
  • Gefällt mir
Reaktionen: Enurian
@xmarsx Das Stichwort lautet "polyglot". Man nutze für jeden Anwendungsfall die dafür passende Datenbank.

Daten Validierung ist so 'ne Sache. RDBMS bringen da auch nur die Basics mit. Ja, man könnte komplexe Validierung von Domain Objects in Form von riesigen SQL Statements machen - aber sowas ist mir bisher noch nicht über den Weg gelaufen, wäre ja auch extrem unübersichtlich. Also macht man den Kram eh in der Anwendungslogik. Und hier kann man dann auch gleich alles andere validieren. Dafür braucht's keine Datenbank, die das übernimmt.

Riesige Objekte in RDBMS können schnell mal dutzende Tables mit jeweils dutzenden Spalten bedeuten. Wenn ich auf diesen Daten allerdings weder suchen noch sortieren muss, dann schmeiß ich den Kram einfach in MongoDB oder Redis und gut ist.

Graphen im RDBMS gehen natürlich auch. Aber bei 1000 JOINs pro Query schau ich mich dann doch lieber bei Neo4j um. Vor allem sind die Querys für diese Datenstrukturen dort hundert mal übersichtlicher und einfacher.

Es gibt natürlich auch haufenweise gute Anwendungsfälle für ein RDBMS. Keine Frage.

Was ich eigentlich sagen wollte: Ohne Anwendungslogik geht's im Normalfall eh nicht. Und in der Anwendungslogik habe ich die volle Kontrolle über alles und muss an keiner Stelle auf ein Datenbanksystem vertrauen. Querys aus mehreren Datastores, Joins, Locking, Conditional Updates, etc. alles kein Problem.
Vor allem hat man heutzutage ja auch immer häufiger "externe Datenbanken" in Form von APIs in seiner Applikation. Und schon ist man gezwungenermaßen polyglot unterwegs. Da ist der Weg zu Microservices mit jeweils für die dort enthaltenen Datenstrukturen spezialisierte Datenbanken auch nicht mehr weit, denn im Endeffekt nutzt man diese Services auch nur noch via API.
 
1. Spalten sind lange Risse in festem Material
2. RDBMS unterscheiden sich von "Excel" durch das "R"
3. 3. Normalform

Edit:
4. Für die angesprochenen Microservices verwendet man in nahezu allen fällen ein OODBMS, da die Daten in 99,9% der Fälle ohnehin als key value pairs vorliegen.
 
ayngush schrieb:
1. Spalten sind lange Risse in festem Material
Das Wort - wie so viele andere - hat mehr als eine Bedeutung ;)

ayngush schrieb:
2. RDBMS unterscheiden sich von "Excel" durch das "R"
3. 3. Normalform
Und gerade das verursacht bei riesigen Objektbäumen haufenweise JOINs. Manchmal nützlich, manchmal unbrauchbar.

ayngush schrieb:
4. Für die angesprochenen Microservices verwendet man in nahezu allen fällen ein OODBMS, da die Daten in 99,9% der Fälle ohnehin als key value pairs vorliegen.
Da sind Redis oder auch MongoDB und zum Teil auch Elasticsearch mit entsprechender Data Mapper sehr praktisch. Je nach dem was man mit den Daten noch so alles anstellen will.
Aber ich hab auch des öfteren Services für spezielle Suchen. Da interessieren mich - je nach Anwendungsfall - die Values nach dem Ablegen nicht mehr, solang sie gesucht und gefunden werden können und mir als Ergebnis eine ID zurückgegeben wird.
Oder oben angesprochene Graphen: Im Extremfall ist das einfach nur ein riesiger Haufen IDs, weil das für die Aufgabe dieses Services vollkommen ausreicht. Und eine andere Datenbank enthält dann die eigentlichen Daten zu den IDs.
 
Zuletzt bearbeitet:
new Account() schrieb:
Warum nicht einfach eine Tabelle:
Tag, Beginn, Ende

Hätte deine Anforderung sehr einfach und flexibel abgedeckt: du kannst beliebig oft öffnen am Tag, statt zweimal; du kannst an beliebigrn Wochentagen geöffnet haben, etc.

Warum überhaupt das Boolean Field abspeichern? Solche abgeleiteten Daten gehören doch sowieso nicht in eine DB.

Mit etwas Verzug noch mal ein Update...
Das gesamte Konstrukt besteht aus einem Data Warehouse mit allen Daten über "Jahre" (es fließen auch von Dritten täglich Updates ins System) und daraus wird per SQL-Skript ein "abfrageoptimiertes" Schema mit den aktuellsten Daten erstellt und mittels Dump + Restore auf dem Portal-DB-Server eingespielt.

Grundsätzlich ist es natürlich möglich und auch sauber die Sprechzeiten gesondert in eine extra Tabelle zu packen (für das Data Warehouse), so einfach wie oben beschrieben aber eben nicht umsetzbar, da eine weitere "Reihenfolge" fehlt die man sich nur über Inhaltsprüfung bauen kann.
Es ging hier insbesondere auch um die Performance des Portals und die Suche. Jeder JOIN tut dann schon weh weil insbesondere auch nach Informationen aus den Sprechzeiten neben weiteren Details wie "PLZ-Gebiet/Umkreis", Fachgebiet, weiterer Zusatzleistungen, etc. gesucht werden kann.
In dem abfrageoptimierten Schema wurden Informationen aus vielen Tabellen über Konstrukte wie bei den Sprechzeiten oder auch Arrays in wenige Tabellen zusammengeführt.

Die Abendsprechstunden können ebenfalls in der Suche vom Nutzer selektiert werden und müssen daher auch gespeichert werden. Nicht jede Praxis bietet das regelmäßig für die arbeitende Bevölkerung an. Termine nach Absprache sind in der Regel gesondert möglich (das war übrigens ein weiteres Boolean Flag). ;)
 
Zurück
Oben