In welchem ​​Datentyp soll ich eine E-Mail-Adresse in der Datenbank speichern?

44

Ich verstehe, dass eine 254-stellige E-Mail-Adresse gültig ist, aber bei Implementierungen, die ich recherchiert habe, wird in der Regel ein varchar (60) bis varchar (80) oder ein gleichwertiges verwendet. Beispiel: In dieser SQL Server-Empfehlung wird varchar (80) oder dieses Oracle-Beispiel verwendet

Gibt es einen Grund, nicht die vollen 254 Zeichen zu verwenden? Verbraucht ein Varchar per Definition nicht nur so viel Speicher, wie für die Speicherung der Daten benötigt wird?

Gibt es signifikante Auswirkungen auf die Leistung / Kompromisse, die dazu führen, dass bei so vielen Implementierungen weniger als die vollen 254 möglichen Zeichen verwendet werden?

Thronk
quelle

Antworten:

45

Ich habe es immer benutzt VARCHAR(320). Hier ist der Grund. Der Standard schreibt die folgenden Einschränkungen vor:

  • 64 Zeichen für den "lokalen Teil" (Benutzername).
  • 1 Zeichen für das @Symbol.
  • 255 Zeichen für den Domainnamen.

Nun werden einige Leute sagen, dass Sie mehr als das unterstützen müssen. Einige Leute werden auch sagen, dass Sie Unicode für Domain-Namen unterstützen müssen (was bedeutet, dass Sie wechseln müssen NVARCHAR). Während sich der Standard in der Zwischenzeit möglicherweise geändert hat (es ist schon eine Weile her, seit ich Skin im Spiel hatte), bin ich ziemlich zuversichtlich, dass die meisten Server der Welt derzeit keine Unicode-E-Mail-Adressen akzeptieren, und ich bin mir sicher Bei vielen Servern treten Probleme beim Erstellen und / oder Akzeptieren von Adressen mit mehr als 320 Zeichen auf.

Das heißt, Sie können sich jetzt auf das Schlimmste vorbereiten, wenn Sie möchten (und wenn Sie Datenkomprimierung in SQL Server 2008 R2 oder höher verwenden, profitieren Sie von der Unicode-Komprimierung, dh Sie zahlen nur die 2-Byte-Strafe für Zeichen, die tatsächlich benötigt werden es). Auf diese Weise können Sie Ihre Spalte so breit machen, wie Sie möchten, und Sie können zulassen, dass die Leute allzu viel Müll hineinstecken. Sie erhalten keine E-Mail, wenn sie Ihnen Müll geben, so wie sie es nicht tun Erhalten Sie eine E-Mail, wenn die Einfügung fehlschlägt. Das Problem ist, wenn Sie ungültigen Müll reinlassen, Siedamit umgehen müssen. Und egal wie groß Sie es machen - wenn jemand versucht, 400 Zeichen in eine 320-Zeichen-Spalte zu schreiben, versucht jemand, 1025 Zeichen in eine 1024-Zeichen-Spalte zu schreiben. Es gibt keinen Grund, warum eine vernünftige Person eine E-Mail-Adresse mit mehr als 320 Zeichen haben sollte, es sei denn, sie verwendet sie zum expliziten Testen von Systemgrenzen.

