Was bringen relationale Datenbanken, wenn für jede Spalte ein vordefinierter Datentyp festgelegt wird?

44

Ich arbeite gerade mit einer SQL-Datenbank und das hat mich immer neugierig gemacht, aber die Google-Suche taucht nicht viel auf: Warum die strengen Datentypen?

Ich verstehe, warum Sie ein paar verschiedene Datentypen haben, zum Beispiel wie wichtig es ist, zwischen Binär- und Nur-Text-Daten zu unterscheiden . Anstatt die Einsen und Nullen von Binärdaten als Klartext zu speichern, ist es meines Wissens effizienter, die Binärdaten als eigenes Format zu speichern.

Was ich aber nicht verstehe, ist der Vorteil, so viele verschiedene Datentypen zu haben:

  • Warum mediumtext, longtextund text?
  • Warum decimal, floatund int?
  • usw.

Was ist der Vorteil, wenn Sie der Datenbank mitteilen, dass die Einträge in dieser Spalte nur 256 Byte Klartext enthalten. oder "Diese Spalte kann Texteinträge von bis zu 16.777.215 Byte enthalten"?

Ist es ein Leistungsvorteil? Wenn ja, warum hilft es der Leistung, die Größe des Eintrags vor der Hand zu kennen? Oder eher etwas ganz anderes?

John Doe
quelle
2
Ich dachte, dass diese Frage hier bereits existieren sollte, aber ich habe die Site durchsucht und nichts Nützliches gefunden.
John Doe
6
Was würden Sie erwarten , wenn Sie keine eindeutigen decimal, floatund intTypen hätten 1 / 3? Was ist 1.0 / 3.0? Können Sie sicher sein , dass , wenn Sie teilen columnAmit , columnBdass werden Sie die Ergebnisse , die Sie erwarten?
Andrew sagt Reinstate Monica
2
@Johndoe Ich glaube nicht, dass es jemals notwendig sein würde, aber es könnte sehr praktisch sein. Angenommen, Sie möchten die Einschränkung durchsetzen, dass der Lagerbestand eines Geschäfts nicht unter 5% des monatlich erwarteten Umsatzes liegen darf. Oder Sie möchten sicherstellen, dass das Gesamtbudget jeder Abteilung nicht mehr als 20% des Gesamtbudgets beträgt. Es kann auch in berechneten Spalten vorkommen, die Sie in mehreren Anwendungen mit derselben Datenbank auf dieselbe Weise berechnen möchten.
Andrew sagt Reinstate Monica
2
Beachten Sie, dass SQLite keinen vordefinierten Typ pro Spalte festlegt: "SQLite ist" typenlos ". Dies bedeutet, dass Sie jede Art von Daten in jeder Spalte einer Tabelle speichern können, unabhängig vom deklarierten Datentyp dieser Spalte. "
Prime

Antworten:

50

SQL ist eine statisch typisierte Sprache. Dies bedeutet, dass Sie wissen müssen, welchen Typ eine Variable (oder in diesem Fall ein Feld) hat, bevor Sie sie verwenden können. Dies ist das Gegenteil von dynamisch getippten Sprachen, wo dies nicht unbedingt der Fall ist.

