Apa yang diperoleh basis data relasional dengan menetapkan tipe data yang telah ditentukan untuk setiap kolom?

44

Saya sedang bekerja dengan database SQL sekarang, dan ini selalu membuat saya penasaran, tetapi pencarian Google tidak banyak berubah: Mengapa tipe data yang ketat?

Saya mengerti mengapa Anda memiliki beberapa tipe data yang berbeda, misalnya seperti bagaimana membedakan antara data biner dan teks biasa . Daripada menyimpan 1s dan 0s data biner sebagai plaintext, saya sekarang mengerti bahwa lebih efisien untuk menyimpan data biner sebagai formatnya sendiri.

Tetapi yang saya tidak mengerti adalah apa manfaatnya memiliki begitu banyak tipe data yang berbeda:

  • Mengapa mediumtext, longtextdan text?
  • Mengapa decimal, floatdan int?
  • dll.

Apa manfaatnya memberi tahu basis data "Hanya akan ada 256 byte data teks biasa dalam entri ke kolom ini." atau "Kolom ini dapat memiliki entri teks hingga 16.777.215 byte"?

Apakah ini manfaat kinerja? Jika demikian, mengapa mengetahui ukuran entri sebelum tangan membantu kinerja? Atau lebih tepatnya itu sesuatu yang lain sama sekali?

john doe
sumber
2
Saya pikir pertanyaan ini seharusnya sudah ada di sini, tetapi saya mencari di situs dan tidak menemukan sesuatu yang bermanfaat.
john doe
6
Jika Anda tidak memiliki yang berbeda decimal, floatdan intjenis, apa yang Anda harapkan 1 / 3lakukan? Bagaimana dengan 1.0 / 3.0? Bisakah Anda yakin bahwa ketika Anda membagi columnAdengan columnBitu Anda akan mendapatkan hasil yang Anda harapkan?
Andrew mengatakan Reinstate Monica
2
@ johndoe Saya tidak berpikir itu akan perlu, tetapi bisa sangat nyaman. Katakanlah Anda ingin menerapkan batasan bahwa persediaan toko tidak boleh lebih rendah dari 5% dari penjualan bulanan yang diharapkan. Atau Anda ingin memastikan bahwa total anggaran setiap divisi tidak lebih dari 20% dari total anggaran. Itu juga bisa muncul dalam kolom yang dihitung yang ingin Anda hitung dengan cara yang sama di beberapa aplikasi menggunakan database yang sama.
Andrew mengatakan Reinstate Monica
2
Perlu dicatat bahwa SQLite tidak menetapkan tipe yang ditentukan sebelumnya per kolom : "SQLite adalah" typeless ". Ini berarti bahwa Anda dapat menyimpan segala jenis data yang Anda inginkan di kolom mana saja dari tabel apa pun, terlepas dari tipe data yang dinyatakan dari kolom itu. "
Perdana

Jawaban:

50

SQL adalah bahasa yang diketik secara statis . Ini berarti Anda harus tahu apa jenis variabel (atau bidang, dalam hal ini) sebelum Anda dapat menggunakannya. Ini adalah kebalikan dari bahasa yang diketik secara dinamis, di mana itu belum tentu demikian.

