it-swarm.com.de

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

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 zum Beispiel ein paar verschiedene Datentypen haben würden wie wichtig es ist, zwischen Binär- und Klartextdaten zu unterscheiden . Anstatt die Einsen und Nullen von Binärdaten als Klartext zu speichern, verstehe ich jetzt, dass es effizienter ist, die Binärdaten als eigenes Format zu speichern.

Aber was ich nicht verstehe, ist, was der Vorteil ist, so viele verschiedene Datentypen zu haben:

  • Warum mediumtext, longtext und text?
  • Warum decimal, float und int?
  • usw.

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

Ist es ein Leistungsvorteil? Wenn ja, warum hilft es, die Größe des Eintrags vorab zu kennen, um die Leistung zu verbessern? Oder ist es eher etwas ganz anderes?

44
john doe

[~ # ~] 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 typisierten Sprachen, bei denen dies nicht unbedingt der Fall ist.

Im Kern ist SQL so konzipiert, dass es Daten definiert ( [~ # ~] ddl [~ # ~] ) und auf Daten zugreift ( [~ # ~] dml [~ # ~ ] ) in einer relationalen Datenbank Engine. Die statische Typisierung bietet für diese Art von System mehrere Vorteile gegenüber der dynamischen 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 Werten im Index vergleichen und die gewünschten Datensätze schneller finden .

  • Betrachten Sie zwei Ganzzahl Werte. In einem dynamischen Typsystem können sie von variabler Größe sein (think Java BigInteger oder Pythons integrierte Ganzzahlen mit beliebiger Genauigkeit). Wenn ich die Ganzzahlen vergleichen möchte, Ich muss zuerst ihre Bitlänge kennen. Dies ist ein Aspekt des Ganzzahlvergleichs, der von modernen Sprachen weitgehend verborgen wird, aber auf CPU-Ebene sehr real ist. Wenn die Größen festgelegt und im Voraus bekannt sind, wird ein ganzer Schritt entfernt Auch hier sollen Datenbanken in der Lage sein, zig Millionen Transaktionen so schnell wie möglich zu verarbeiten. Geschwindigkeit ist das A und O.

  • SQL wurde bereits in den 1970er Jahren entwickelt. In den früheren Tagen des Mikrocomputers war der Speicher sehr wichtig. Durch die Begrenzung der Daten konnten die Speicheranforderungen unter Kontrolle gehalten werden. Wenn eine Ganzzahl nie über ein Byte hinauswächst, warum mehr Speicherplatz dafür zuweisen? Das ist Platzverschwendung in Zeiten begrenzten Gedächtnisses. Selbst in der heutigen Zeit können diese zusätzlichen verschwendeten Bytes die Leistung des Cache einer CPU summieren und beeinträchtigen. Denken Sie daran, dass dies Datenbank-Engines sind, die möglicherweise Hunderte von Transaktionen pro Sekunde bedienen, nicht nur Ihre kleine Entwicklungsumgebung.

  • Im Sinne eines begrenzten Speichers ist es hilfreich, einen einzelnen Datensatz auf einer einzelnen Seite im Speicher unterbringen zu können. 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. Durch geeignete Größenanpassung der Daten können Sie dieses Risiko verringern.

  • In der heutigen Zeit wird SQL auch verwendet, um über [~ # ~] orm [~ # ~] oder [~ # ~] odbc [~ # ~ eine Verbindung zu anderen Sprachen herzustellen ] oder eine andere Ebene. Einige dieser Sprachen haben Regeln für das Erfordernis starker statischer Typen. Es ist am besten, die strengeren Anforderungen zu erfüllen, da dynamisch typisierte Sprachen mit statischen Typen einfacher umgehen können als umgekehrt.

  • SQL unterstützt die statische Typisierung, da Datenbankmodule diese 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 Verwendung mit einem Thread auf einem einzelnen System ausgelegt, so dass die Leistungsbedenken möglicherweise nicht so ausgeprägt sind wie z. Eine Oracle-Unternehmensdatenbank, die Millionen von Anfragen pro Minute bearbeitet.

50
user22815

Erstens: Klartext ist binär (es ist nicht einmal das UTF8 oder ASCII Zeichen "0" und "1", aber tatsächliche Ein/Aus-Bits)

Einige der Gründe sind jedoch:

  • Geschäfts-/Designeinschränkungen: Das Zulassen der Nummer 7626355112 in der Spalte HEIGHT der PERSON-Tabelle wäre falsch. Es wäre falsch, "Howya" in der DATE-Spalte einer REVOICE zuzulassen.
  • 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.
  • Recheneffizienz: Wenn eine Spalte vom Typ INTEGER ist und Sie SUM (), muss das RDBMS keine Gleitkomma-Arithmetik anwenden.
  • Speichereffizienz: Wenn Sie angeben, dass eine Spalte VARCHAR ist (10), kann das RDBMS den Speicherplatz genauer zuweisen.
  • Referenzielle Integrität und Einheitlichkeit: PK (oder FKs) einer Tabelle sollten keine Gleitkommazahlen zulassen, da die Gleitkomma-Gleichheit schwierig ist. Sie müssen sie daher deklarieren Ein Nicht-Float-Typ wie Zeichen oder Ganzzahlen.
  • Es gibt RDBMS mit dynamischen (nicht strengen) Spaltentypen (SQLite) . Es verwendet das Konzept der "Typaffinität" und ermöglicht es Ihnen dennoch, praktisch alles in jede Spalte einzufügen, ohne sich zu beschweren. Es gibt Kompromisse, die hier nicht diskutiert werden. Siehe diese Frage .
24

Es ist so, dass der zugrunde liegende Code, in den die Datenbank geschrieben ist, Datensätze mit fester Größe zuweisen und verwenden kann. Wenn er weiß, dass ein bestimmtes Feld 0 bis 256 Zeichen Text enthalten kann, kann er einen Block von 256 Bytes zum Speichern zuweisen.

Dies macht die Dinge viel schneller, z. Sie müssen keinen zusätzlichen Speicher zuweisen, während der Benutzer eingibt, da ein bestimmtes Feld immer x Bytes in den Datensatz startet. Eine Suche oder Auswahl in diesem Feld weiß, dass immer x Bytes in jedem Datensatz usw. überprüft werden.

8
Steve Barnes

Wenn den Spalten einer Datenbank definierte Typen zugewiesen werden, werden die Typen normalerweise selbst 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 festzustellen, 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 Speicherort des Datensatzes 32 Byte hinzuzufügen.

2) Wenn Sie ein Feld innerhalb einer Zeile nachschlagen, ist es möglich, einen genauen Versatz für dieses Feld erneut zu ermitteln, ohne etwas zu analysieren. Daher sind Spalten-Lookups eher eine einfache arithmetische Operation als eine potenziell kostspielige Datenverarbeitungsoperation.

6
UserNotFound

Sie haben gefragt warum DBMS haben statische Datentypen.

  1. Suchgeschwindigkeit. Der Sinn eines DBMS besteht darin, weit mehr Daten zu speichern, als Sie möglicherweise in ein Programm laden könnten. Denken Sie "an alle Kreditkartenbelege, die in den letzten zehn Jahren weltweit generiert 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, in effiziente Indizes zu laden.

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

  3. Geschichte. RDBMS wurden gestartet, als Computer nur wenige Megabyte RAM hatten und Speicher im Terabyte-Bereich enorm teuer war. Das Speichern eines Dutzend Bytes in jeder Zeile einer Tabelle kann unter diesen Umständen Tausende von Dollar und Stunden Zeit sparen.

  4. Der Fluch des Kundenstamms. RDBMS sind heutzutage sehr komplexe, hochoptimierte Softwarepakete und werden seit Jahrzehnten verwendet, um Daten zu sammeln. Sie sind reif. Sie arbeiten. Ein RDBMS-Absturz, der zu einem großen Datenverlust führt, ist heutzutage äußerst selten. Der Wechsel zu einem flexibleren Datentypisierungssystem ist für die meisten Unternehmen weder die Kosten noch das Risiko wert.

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

3
O. Jones

Im Allgemeinen Je detaillierter Sie der Datenbank mitteilen, was Sie speichern, desto mehr kann sie versuchen, verschiedene Leistungsmetriken in Bezug auf diese Daten zu optimieren. B. wie viel Speicherplatz auf der Disc zugewiesen werden soll oder wie viel Speicher beim Abrufen zugewiesen werden soll.

Warum Medientext, Langtext und Text?

Ich bin mir nicht sicher, welche Datenbank Sie verwenden , daher muss ich raten: Ich würde vermuten, 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. Weitere Informationen finden Sie in Ihrem Handbuch).

Warum Dezimal, Float und Int?

Unterschiedliche Präzisionsniveaus erfordern unterschiedliche Speichermengen, und nicht jede Verwendung erfordert ein Höchstmaß an Präzision. Siehe hier: https://docs.Oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF5095

Oracle verfügt über eine Reihe verschiedener numerischer Typen mit unterschiedlichen Speicheranforderungen und unterschiedlichen Funktionen in Bezug auf Genauigkeit und Größe der darstellbaren Anzahl.

Bis zu einem gewissen Grad ist es historisch.

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

Wenn Sie einer solchen Datei einige Indizes hinzufügen, haben Sie die Anfänge einer relationalen Datenbank.

Mit der Entwicklung relationaler Datenbanken wurden mehr Datentypen und Speicheroptionen eingeführt, darunter Text mit variabler Länge oder Binärfelder. Dies führte jedoch zu Datensätzen variabler Länge und unterbrach die Möglichkeit, Datensätze über Berechnungen oder Felder über einen festen Versatz konsistent zu lokalisieren. Egal, Maschinen sind heute viel leistungsfähiger als damals.

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

2
Zenilogix

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 Klartextdaten enthalten? oder "Diese Spalte kann Texteingaben von bis zu 16.777.215 Bytes enthalten"?

Wie Sie vermuten, liegt der Grund in der Effizienz. Die Abstraktionen lecken . Eine Abfrage wie SELECT author FROM books kann 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 Büchertabelle) genau die gleiche Länge in Bytes, und jedes Feld hat immer einen festen Versatz vom Zeilenanfang. Wenn beispielsweise jeder Datensatz in der Büchertabelle 100 Byte lang ist und das Autorenfeld auf Offset 23 steht, werden Autoren auf Byte 23, 123, 223, 323 usw. gespeichert. In welchen Code soll verschoben werden? der nächste Datensatz im Ergebnis dieser Abfrage? Im Grunde ist es das:

pointer += 100;

Ein CPU-Befehl. Faaaaaaaaast.

Die meiste Zeit arbeiten Sie weit genug von den Grundlagen entfernt, dass Sie sich nicht darum kümmern müssen. Interessiert es Sie als PHP-basierter Webentwickler , wie viele CPU-Anweisungen Ihr Code verwendet? Meistens nein, 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.

1
TRiG

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 eine Datenbank hingegen versucht, Datensätze mit genau der für ihre Felder erforderlichen Speichermenge zu speichern, kann die Änderung des Namens von Emma Smith in Emma Johnson dazu führen, dass ihr 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 Standort verfolgt, 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 Orten 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, vereinfacht jedoch die Arbeit erheblich.

1
supercat