SQL dient im Kern dazu, Daten ( DDL ) und Zugriffsdaten ( DML ) in einer relationalen Datenbank- Engine zu definieren. Statische Typisierung bietet diesem Systemtyp mehrere Vorteile gegenüber dynamischer Typisierung.

  • Indizes , die für den schnellen Zugriff auf bestimmte Datensätze verwendet werden, funktionieren sehr gut, wenn die Größe festgelegt ist. Stellen Sie sich eine Abfrage vor, die einen Index verwendet, möglicherweise mit mehreren Feldern: Wenn die Datentypen und -größen im Voraus bekannt sind, kann ich mein Prädikat (WHERE-Klausel oder JOIN-Kriterien) sehr schnell mit den Werten im Index vergleichen und die gewünschten Datensätze schneller finden .

  • Betrachten Sie zwei ganzzahlige Werte. In einem dynamischen Typsystem können sie eine variable Größe haben (denken Sie an Java BigIntegeroder Pythons integrierte Ganzzahlen mit willkürlicher Genauigkeit). Wenn ich die ganzen Zahlen vergleichen möchte, muss ich zuerst ihre Bitlänge kennen. Dies ist ein Aspekt des Ganzzahlvergleichs, der von modernen Sprachen weitgehend verborgen wird, auf CPU-Ebene jedoch sehr real ist. Wenn die Größen festgelegt und im Voraus bekannt sind, wird ein ganzer Schritt aus dem Prozess entfernt. Auch hier sollen Datenbanken in der Lage sein, zig Millionen von Transaktionen so schnell wie möglich zu verarbeiten. Geschwindigkeit ist König.

  • SQL wurde bereits in den 1970er Jahren entwickelt. In den früheren Tagen des Mikrocomputing war der Speicher von höchster Wichtigkeit. Durch die Begrenzung der Daten konnten die Speicheranforderungen unter Kontrolle gehalten werden. Wenn eine Ganzzahl niemals über ein Byte hinauswächst, warum sollte mehr Speicher dafür reserviert werden? Das ist Platzverschwendung im Zeitalter des begrenzten Speichers. Selbst in der heutigen Zeit können diese zusätzlichen verschwendeten Bytes die Leistung des Cache einer CPU beeinträchtigen. Denken Sie daran, dass dies Datenbank-Engines sind, die möglicherweise Hunderte von Transaktionen pro Sekunde abwickeln, nicht nur Ihre kleine Entwicklungsumgebung.

  • In Anbetracht der begrenzten Speicherkapazität ist es hilfreich, einen einzelnen Datensatz auf einer einzelnen Seite im Speicher unterzubringen. Sobald Sie eine Seite durchgehen, treten mehr Seitenfehler und ein langsamerer Speicherzugriff auf. Neuere Engines haben Optimierungen, um dies weniger problematisch zu machen, aber es ist immer noch da. Indem Sie die Daten entsprechend dimensionieren, können Sie dieses Risiko verringern.

  • Um so mehr in der heutigen Zeit, ist SQL - Plug verwendet in anderen Sprachen über ORM oder ODBC oder eine andere Schicht. Einige dieser Sprachen haben Regeln, nach denen starke statische Typen erforderlich sind. Es ist am besten, sich an die strengeren Anforderungen zu halten, da dynamisch typisierte Sprachen mit statischen Typen einfacher umgehen können als umgekehrt.

  • SQL unterstützt die statische Typisierung, da Datenbank-Engines sie wie oben gezeigt für die Leistung benötigen.

Es ist interessant festzustellen, dass es Implementierungen von SQL gibt, die nicht stark typisiert sind. SQLite ist wahrscheinlich das beliebteste Beispiel für eine solche relationale Datenbank-Engine. Andererseits ist es für die Single-Thread-Verwendung auf einem einzelnen System konzipiert, sodass die Leistungsprobleme möglicherweise nicht so ausgeprägt sind wie beispielsweise bei einer Oracle-Unternehmensdatenbank, die Millionen von Anforderungen pro Minute verarbeitet.

gruszczy
quelle
SQLite verfügt über Datentypen, die zwischen numerischen und Textdaten unterscheiden, hat jedoch nur 5 "Klassen" für die Datenspeicherung: sqlite.org/datatype3.html
FrustratedWithFormsDesigner
1
@FrustratedWithFormsDesigner Ich weiß, aber es ist noch lange nicht so streng wie Engines wie SQL Server, Oracle oder PostgreSQL.
SQL ist nicht nur statisch typisiert - aufgrund der vorhandenen Prüfungseinschränkungen werden Verfeinerungstypen effektiv unterstützt.
Gardenhead
4
Obwohl dies im ersten Aufzählungszeichen impliziert ist, heißt es im IndexesWesentlichen: Ein Datentyp ermöglicht es der Datenbank-Engine, die Daten zu verstehen und Vergleiche anzustellen (größere / kleinere Zahlen, frühere / spätere Datumsangaben, vorher / nachher im Alphabet). und ermöglicht somit das Sortieren und Abfragen .
Basil Bourque
Also, wenn Größen wichtig sind ... und SQL im Voraus wissen muss ... was ist die genaue Größe einer "Zillion" -Transaktion?
WernerCD
24

Erstens: Klartext ist binär (es sind nicht einmal die UTF8- oder ASCII-Zeichen "0" und "1", sondern die tatsächlichen Ein / Aus-Bits)