Pada intinya, SQL dirancang untuk mendefinisikan data ( DDL ) dan mengakses data ( DML ) dalam mesin basis data relasional . Pengetikan statis menghadirkan beberapa keuntungan dibandingkan pengetikan dinamis untuk jenis sistem ini.

  • Indeks , digunakan untuk dengan cepat mengakses catatan tertentu, berfungsi dengan sangat baik ketika ukurannya tetap. Pertimbangkan kueri yang menggunakan indeks, mungkin dengan beberapa bidang: jika tipe dan ukuran data diketahui sebelumnya, saya dapat dengan cepat membandingkan predikat saya (klausa WHERE atau kriteria GABUNG) dengan nilai-nilai dalam indeks dan menemukan catatan yang diinginkan lebih cepat .

  • Pertimbangkan dua nilai integer . Dalam sistem tipe dinamis, mereka mungkin memiliki ukuran variabel (bayangkan Java BigInteger, atau integer presisi arbitrer built-in arbitrary). Jika saya ingin membandingkan bilangan bulat, saya harus tahu panjang bitnya terlebih dahulu. Ini adalah aspek perbandingan integer yang sebagian besar disembunyikan oleh bahasa modern, tetapi sangat nyata di level CPU. Jika ukurannya sudah diperbaiki dan diketahui sebelumnya, seluruh langkah dihapus dari proses. Sekali lagi, basis data seharusnya dapat memproses zillions transaksi secepat mungkin. Kecepatan adalah raja.

  • SQL dirancang kembali pada tahun 1970-an. Pada hari-hari awal microcomputing, memori berada pada premium. Membatasi data membantu menjaga persyaratan penyimpanan tetap terkendali. Jika integer tidak pernah tumbuh melebihi satu byte, mengapa mengalokasikan lebih banyak penyimpanan untuknya? Itulah ruang terbuang di era memori terbatas. Bahkan di zaman modern, byte yang terbuang ekstra itu dapat menambah dan membunuh kinerja cache CPU. Ingat, ini adalah mesin basis data yang dapat melayani ratusan transaksi per detik, bukan hanya lingkungan pengembangan kecil Anda.

  • Sejalan dengan penyimpanan terbatas, akan sangat membantu untuk dapat memasukkan satu catatan dalam satu halaman dalam memori. Setelah Anda membaca lebih dari satu halaman, ada lebih banyak halaman yang hilang dan akses memori yang lebih lambat. Mesin yang lebih baru memiliki optimisasi untuk membuat ini kurang dari masalah, tetapi masih ada. Dengan mengukur data dengan tepat, Anda dapat mengurangi risiko ini.

  • Selain itu di zaman modern, SQL digunakan untuk menghubungkan ke bahasa lain melalui ORM atau ODBC atau lapisan lain. Beberapa dari bahasa ini memiliki aturan tentang keharusan jenis yang kuat dan statis. Cara terbaik adalah mematuhi persyaratan yang lebih ketat, karena bahasa yang diketik secara dinamis dapat menangani jenis statis lebih mudah daripada sebaliknya.

  • SQL mendukung pengetikan statis karena mesin basis data memerlukannya untuk kinerja, seperti yang ditunjukkan di atas.

Sangat menarik untuk dicatat bahwa ada implementasi SQL yang tidak diketik dengan kuat. SQLite mungkin adalah contoh paling populer dari mesin basis data relasional tersebut. Kemudian lagi, ia dirancang untuk penggunaan single-threaded pada satu sistem tunggal, sehingga masalah kinerja mungkin tidak diucapkan seperti misalnya dalam database Oracle perusahaan yang melayani jutaan permintaan per menit.

gruszczy
sumber
SQLite memiliki tipe data yang membedakan antara data numerik dan teks, tetapi hanya memiliki 5 "kelas" penyimpanan data: sqlite.org/datatype3.html
FrustratedWithFormsDesigner
1
@FrustratedWithFormsDesigner saya tahu, tetapi masih jauh dari ketat seperti mesin seperti SQL Server, Oracle, atau PostgreSQL.
Tidak hanya SQL yang diketik secara statis - karena adanya kendala pemeriksaan, ia secara efektif mendukung jenis penyempurnaan.
Gardenhead
4
Meskipun tersirat dalam bullet pertama Indexes, pada dasarnya lebih menyatakan: Memiliki tipe data memungkinkan mesin database memahami data , untuk membuat perbandingan (angka lebih besar / lebih kecil, tanggal-tanggal sebelumnya / nanti, sebelum / sesudah dalam alfabet), dan karenanya memungkinkan pengurutan dan pencarian .
Basil Bourque
Jadi, jika ukuran itu penting ... dan sql perlu tahu sebelumnya ... apa ukuran persis dari transaksi "Zillion"?
WernerCD
24

Pertama: teks biasa adalah biner (bahkan bukan karakter UTF8 atau ASCII "0" dan "1" tetapi bit on / off aktual)

