Character vs Integer primary key

30

Saya merancang database dengan beberapa tabel pencarian yang berisi atribut yang mungkin dari entitas utama. Saya sedang berpikir untuk menggunakan kunci 4 atau 5 karakter untuk mengidentifikasi nilai-nilai pencarian ini daripada bilangan bulat peningkatan otomatis sehingga ketika saya menyimpan ID atribut ini pada tabel utama saya akan melihat nilai-nilai yang bermakna daripada hanya angka acak.

Apa implikasi kinerja menggunakan bidang karakter sebagai kunci utama daripada bilangan bulat?

Saya menggunakan MySQL jika itu penting.

[Sunting]
Tabel pencarian ini memiliki catatan baru yang ditambahkan jarang. Mereka dipelihara secara manual, dan tombol berbasis karakter juga dibuat secara manual. Ini sebuah contoh:

      CUISINES
 ID      Description
-----  --------------
CHNSE  Chinese
ITALN  Italian
MXICN  Mexican
BenV
sumber

Jawaban:

22

Itu tergantung pada mesin Anda. Kebijaksanaan umum adalah bahwa membaca itu murah, beberapa byte di sana-sini tidak akan secara signifikan mempengaruhi kinerja database ukuran kecil hingga menengah.

Lebih penting lagi, itu tergantung pada kegunaan mana Anda akan meletakkan kunci primer. Serial integer memiliki keuntungan karena mudah digunakan dan diimplementasikan. Mereka juga, tergantung pada implementasi spesifik dari metode serialisasi, memiliki keuntungan dengan cepat diturunkan, karena kebanyakan database hanya menyimpan nomor seri di lokasi yang tetap, daripada menurunkannya dengan Select max(ID)+1 from foocepat.

Pertanyaannya menjadi: bagaimana kunci 5 karakter menyajikan "nilai yang berarti" bagi Anda dan aplikasi? Bagaimana nilai ini dibuat, dan apakah perlu waktu lebih banyak atau lebih sedikit daripada menemukan nomor seri yang bertambah. Meskipun ada sejumlah kecil ruang yang dihemat dalam beberapa bilangan bulat, sebagian besar sistem akan mengabaikan penghematan ruang ini.

Tidak ada implikasi kinerja, kecuali bahwa skema karakter mensyaratkan bahwa tidak pernah ada mesin otomatis, karena "kunci" Anda tidak dapat diubah. Untuk domain spesifik Anda, jangan repot-repot dengan kunci buatan, dan cukup gunakan bahasa Cina, Jepang dan Thailand sebagai nama kunci. Meskipun Anda tidak dapat menjamin keunikan atas aplikasi apa pun yang mungkin, dalam lingkup Anda, jauh lebih masuk akal untuk menggunakannya daripada singkatan 5 karakter yang mengerikan dan dipaksakan. Tidak ada dampak kinerja yang signifikan hingga Anda mendapatkan jutaan tupel.

Atau, jika Anda hanya melacak berdasarkan negara asal, dan bukan masakan daerah tertentu (Kanton, Sichuan, Sisilia, Umbria, Calabrian, Yucatecan, Oaxacan, dll.), Anda selalu dapat menggunakan kode ISO 3166 saja .

Jika saya memiliki 10.000 resep, apakah perbedaan antara kunci 5 karakter dan 20 karakter mulai bertambah?

Ruang murah . Ketika Anda berbicara tentang 10.000.000 resep yang sedang Anda lakukan operasi OLAP, mungkin. Dengan resep 10k, Anda melihat ruang 150k.

Tetapi sekali lagi, itu tergantung. Jika Anda memiliki jutaan rekaman, dan melakukan penggabungan padanya, maka masuk akal untuk mendenormalkan pencarian untuk sesuatu yang sepele ini (ke tampilan yang terwujud). Untuk semua tujuan praktis, efisiensi gabungan relatif pada mesin modern antara kunci 5 karakter dan kunci panjang variabel sangat mirip dengan yang identik. Untungnya, kita hidup di dunia CPU yang berlimpah dan cakram yang berlimpah. Yang jahat adalah terlalu banyak gabungan dan kueri inefisiensi, daripada perbandingan karakter-per-karakter. Dengan itu, selalu tes .