Das heißt, einige der Gründe sind:

  • Geschäfts- / Designbeschränkungen: Das Zulassen der Nummer 7626355112 in der Spalte HEIGHT der Tabelle PERSON wäre falsch. Das Zulassen von "Howya" in der Spalte DATE einer INVOICE wäre falsch.
  • Weniger fehleranfälliger Code: Sie müssen keinen Code schreiben, um sicherzustellen, dass die aus einer Datumsspalte abgerufenen Daten wirklich ein Datum sind. Wenn Spaltentypen dynamisch wären, müssten Sie beim Lesen viele Typprüfungen durchführen.
  • Rechenleistung: Wenn eine Spalte vom Typ INTEGER ist und Sie SUM (), muss das RDBMS keine Gleitkomma-Arithmetik anwenden.
  • Speichereffizienz: Wenn angegeben wird, dass eine Spalte VARCHAR (10) ist, kann das RDBMS den Speicherplatz genauer zuordnen.
  • Referentielle Integrität und Einheitlichkeit: PK (oder FKs) einer Tabelle sollten keine Fließkommazahlen zulassen, da die Fließkommazahlen schwierig sind. Sie müssen sie daher in einem Typ ohne Fließkommazahlen deklarieren, z. B. Zeichen oder Ganzzahlen.
  • Es gibt RDBMSs mit dynamischen (nicht strengen) Spaltentypen (SQLite) . Es verwendet das Konzept der "Typaffinität", während Sie praktisch alles in jede Spalte einfügen können, ohne sich zu beschweren. Es gibt Kompromisse, die hier nicht diskutiert werden. Siehe diese Frage .
Tulains Córdova
quelle
8

Der zugrunde liegende Code, in den die Datenbank geschrieben ist, kann Datensätze mit fester Größe zuordnen und verwenden. Wenn bekannt ist, dass ein bestimmtes Feld 0 bis 256 Zeichen Text enthalten kann, kann ein 256-Byte-Block zum Speichern zugewiesen werden.

Dies macht die Dinge viel schneller, z. B. müssen Sie keinen zusätzlichen Speicher als Benutzertypen zuweisen, da ein bestimmtes Feld immer x Bytes in den Datensatz startet, wenn eine Suche oder Auswahl in diesem Feld weiß, dass immer x Bytes in jeden Datensatz eingecheckt werden.

Steve Barnes
quelle
Wenn nur alle Antworten so präzise und auf den Punkt gebracht werden könnten ...
Darren Ringer
6

Wenn den Spalten einer Datenbank definierte Typen zugewiesen werden, werden die Typen in der Regel so definiert, dass sie eine bestimmte Größe in Bit haben. Als Ergebnis:

1) Wenn das Datenbankmodul die Zeilen in einer Tabelle durchläuft, muss es keine ausgefallene Analyse durchführen, um zu bestimmen, wo jeder Datensatz endet. Es kann nur wissen, dass jede Zeile beispielsweise aus 32 Bytes besteht, um die zu erhalten Beim nächsten Datensatz ist es ausreichend, dem aktuellen Datensatzspeicherort 32 Byte hinzuzufügen.

2) Wenn Sie ein Feld in einer Zeile nachschlagen, ist es möglich, einen genauen Versatz für dieses Feld erneut zu ermitteln, ohne etwas zu analysieren. Daher sind Spaltensuchen eher eine einfache Rechenoperation als eine möglicherweise kostspielige Datenverarbeitungsoperation.

Benutzer wurde nicht gefunden
quelle
Felder mit fester Länge können die Verarbeitung aufgrund konsistenter Datensatzlängen und Feldversätze effizienter gestalten. Felder mit variabler Länge können diese Vorteile jedoch zunichte machen, da die Datensatzlänge und der Versatz von Feldern variieren können. In ähnlicher Weise führt die Komprimierung auf Datensatzebene zu Datensätzen mit variabler Länge, sodass die Position eines bestimmten Datensatzes nicht einfach berechnet werden kann.
Zenilogix
Dies ist wahr, und es war lange Zeit ein allgemeiner Rat, Felder mit variabler Länge aus genau diesem Grund zu vermeiden. Ich weiß nicht, wie die großen Spieler das machen, aber es scheint, als könnten Sie einige der Vorteile einer festen Länge wiedererlangen, wenn die Engine Felder mit variabler Breite in einer nicht für den Benutzer sichtbaren Tabelle oder einem Speicherblock speichert und die Die Darstellung dieser Felder in Primärtabellen ist ein Zeiger (mit fester Breite). In Anbetracht der Tatsache, dass Sie regelmäßig vollständige Scans von Feldern mit variabler Länge durchführen sollten, ist es möglicherweise sinnvoll, beim Leistungsverlust der Indirektion feste Breiten beizubehalten.
UserNotFound
3