Karena itu, beberapa alasannya adalah:

  • Batasan bisnis / desain: mengizinkan nomor 7626355112 di kolom HEIGHT dari tabel PERSON akan salah. Membiarkan "Howya" di kolom DATE pada INVOICE akan salah.
  • Kurangi kode rawan kesalahan: Anda tidak perlu menulis kode untuk memastikan data yang diambil dari kolom tanggal benar-benar tanggal. Jika tipe kolom dinamis, Anda harus melakukan banyak pemeriksaan tipe saat membacanya.
  • Efisiensi komputasi: Jika kolom bertipe INTEGER, dan Anda SUM (), RDBMS tidak harus menerapkan aritmatika titik apung.
  • Efisiensi penyimpanan: menyatakan bahwa sebuah kolom adalah VARCHAR (10) memungkinkan RDBMS mengalokasikan ruang lebih tepat.
  • Integritas dan keutuhan referensial: PK (atau FK) dari sebuah tabel tidak boleh memungkinkan mengapung, karena persamaan titik mengambang rumit, jadi Anda harus mendeklarasikannya dalam tipe non-float, seperti karakter atau bilangan bulat.
  • Ada RDBMS dengan tipe kolom dinamis (tidak ketat) (SQLite) . Ini menggunakan konsep "tipe afinitas" sambil tetap memungkinkan Anda untuk memasukkan apa saja ke dalam kolom apa pun tanpa mengeluh. Ada pertukaran yang tidak akan dibahas di sini. Lihat pertanyaan ini .
Tulains Córdova
sumber
8

Sehingga kode yang mendasari bahwa database ditulis dapat mengalokasikan dan menggunakan catatan ukuran tetap, jika ia tahu bahwa bidang tertentu dapat berisi 0 hingga 256 karakter teks maka dapat mengalokasikan blok 256 byte untuk menyimpannya.

Ini membuat segalanya jauh lebih cepat, misalnya Anda tidak harus mengalokasikan penyimpanan tambahan sebagai tipe pengguna, karena bidang yang diberikan selalu dimulai x byte ke dalam catatan pencarian atau pilih pada bidang itu yang tahu untuk selalu memeriksa x byte ke dalam setiap catatan, dll.

Steve Barnes
sumber
Kalau saja semua jawaban bisa singkat dan langsung ...
Darren Ringer
6

Ketika kolom-kolom dari suatu basis data diberikan tipe-tipe tertentu, tipe-tipe tersebut biasanya didefinisikan sendiri untuk memiliki ukuran tertentu dalam bit. Hasil dari:

1) ketika mesin basis data melintasi baris dalam sebuah tabel, ia tidak harus melakukan penguraian mewah untuk menentukan di mana setiap catatan berakhir, ia hanya dapat mengetahui bahwa setiap baris terdiri dari, katakanlah, 32 byte, dan untuk mendapatkan catatan berikutnya cukup untuk menambahkan 32 byte ke lokasi catatan saat ini.

2) ketika mencari bidang dalam satu baris, dimungkinkan untuk mengetahui offset yang tepat untuk bidang itu lagi tanpa menguraikan apa pun, sehingga pencarian kolom adalah operasi aritmatika sederhana daripada proses pengolahan data yang berpotensi mahal.

Pengguna tidak ditemukan
sumber
Bidang panjang tetap dapat membuat pemrosesan lebih efisien karena panjang rekaman dan offset bidang yang konsisten, tetapi bidang panjang variabel dapat membatalkan manfaat tersebut karena panjang rekaman dan offset bidang dapat bervariasi. Demikian pula, kompresi tingkat catatan akan menghasilkan catatan panjang variabel, sehingga lokasi catatan yang diberikan tidak dapat hanya dihitung.
Zenilogix
Ini benar, dan itu adalah saran umum untuk waktu yang lama untuk menghindari bidang panjang variabel untuk alasan itu. Saya tidak tahu bagaimana para pemain besar melakukannya tetapi sepertinya Anda mungkin bisa mendapatkan kembali beberapa manfaat dari panjang tetap dengan meminta bidang lebar variabel toko mesin di tabel atau blok memori yang tidak terlihat oleh pengguna dan memiliki representasi tabel primer dari bidang-bidang tersebut menjadi 'penunjuk' (lebar tetap) ke dalamnya. Mengingat Anda harus secara teratur melakukan pemindaian penuh bidang panjang variabel di tempat pertama hit kinerja tipuan mungkin layak mempertahankan lebar tetap.
UserNotFound
3