Aber hören Sie auf, nach Meinungen dazu zu fragen - und schauen Sie nicht mehr nach anderen Implementierungen, um sich eine Orientierung zu verschaffen (in diesem Fall haben sich die von Ihnen angesprochenen nicht die Mühe gemacht, ihre eigenen Hausaufgaben zu machen, und haben nur Zahlen aus ihren herausgesucht. . Sie haben direkten Zugriff auf den Standard. Stellen Sie sicher, dass Sie die aktuellste Version konsultieren, diese mindestens unterstützen und stets auf dem neuesten Stand sind, damit Sie sich an Änderungen der Spezifikationen anpassen können.


EDIT danke an @ypercube für den Ping im Chat.

Abgesehen davon möchten Sie vielleicht gar nicht erst die gesamte Adresse in eine einzelne Spalte schreiben. Die Normalisierung könnte darauf hindeuten, dass Sie nicht @hotmail.com15 Millionen Mal speichern möchten, wenn ein viel dünneres FK int gut funktioniert und nicht den zusätzlichen Overhead von Spalten variabler Länge hat. Sie können den Benutzernamen auch normalisieren [email protected]und [email protected]einen gemeinsamen Benutzernamen verwenden - sie kennen sich nicht, aber Ihre Datenbank kümmert sich nicht darum.

Ich habe hier über einiges davon gesprochen:

http://www.mssqltips.com/sqlservertip/2657/storing-email-addresses-more-efficiently-in-sql-server/

http://www.mssqltips.com/sqlservertip/2671/sql-server-part-2/

Dies führt jedoch zu Problemen mit der obigen Beschränkung von 254 Zeichen, da offenbar kein Konsens darüber besteht, was passiert, wenn eine gültige Domäne mit 255 Zeichen mit einem gültigen lokalen Teil mit 1 Zeichen kombiniert wird. Dies sollte von den meisten Servern auf der Welt akzeptiert werden, scheint jedoch diese Beschränkung von 254 Zeichen zu verletzen. Erstellen Sie also eine DomainsTabelle mit einer künstlich geringeren Längenbeschränkung für E-Mail-Adressen, wenn die Domain als gültige URL mit 255 Zeichen wiederverwendet werden könnte ?

Aaron Bertrand
quelle
Ich mag diesen Ansatz, aber was ist mit der E-Mail-Eindeutigkeit? Wie wird es gehandhabt?
Roberto Rizzi
2
@RobertoRizzi Eine eindeutige Einschränkung oder ein eindeutiger Primärschlüssel für die Kombination von DomainID + LocalPart oder umgekehrt.
Aaron Bertrand
5

Bei dieser Entscheidung gibt es einige Überlegungen. In erster Linie müssen aktuelle und zukünftige Vorhersagen der notwendigen Einschränkungen verwendet werden, denen die Daten entsprechen müssen. Es gibt einen Grund, warum Sie nicht jeden Datentyp für Zeichenfolgenspalten festlegen möchten, varchar(1024)wenn Sie nur eine Zeichenfolge speichern, die nicht länger als 32 Zeichen sein darf (Betonung des Schlüsselworts should ).

Wenn Sie eine Sicherheitsanfälligkeit haben, bei der alle E-Mails so geändert werden, dass sie 255 Zeichen lang sind, kann dies möglicherweise zu einer längeren Beeinträchtigung der Leistung durch Seitenaufteilungen führen. Dies mag ungewöhnlich erscheinen und ist es höchstwahrscheinlich, aber Sie müssen Ihre Daten an die geschäftlichen Anforderungen anpassen . Ich bin fest davon überzeugt, dass ähnlich wie bei der jahrhundertealten Einschränkung der Datenbank- und Anwendungsdebatte auch auf der Datenebene Datentypbeschränkungen und zulässige Werte durchgesetzt werden sollten.

Was mich zu meinem nächsten Punkt führt. Die Datenbank ist höchstwahrscheinlich nur die Datenebene. Was nutzt die Anwendungsebene? Wenn Sie beispielsweise eine Anwendung haben, in der Sie nur 80 Zeichen für eine E-Mail-Adresse eingeben können, warum sollte der Datentyp größer sein? Unternehmen müssen zwei Fragen beantworten:

  1. Was kann es sein
  2. Was soll es sein

Erst dann haben Sie Ihre Antwort.

Verbraucht ein Varchar per Definition nicht nur so viel Speicher, wie für die Speicherung der Daten benötigt wird?

Ja und nein. Es wird eine Art Versatz für die Daten mit variabler Länge geben, um deren Länge aufzuzeichnen.

Thomas Stringer
quelle
3

RFC 5321 (die aktuelle SMTP-Spezifikation, die RFC2821 veraltet) besagt:

Die maximale Gesamtlänge eines Benutzernamens oder eines anderen lokalen Teils beträgt 64 Bytes. Die maximale Gesamtlänge eines Domainnamens oder einer Domainnummer beträgt 255 Bytes

64 + 255 + @ impliziert also VARCHAR (320). Sie werden wahrscheinlich nie so viel brauchen, aber es ist sicher, es für alle Fälle zu haben.

Avakharia
quelle
4
Das korrekte Limit ist 254. rfc-editor.org/errata_search.php?rfc=3696&eid=1690
Neil McGuigan,
1

Jede Variation von VARCHAR belegt nur so viel Platz im Datenblock, wie benötigt wird. Die zusätzlichen Bytes zum Speichern der Länge sind im Vergleich zu dem Platz, der bei Verwendung einer CHAR mit fester Länge verschwendet würde, trivial.

Da eine VARCHAR-Spaltenlänge tatsächlich eine "maximale Länge" ist, sollte sie unter allen Umständen größer als die maximal mögliche Länge eingestellt werden. Es wird nur so viel Platz verwendet, wie jede Zeile benötigt. Die Anwendungsprogramme sollten dann mit Bildlauffeldern oder was auch immer sinnvoll ist, basierend auf typischen Werten entworfen werden.

Ein Datenbankdesign ist insofern wie ein physisches Stück Papier, als es die harten Grenzen der Größe festlegt. Eine Papierseite kann nicht vergrößert werden. In dieser Analogie ähnelt das Anwendungsprogramm einem auf der Seite gedruckten Formular. Es kann eine Menge getan werden, um anzupassen, wie viele Daten in dem Formular gespeichert werden können.

Obwohl der Befehl zum Erhöhen einer VARCHAR-Größe möglicherweise einfach aussieht und sofort in einer kleinen Tabelle ausgeführt wird, erfordert dies in einer Tabelle mit Tausenden von Zeilen oder mehr wahrscheinlich eine Art Datenbankstillstand, während alle Daten- und Indexblöcke neu generiert werden. Eine Möglichkeit besteht darin, alles in eine neue Tabelle mit den größeren Spalten zu kopieren. Welche Technik auch immer angewendet wird, es ist eine große Sache. Daher sollten Sie die VARCHAR-Spaltengröße nach dem Laden einer Produktionstabelle als weitgehend unveränderlich betrachten.

DocSalvager
quelle
1

Als Kommentar zu den hervorragenden Antworten schon hier:

Wenn Sie das Feld als erstellt haben varchar(240)und es später in ein längeres Feld ändern möchten varchar(320), sollte diese Änderung beispielsweise eine triviale Operation auf dem Datenbankserver sein - natürlich abhängig von Ihrem Datenbankprodukt.

alter table Schema.Object alter column EmailAddress varchar(320) ;

Zweitens kann, abhängig von der durchschnittlichen Zeilengröße und der Seitengröße, die Anzahl der zugewiesenen Seiten (der tatsächlich von der Tabelle belegte Speicherplatz) durch Verwenden varchar(320)von varchar(240)nicht geändert werden.

Drittens sprach jemand über die Validierung einer E-Mail-Adresse. Ich behaupte, dass es nur einen sicheren Weg gibt, eine E-Mail-Adresse zu validieren, nämlich eine E-Mail an sie zu senden. :-)

