Dalam tipe data apa saya harus menyimpan alamat email dalam basis data?

44

Saya mengerti bahwa alamat email 254 karakter valid, tetapi implementasi yang saya teliti cenderung menggunakan varchar (60) ke varchar (80) atau setara. Sebagai contoh: rekomendasi SQL Server ini menggunakan varchar (80) atau contoh Oracle ini

Apakah ada alasan untuk tidak menggunakan maksimal 254 karakter? Bukankah suatu definisi varchar hanya menggunakan penyimpanan sebanyak yang diperlukan untuk menyimpan data?

Apakah ada implikasi / trade-off kinerja yang signifikan yang menyebabkan begitu banyak implementasi menggunakan kurang dari 254 karakter yang mungkin?

Thronk
sumber

Jawaban:

45

Saya selalu menggunakan VARCHAR(320). Inilah sebabnya. Standar menentukan batasan berikut:

  • 64 karakter untuk "bagian lokal" (nama pengguna).
  • 1 karakter untuk @simbol.
  • 255 karakter untuk nama domain.

Sekarang, beberapa orang akan mengatakan Anda perlu mendukung lebih dari itu. Beberapa orang juga akan mengatakan bahwa Anda perlu mendukung Unicode untuk nama domain (artinya Anda harus beralih ke NVARCHAR). Sementara standar dapat berubah sementara itu (sudah lama sejak saya sudah skin di permainan), saya cukup yakin bahwa saat ini sebagian besar server di dunia tidak akan menerima alamat email Unicode, dan saya yakin banyak server akan mengalami masalah membuat dan / atau menerima alamat dengan> 320 karakter.

Yang mengatakan, Anda dapat mempersiapkan yang terburuk sekarang, jika Anda suka (dan jika Anda menggunakan Kompresi Data di SQL Server 2008 R2 atau lebih baik, Anda akan mendapat manfaat dari kompresi Unicode, yang berarti Anda hanya membayar penalti 2 byte untuk karakter yang benar-benar membutuhkan saya t). Dengan cara ini Anda dapat membuat kolom Anda selebar yang Anda inginkan, dan Anda dapat membiarkan orang-orang menjejalkan sampah terlalu lama di sana yang mereka inginkan - mereka tidak akan menerima email jika mereka memberi Anda sampah sama seperti mereka tidak mau menerima email jika sisipan gagal. Masalahnya adalah jika Anda membiarkan sampah yang tidak valid masuk, Andaharus menghadapinya. Dan berapa pun ukuran yang Anda buat - jika seseorang mencoba memasukkan 400 karakter ke dalam kolom 320 karakter, seseorang akan mencoba memasukkan 1025 karakter ke dalam kolom 1024 karakter. Tidak ada alasan orang yang berakal memiliki alamat email> 320 karakter kecuali mereka menggunakannya untuk secara eksplisit menguji batasan sistem.

Tapi berhentilah meminta pendapat tentang ini - dan berhentilah melihat implementasi lain untuk panduan (kebetulan dalam kasus ini yang Anda rujuk tidak repot-repot mengerjakan pekerjaan rumah mereka sendiri dan hanya mengambil nomor dari mereka, yah, Anda tahu) . Anda memiliki akses langsung ke standar - pastikan Anda berkonsultasi dengan versi terbaru, mendukungnya sebagai minimum, dan tetap di atas standar sehingga Anda dapat beradaptasi dengan perubahan spesifikasi.


EDIT terima kasih kepada @ypercube untuk ping di obrolan.

Sebagai tambahan, mungkin Anda tidak ingin membuang seluruh alamat ke dalam satu kolom di tempat pertama. Normalisasi mungkin menunjukkan bahwa Anda tidak ingin menyimpan @hotmail.com15 juta kali ketika int FK jauh lebih kurus akan bekerja dengan baik dan tidak memiliki overhead tambahan dari kolom panjang variabel. Anda juga bisa menormalkan nama pengguna, [email protected]dan [email protected]membagikan nama pengguna yang sama - mereka tidak saling kenal tetapi database Anda tidak peduli tentang itu.