Anda bertanya mengapa DBMS memiliki tipe data statis.

  1. Kecepatan pencarian. Inti dari DBMS adalah menyimpan data yang jauh lebih banyak daripada yang dapat Anda muat ke dalam suatu program. Pikirkan "semua slip kartu kredit yang dihasilkan di dunia dalam sepuluh tahun terakhir". Untuk mencari data tersebut secara efisien, tipe data panjang tetap sangat membantu. Ini terutama berlaku untuk data terstruktur seperti perangko tanggal dan nomor akun. Jika Anda tahu apa yang Anda hadapi sebelumnya, lebih mudah memuat ke indeks yang efisien.

  2. Integritas dan kendala. Lebih mudah menjaga data tetap bersih jika memiliki tipe data yang diperbaiki.

  3. Sejarah. RDBMS dimulai ketika komputer memiliki beberapa megabyte RAM, dan penyimpanan skala terabyte sangat mahal. Menyimpan selusin byte di setiap baris tabel dapat menghemat ribuan dolar dan waktu dalam keadaan itu.

  4. Kutukan dari basis pelanggan. RDBMS saat ini adalah paket perangkat lunak yang sangat kompleks, sangat dioptimalkan, dan telah digunakan selama beberapa dekade untuk mengumpulkan data. Mereka dewasa. Mereka bekerja. Kecelakaan RDBMS yang mengakibatkan hilangnya data dalam skala besar jarang terjadi akhir-akhir ini. Beralih ke sesuatu dengan sistem pengetikan data yang lebih fleksibel tidak sebanding dengan biaya atau risiko bagi sebagian besar organisasi.

Analogi: mungkin sangat jelas bahwa sistem kereta bawah tanah perkotaan akan bekerja lebih baik (lebih tenang, lebih cepat, lebih hemat daya) pada pengukur rel yang lebih sempit. Tetapi bagaimana Anda akan mengubah semua rel di sistem kereta bawah tanah Kota New York untuk mewujudkan perbaikan itu? Anda tidak, jadi Anda mengoptimalkan apa yang Anda miliki.

O. Jones
sumber
3

Secara umum, semakin detail Anda memberi tahu database tentang apa yang Anda simpan, semakin dapat mencoba mengoptimalkan berbagai metrik kinerja yang terkait dengan data itu, seperti berapa banyak ruang yang dialokasikan pada disk atau berapa banyak memori yang dialokasikan ketika mengambilnya. .

Mengapa mediumtext, longtext, dan teks?

Tidak yakin basis data mana yang Anda gunakan, jadi saya harus menebak: Saya kira dua tipe data ini memiliki batas atas, salah satunya tidak. Menggunakan tipe data untuk teks yang memiliki batas atas memberi tahu basis data berapa ruang penyimpanan yang dibutuhkan untuk setiap catatan. Ada juga kemungkinan bahwa beberapa database mungkin memiliki cara berbeda untuk menyimpan teks besar (mungkin tidak terbatas) vs teks kecil dengan panjang tetap (ini dapat bervariasi berdasarkan basis data, periksa manual Anda untuk mengetahui tentang Anda).

Mengapa desimal, mengambang, dan int?

Tingkat presisi yang berbeda membutuhkan jumlah penyimpanan yang berbeda, dan tidak setiap penggunaan memerlukan tingkat presisi tertinggi. Misalnya, lihat di sini: https://docs.oracle.com/cd/B28359_01/server.111/b28286/sql_elements001.htm#SQLRF50950

Oracle memiliki cukup banyak jenis numerik yang berbeda dengan persyaratan penyimpanan yang berbeda dan kemampuan yang berbeda dalam hal tingkat presisi dan ukuran angka yang dapat diwakili.

FrustratedWithFormsDesigner
sumber
2

Dalam batas tertentu, ini historis.

Sekali waktu, data tabular disimpan dalam file yang terdiri dari catatan panjang tetap pada gilirannya terdiri dari bidang yang telah ditentukan sebelumnya sehingga bidang yang diberikan selalu dari jenis yang sama dan di tempat yang sama di setiap catatan. Ini membuat pemrosesan menjadi efisien dan membatasi kompleksitas pengkodean.