Greenstone Walker
quelle
0

VARCHAR ist der beste Datentyp für E-Mail-Adressen, da E-Mails sehr unterschiedlich lang sind. NVARCHAR ist auch eine Alternative, aber ich würde empfehlen, es nur zu verwenden, wenn die E-Mail-Adresse erweiterte Zeichen enthält, und bedenken Sie, dass es im Vergleich zu VARCHAR doppelt so viel Speicherplatz benötigt.

In meiner Umgebung verwenden wir varchar (70), da die längsten Zeichen, auf die ich gestoßen bin, eng zwischen 60 und 70 Zeichen lang sind. Dies hängt jedoch auch von der Kundenbasis Ihres Unternehmens ab. Stellen Sie als Randnotiz auch sicher, dass Sie eine E-Mail-Validierungsprüfung für die Gültigkeit von E-Mail-Adressen durchgeführt haben. Verwenden Sie beispielsweise Check-Constraints oder CHARINDEX

Kin Shah
quelle
0

SQL verwenden DOMAIN

Wenn Sie einen Enterprise-Datenbankserver verwenden, sollte es eine Möglichkeit geben, eine E-Mail-Adresse mit einer DOMAINgewissen Gültigkeit zu speichern . Domänen werden in der SQL-Spezifikation angegeben

Eine Domäne ist ein benanntes benutzerdefiniertes Objekt, das an bestimmten Stellen, an denen ein Datentyp angegeben werden kann, als Alternative zu einem Datentyp angegeben werden kann. Eine Domain besteht aus einem Datentyp, möglicherweise einer Standardoption und null oder mehr (Domain-) Einschränkungen.

Das kostenlose und Open-Source-Programm PostgreSQL unterstützt dies. Abgesehen von Einschränkungen bei der Implementierung der Spezifikation enthält die Spalte selbst eine gültige E-Mail-Adresse. Sie können zum Beispiel ..

  • Erstellen Sie eine benutzerdefinierte DOMAINE-Mail über die HTML5-Spezifikation.
  • Oder über die E-Mail-Spezifikation RFC822, RFC2822, RFC5322.
  • Erstellen Sie eine Benutzerdefinition DOMAIN, die den Server zum Zeitpunkt der Überprüfung auf einen MX-Eintrag überprüft.

Ich bewerte diese Optionen in dieser Antwort, die spezifisch für PostgreSQL ist

Evan Carroll
quelle