Saya membicarakan beberapa hal di sini:

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

http://www.mssqltips.com/sqlservertip/2671/storing-email-addresses-more-efisienly-in-sql-server--part-2/

Namun hal ini menimbulkan tantangan hingga batas 254 karakter di atas, karena tampaknya tidak ada konsensus tentang apa yang terjadi ketika domain 255 karakter yang valid digabungkan dengan bagian lokal 1 karakter yang valid. Ini harus diterima oleh sebagian besar server di seluruh dunia tetapi tampaknya melanggar batas 254 karakter ini. Jadi, apakah Anda membuat Domainstabel yang memiliki batasan panjang artifisial lebih rendah untuk alamat e-mail, ketika domain dapat digunakan kembali sebagai URL 255 karakter yang valid?

Aaron Bertrand
sumber
Saya suka pendekatan ini tetapi bagaimana dengan keunikan email? Bagaimana cara mengaturnya?
Roberto Rizzi
2
@RobertoRizzi Suatu kendala unik atau kunci utama pada kombinasi DomainID + LocalPart atau sebaliknya.
Aaron Bertrand
5

Ada beberapa pertimbangan dengan keputusan ini. Yang pertama dan terpenting adalah menggunakan prediksi saat ini dan di masa depan mengenai batasan yang diperlukan yang harus dipenuhi oleh data. Ada alasan mengapa Anda tidak ingin mengatur setiap tipe data kolom string varchar(1024)saat Anda hanya menyimpan string yang tidak boleh melebihi 32 karakter (penekanan pada kata kunci yang seharusnya ).

Jika Anda memiliki semacam kerentanan di mana semua email diubah menjadi 255 karakter, maka Anda berpotensi memiliki dampak kinerja yang panjang dari pemisahan halaman. Ini mungkin tampak luar biasa, dan kemungkinan besar memang demikian, tetapi Anda perlu mengukur data Anda sesuai kebutuhan bisnis . Sama seperti batasan lama pada debat database vs aplikasi, saya sangat percaya bahwa batasan tipe data dan nilai yang diijinkan juga harus ditegakkan di tingkat data.

Yang membawa saya ke poin saya berikutnya. Basis data kemungkinan besar hanya tingkat data. Apa yang digunakan tingkat aplikasi? Misalnya, jika Anda memiliki aplikasi di mana Anda hanya dapat memasukkan 80 karakter untuk alamat email, mengapa Anda ingin tipe data menjadi lebih besar? Bisnis perlu menjawab dua pertanyaan:

  1. Apa yang bisa itu?
  2. Apa yang seharusnya ?

Hanya dengan begitu Anda akan mendapat jawaban.

Bukankah suatu definisi varchar hanya menggunakan penyimpanan sebanyak yang diperlukan untuk menyimpan data?

Iya dan tidak. Akan ada semacam offset untuk data panjang variabel untuk mencatat panjangnya.

Thomas Stringer
sumber
3

RFC 5321 (spesifikasi SMTP saat ini, obsoletes RFC2821) menyatakan:

Panjang total maksimum nama pengguna atau bagian lokal lainnya adalah 64 oktet. Panjang total maksimum nama atau nomor domain adalah 255 oktet

Jadi 64 + 255 + @ tanda menyiratkan VARCHAR (320). Anda mungkin tidak akan pernah membutuhkan sebanyak ini tetapi aman untuk memilikinya, untuk berjaga-jaga.

avakharia
sumber
4
Batas yang benar adalah 254. rfc-editor.org/errata_search.php?rfc=3696&eid=1690
Neil McGuigan
1

Variasi VARCHAR apa pun hanya menggunakan banyak ruang di blok data sesuai kebutuhan. Byte tambahan untuk menyimpan panjang adalah sepele dibandingkan dengan ruang yang akan terbuang menggunakan CHAR panjang tetap sebagai gantinya.

Karena panjang kolom VARCHAR benar-benar "panjang maksimum," itu harus ditetapkan lebih besar dari panjang maksimum yang mungkin dalam keadaan apa pun. Hanya ruang sebanyak yang dibutuhkan setiap baris yang akan digunakan. Program aplikasi kemudian harus dirancang dengan bidang gulir atau apa pun yang masuk akal berdasarkan nilai-nilai khas.