Hal-hal P&T pada tingkat ini sangat bergantung pada basis data sehingga generalisasi sangat sulit. Bangun dua model sampel dari basis data, isi dengan perkiraan jumlah catatan, lalu lihat mana yang lebih cepat. Dalam pengalaman saya, panjang karakter tidak membuat perbedaan besar dibandingkan dengan indeks yang baik, konfigurasi memori yang baik, dan elemen penyetelan kinerja kritis lainnya.

Brian Ballsun-Stanton
sumber
@ BrianBallsun-Stanton jika Anda memiliki data sekuensial besar yang terkait dengan tabel pencarian ini, ruang penyimpanan tidak murah (dalam hal kecepatan permintaan) karena kecepatan baca disk adalah hambatan dalam RDB yang tidak dapat di-cache sepenuhnya dalam RAM. Saya menemukan ini ketika mencoba mengembangkan skema RDB yang dapat bersaing dengan yang terbaik dalam seri waktu pengungkapan bisnis penuh DB , saya tidak memiliki hubungan dengan Skyspark, kecuali bahwa mereka membebani majikan saya banyak untuk menggunakan DB mereka yang sangat efisien.
hobs
8

Saya pikir, tidak ada masalah dengan kinerja untuk tabel yang jarang berubah. Mungkin Anda akan memiliki masalah dengan desain di masa depan. Saya menyarankan Anda untuk tidak menggunakan data bisnis sebagai kunci utama karena perubahan bisnis. Gunakan kunci utama tambahan apa saja untuk tabel "tautan" dalam model Anda. Setiap perubahan bisnis TIDAK akan berdampak pada terkait dengan tabel yang satu ini.

garik
sumber
3

Pertanyaan sebenarnya adalah apakah kinerja permintaan DB sama sekali signifikan untuk aplikasi Anda (ukuran data). Jika kueri Anda menggunakan mikrodetik, menyimpan beberapa mikrodetik tersebut dengan menggunakan Intkunci tidak sebanding dengan hukuman keterbacaan / pemeliharaan. Namun, jika kueri Anda membutuhkan waktu beberapa menit, maka menghemat beberapa menit itu mungkin sepadan dengan rasa sakit Intkunci.

Di bawah ini adalah mengapa saya pikir bilangan bulat dapat menghemat waktu kueri Anda (sebagai persentase dari keseluruhan waktu kueri Anda), tetapi pendiri SkySpark dapat menjelaskannya lebih baik daripada saya . Pengungkapan penuh, majikan saya membayar SkySpark banyak uang untuk menggunakan DB mereka dan saya mencoba untuk membangun sesuatu yang lebih baik / lebih cepat.

Jika Anda memiliki banyak data sekuensial (file log, seri waktu, analitik, teks atau pidato korpora) yang memiliki tautan (hubungan) ke salah satu tabel pencarian Anda, Anda akan menemukan bahwa ruang penyimpanan sangat penting untuk kecepatan permintaan, meskipun @ Analisis Ballsun-Stanton yang benar tentang seberapa murah ruang dalam $. Karena sebagian besar waktu kueri (untuk data berurutan) dihabiskan untuk membaca disk, ruang tidak murah dalam hal waktu (sebagai persen dari keseluruhan waktu kueri). Jadi, kecuali RDB Anda secara otomatis dan efisien mengompresi / mendekompres semua kunci asing (kunci ke catatan terkait), Anda ingin semua kunci Anda menjadi Int, yang paling efisien dalam hal ruang disk (dan kecepatan baca) per unit informasi konten (entropi). FYI MyISAM di MySql memberlakukan batasanpada apa yang dapat Anda lakukan dengan baris data terkompresi (hanya baca). Dengan kata lain, bilangan bulat yang bertambah secara otomatis sudah dikompresi sebanyak mungkin secara teoritis , mengingat batasan ukuran minimum yang rendah pada sebagian besar bidang bilangan bulat DB. Dan kompresi itu datang tanpa:

  1. hukuman kompresi / dekompresi permintaan waktu
  2. disk baca-waktu hukuman baca
  3. read-only atau pembatasan DB lainnya pada catatan data atau kunci terkompresi

Ada alasan mengapa ORM populer dan efisien seperti Django default untuk bilangan bulat peningkatan otomatis untuk PK dan mengapa pertanyaan SO lainnya sampai pada kesimpulan yang sama.

hobs
sumber