Sie haben gefragt, warum DBMS statische Datentypen haben.

  1. Suchgeschwindigkeit. Der springende Punkt eines DBMS ist es, weit mehr Daten zu speichern, als Sie möglicherweise in ein Programm laden könnten. Denken Sie "alle Kreditkartenabrechnungen, die in den letzten zehn Jahren weltweit gemacht wurden". Um solche Daten effizient zu durchsuchen, sind Datentypen mit fester Länge hilfreich. Dies gilt insbesondere für strukturierte Daten wie Datumsstempel und Kontonummern. Wenn Sie im Voraus wissen, womit Sie es zu tun haben, ist es einfacher, sie in effiziente Indizes zu laden.

  2. Integrität und Einschränkungen. Es ist einfacher, Daten sauber zu halten, wenn sie feste Datentypen haben.

  3. Geschichte. RDBMS wurden gestartet, als Computer nur wenige Megabyte RAM hatten und Speicher im Terabyte-Bereich enorm teuer war. Wenn Sie ein Dutzend Bytes in jeder Zeile einer Tabelle speichern, können Sie unter diesen Umständen Tausende von Dollar und Stunden Zeit sparen.

  4. Der Fluch des Kundenstamms. RDBMSs sind heutzutage sehr komplexe, hochoptimierte Softwarepakete und werden seit Jahrzehnten zum Sammeln von Daten verwendet. Sie sind ausgereift. Sie arbeiten. Ein RDBMS-Absturz, der zu großen Datenverlusten führt, ist heutzutage äußerst selten. Der Wechsel zu einem flexibleren System für die Dateneingabe ist für die meisten Unternehmen weder die Kosten noch das Risiko wert.

Analogie: Es mag offensichtlich sein, dass städtische U-Bahn-Systeme auf einer schmaleren Spurweite besser (leiser, schneller, energieeffizienter) funktionieren würden. Aber wie werden Sie alle Schienen im New Yorker U-Bahn-System ändern, um diese Verbesserungen zu realisieren? Sie sind nicht, also optimieren Sie, was Sie haben.

O. Jones
quelle
3

Im Allgemeinen das genauer sagen Sie die Datenbank über , was Sie Speichern, desto mehr versuchen können verschiedene Performance - Metriken zu , dass Daten, wie zum Beispiel , wie viel Platz es zuzuteilen auf Disc oder wie viel Speicher zuweisen , wenn das Abrufen Bezug zu optimieren .

Warum Medientext, Langtext und Text?

Ich bin mir nicht sicher, welche Datenbank Sie verwenden, also muss ich raten: Ich würde raten, dass zwei dieser Datentypen Obergrenzen haben, einer von ihnen nicht. Durch die Verwendung von Datentypen für Text mit Obergrenzen wird der Datenbank mitgeteilt, wie viel Speicherplatz für jeden Datensatz benötigt wird. Es ist auch möglich, dass einige Datenbanken unterschiedliche Möglichkeiten zum Speichern von großem (möglicherweise unbegrenztem) Text im Vergleich zu kleinem Text mit fester Länge haben (dies kann je nach Datenbank variieren. Informationen zu Ihrem Text finden Sie in Ihrem Handbuch).

Warum dezimal, float und int?

Unterschiedliche Präzisionsgrade erfordern unterschiedliche Mengen an Speicherplatz, und nicht jede Verwendung erfordert ein Höchstmaß an Präzision. Beispiel: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF50950

Oracle hat eine ganze Reihe verschiedener numerischer Typen mit unterschiedlichen Speicheranforderungen und unterschiedlichen Fähigkeiten in Bezug auf Genauigkeit und Größe der darstellbaren Anzahl.

FrustratedWithFormsDesigner
quelle
2

Bis zu einem gewissen Grad ist es historisch.

Es war einmal, dass Tabellendaten in Dateien gespeichert wurden, die aus Datensätzen fester Länge bestanden, die wiederum aus vordefinierten Feldern bestanden, sodass ein bestimmtes Feld in jedem Datensatz immer vom gleichen Typ und an der gleichen Stelle war. Dies machte die Verarbeitung effizient und begrenzte die Komplexität der Codierung.

Fügen Sie einer solchen Datei einige Indizes hinzu, und Sie haben die Anfänge einer relationalen Datenbank.