Desain basis data adalah seperti selembar kertas fisik karena ia menetapkan batas keras untuk ukuran. Halaman kertas tidak bisa diperbesar. Dalam analogi ini, program aplikasi seperti formulir yang dicetak pada halaman. Ada banyak yang bisa dilakukan untuk menyesuaikan berapa banyak data yang dapat kita pegang dalam formulir.

Meskipun perintah untuk meningkatkan ukuran VARCHAR mungkin terlihat sederhana dan berjalan langsung di atas meja kecil, melakukannya di atas meja dengan ribuan baris atau lebih mungkin akan memerlukan beberapa jenis basis data sementara meregenerasi semua data dan blok indeks. Salah satu caranya adalah menyalin semuanya ke tabel baru dengan kolom yang lebih besar. Teknik apa pun yang digunakan, itu masalah besar. Dengan demikian, Anda harus mempertimbangkan ukuran kolom VARCHAR sebagian besar tidak dapat diubah setelah tabel produksi dimuat.

DocSalvager
sumber
1

Sebagai komentar atas jawaban yang sangat baik sudah ada di sini:

Pertama, jika Anda telah membuat bidang sebagai varchar(240)dan Anda ingin kemudian mengubahnya ke bidang yang lebih panjang, katakanlah varchar(320), perubahan ini harus menjadi operasi sepele pada server database - tergantung, tentu saja, pada produk database Anda.

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

Kedua, tergantung pada ukuran baris rata-rata dan ukuran halaman, menggunakan varchar(320)bukannya varchar(240)mungkin tidak mengubah jumlah halaman yang dialokasikan (ruang disk sebenarnya diambil oleh tabel).

Ketiga, seseorang di atas berbicara tentang memvalidasi alamat email. Saya berpendapat bahwa hanya ada satu cara pasti untuk memvalidasi alamat email dan itu adalah mengirim email ke sana. :-)

Greenstone Walker
sumber
0

VARCHAR adalah tipe data terbaik yang akan digunakan untuk alamat email karena panjangnya Email sangat bervariasi. NVARCHAR juga merupakan alternatif tetapi saya akan merekomendasikannya untuk digunakan hanya jika alamat emailnya berisi karakter tambahan dan perlu diingat bahwa ia membutuhkan ruang penyimpanan dua kali lipat dibandingkan dengan VARCHAR.

Di lingkungan saya, kami menggunakan varchar (70) sebagai yang terpanjang yang saya temui hampir 60-70 tahun, tetapi tergantung pada basis pelanggan perusahaan Anda juga. Juga, sebagai catatan tambahan, pastikan Anda memiliki beberapa pemeriksaan validasi Email di tempat untuk validitas alamat Email .. seperti menggunakan kendala pemeriksaan atau CHARINDEX

Kin Shah
sumber
0

Menggunakan SQL DOMAIN

Jika Anda menggunakan server Database Perusahaan, harus ada cara untuk menyimpan alamat email DOMAINdengan tingkat validitas tertentu. Domain ditentukan dalam spesifikasi SQL

Domain adalah objek yang ditentukan pengguna yang ditentukan yang dapat ditentukan sebagai alternatif untuk tipe data di tempat-tempat tertentu di mana tipe data dapat ditentukan. Domain terdiri dari tipe data, mungkin opsi default, dan nol atau lebih (domain) kendala.

Sebagai contoh, PostgreSQL sumber bebas dan terbuka mendukung ini, kecuali segala batasan dalam implementasi spesifikasi Anda, kolom itu sendiri berisi email yang valid. Anda bisa misalnya ..

  • Buat kustom di DOMAINatas spesifikasi email HTML5.
  • Atau, atas spesifikasi email RFC822, RFC2822, RFC5322.
  • Buat kustom DOMAINyang memeriksa server untuk data MX pada saat pemeriksaan.

Saya mengevaluasi opsi ini dalam jawaban ini yang khusus untuk PostgreSQL

Evan Carroll
sumber