Tambahkan beberapa indeks ke file tersebut dan Anda memiliki awal dari database relasional.

Ketika database relasional berkembang, mereka mulai memperkenalkan lebih banyak tipe data dan opsi penyimpanan, termasuk teks panjang variabel atau bidang biner. Tapi, ini memperkenalkan catatan panjang variabel, dan memutus kemampuan untuk secara konsisten menemukan catatan melalui perhitungan atau bidang melalui offset tetap. Tidak masalah, mesin jauh lebih kuat hari ini daripada sebelumnya.

Kadang-kadang berguna untuk menetapkan ukuran tertentu untuk bidang untuk membantu menegakkan sedikit logika bisnis - katakanlah 10 digit untuk nomor telepon Amerika Utara. Sebagian besar waktu itu hanya sedikit warisan komputasi.

Zenilogix
sumber
1

Jika database menggunakan catatan berukuran tetap, catatan apa pun dalam database akan terus cocok, di lokasi yang sama, bahkan jika isinya diubah. Sebaliknya, jika database mencoba untuk menyimpan catatan menggunakan persis jumlah penyimpanan yang diperlukan untuk bidang mereka, mengubah nama Emma Smith menjadi Emma Johnson dapat menyebabkan catatannya terlalu besar untuk muat di lokasi yang sekarang. Jika catatan dipindahkan ke suatu tempat dengan ruang yang cukup, indeks apa pun yang melacak di mana ia perlu diperbarui untuk mencerminkan lokasi baru.

Ada berbagai cara untuk mengurangi biaya yang terkait dengan pembaruan tersebut. Misalnya, jika sistem menyimpan daftar nomor rekaman dan lokasi data, daftar itu akan menjadi satu-satunya hal yang perlu diperbarui jika catatan bergerak. Sayangnya, pendekatan semacam itu masih memiliki biaya yang signifikan (mis. Menjaga pemetaan antara jumlah rekaman dan lokasi akan membutuhkan pengambilan rekaman akan memerlukan langkah tambahan untuk mengambil data yang terkait dengan nomor rekaman yang diberikan). Menggunakan catatan berukuran tetap mungkin tampak tidak efisien, tetapi ini membuat banyak hal lebih sederhana.

supercat
sumber
1

Untuk banyak hal yang Anda lakukan sebagai pengembang web, tidak perlu memahami apa yang terjadi "di bawah tenda". Namun ada kalanya itu membantu.

Apa manfaatnya memberi tahu basis data "Hanya akan ada 256 byte data teks biasa dalam entri ke kolom ini." atau "Kolom ini dapat memiliki entri teks hingga 16.777.215 byte"?

Seperti yang Anda duga, alasannya adalah berkaitan dengan efisiensi. Abstraksi bocor . Permintaan seperti SELECT author FROM booksdapat berjalan cukup cepat ketika ukuran semua bidang dalam tabel diketahui.

Seperti yang dikatakan Joel,

Bagaimana implementasi database relasional SELECT author FROM books? Dalam database relasional, setiap baris dalam sebuah tabel (misalnya tabel buku) sama persis dengan panjang dalam byte, dan setiap bidang selalu pada offset tetap dari awal baris. Jadi, misalnya, jika setiap catatan dalam tabel buku panjangnya 100 byte, dan bidang penulis di offset 23, maka ada penulis yang disimpan di byte 23, 123, 223, 323, dll. Apa kode untuk pindah ke catatan berikutnya dalam hasil permintaan ini? Pada dasarnya, ini:

pointer += 100;

Satu instruksi CPU. Faaaaaaaaaast.

Banyak waktu, Anda bekerja cukup jauh dari dasar-dasar seluk beluk bahwa Anda tidak perlu peduli tentang hal itu. Sebagai pengembang web berbasis PHP, apakah Anda peduli tentang berapa banyak instruksi CPU yang digunakan kode Anda? Sebagian besar waktu, tidak, tidak juga. Tapi kadang-kadang berguna untuk mengetahui, karena dua alasan: itu bisa menjelaskan keputusan yang dibuat oleh perpustakaan Anda; dan kadang-kadang Anda perlu peduli tentang kecepatan dalam kode Anda sendiri.

Trigonometri
sumber