Im Zuge der Entwicklung relationaler Datenbanken wurden mehr Datentypen und Speicheroptionen eingeführt, darunter Text variabler Länge oder Binärfelder. Dies führte jedoch Datensätze mit variabler Länge ein und verhinderte, dass Datensätze über eine Berechnung oder Felder über einen festen Versatz konsistent lokalisiert werden konnten. Egal, Maschinen sind heute viel leistungsfähiger als damals.

Manchmal ist es hilfreich, eine bestimmte Größe für ein Feld festzulegen, um eine gewisse Geschäftslogik durchzusetzen - beispielsweise 10 Ziffern für eine nordamerikanische Telefonnummer. Die meiste Zeit ist es nur ein bisschen Computererbe.

Zenilogix
quelle
1

Wenn eine Datenbank Datensätze mit fester Größe verwendet, passt jeder Datensatz in der Datenbank weiterhin an denselben Speicherort, auch wenn sein Inhalt geändert wird. Wenn dagegen eine Datenbank versucht, Datensätze mit genau der für ihre Felder erforderlichen Speicherkapazität zu speichern, kann die Änderung des Namens von Emma Smith in Emma Johnson dazu führen, dass der Datensatz zu groß ist, um an den aktuellen Speicherort zu passen. Wenn der Datensatz an einen Ort mit genügend Speicherplatz verschoben wird, muss jeder Index, der den aktuellen Speicherort erfasst, aktualisiert werden, um den neuen Speicherort wiederzugeben.

Es gibt verschiedene Möglichkeiten, die mit solchen Updates verbundenen Kosten zu senken. Wenn das System beispielsweise eine Liste mit Datensatznummern und Datenpositionen verwaltet, muss diese Liste nur aktualisiert werden, wenn ein Datensatz verschoben wird. Leider sind solche Ansätze immer noch mit erheblichen Kosten verbunden (z. B. würde das Aufrechterhalten einer Zuordnung zwischen Datensatznummern und Speicherorten erfordern, dass das Abrufen von Datensätzen einen zusätzlichen Schritt zum Abrufen der Daten erfordert, die einer bestimmten Datensatznummer zugeordnet sind). Die Verwendung von Datensätzen mit fester Größe mag ineffizient erscheinen, erleichtert jedoch die Arbeit erheblich.

Superkatze
quelle
1

Für vieles, was Sie als Webentwickler tun, müssen Sie nicht verstehen, was "unter der Haube" passiert. Es gibt jedoch Zeiten, in denen es hilft.

Was ist der Vorteil, wenn Sie der Datenbank mitteilen, dass die Einträge in dieser Spalte nur 256 Byte Klartext enthalten. oder "Diese Spalte kann Texteinträge von bis zu 16.777.215 Byte enthalten"?

Wie Sie vermuten, liegt der Grund in der Effizienz. Die Abstraktionen lecken . Eine Abfrage wie SELECT author FROM bookskann sehr schnell ausgeführt werden, wenn die Größe aller Felder in der Tabelle bekannt ist.

Wie Joel sagt,

Wie implementiert eine relationale Datenbank SELECT author FROM books? In einer relationalen Datenbank hat jede Zeile in einer Tabelle (z. B. die Buchtabelle) genau dieselbe Länge in Bytes, und jedes Feld hat immer einen festen Abstand zum Zeilenanfang. Wenn also beispielsweise jeder Datensatz in der Buchtabelle 100 Bytes lang ist und das Autorenfeld den Versatz 23 aufweist, werden Autoren in den Bytes 23, 123, 223, 323 usw. gespeichert. In welchen Code soll verschoben werden? der nächste Datensatz im Ergebnis dieser Abfrage? Grundsätzlich ist es das:

pointer += 100;

Eine CPU-Anweisung. Faaaaaaaaaast.

Die meiste Zeit arbeiten Sie weit genug weg von den eigentümlichen Grundlagen, die Sie nicht zu beachten brauchen. Als-PHP - basierten Web - Entwickler, tun Sie kümmern , wie viele CPU - Instruktionen Code verwendet? Meistens nicht wirklich. Aber manchmal ist es aus zwei Gründen nützlich zu wissen: Es kann Entscheidungen erklären, die von Ihren Bibliotheken getroffen wurden. und manchmal müssen Sie sich um die Geschwindigkeit in Ihrem eigenen Code kümmern.

TRiG
quelle