Saya menyimpan berbagai detail pengguna di database MySQL saya. Awalnya itu diatur dalam berbagai tabel yang berarti data dihubungkan dengan UserIds dan dikeluarkan melalui panggilan yang terkadang rumit untuk menampilkan dan memanipulasi data sesuai kebutuhan. Menyiapkan sistem baru, hampir masuk akal untuk menggabungkan semua tabel ini menjadi satu tabel besar konten terkait.
- Apakah ini akan menjadi bantuan atau penghalang?
- Pertimbangan kecepatan dalam menelepon, memperbarui, atau mencari / memanipulasi?
Berikut adalah contoh dari beberapa struktur tabel saya:
- pengguna - UserId, nama pengguna, email, kata sandi terenkripsi, tanggal pendaftaran, ip
- user_details - data cookie, nama, alamat, detail kontak, afiliasi, data demografis
- user_activity - kontribusi, terakhir online, terakhir dilihat
- user_settings - pengaturan tampilan profil
- user_interests - mengiklankan variabel yang dapat ditargetkan
- user_levels - hak akses
- user_stats - klik, penghitungan
Sunting: Sejauh ini saya telah memilih semua jawaban, semuanya memiliki elemen yang pada dasarnya menjawab pertanyaan saya.
Sebagian besar tabel memiliki hubungan 1: 1 yang merupakan alasan utama untuk melakukan denormalisasi.
Apakah akan ada masalah jika tabel mencakup lebih dari 100 kolom ketika sebagian besar sel ini cenderung tetap kosong?
sumber
Jawaban:
Beberapa tabel membantu dalam cara / kasus berikut:
(a) jika orang yang berbeda akan mengembangkan aplikasi yang melibatkan tabel yang berbeda, masuk akal untuk membaginya.
(b) Jika Anda ingin memberikan jenis otoritas yang berbeda kepada orang yang berbeda untuk bagian pengumpulan data yang berbeda, mungkin lebih mudah untuk memisahkannya. (Tentu saja, Anda dapat melihat cara menentukan pandangan dan memberikan otorisasi pada pandangan tersebut dengan tepat).
(c) Untuk memindahkan data ke tempat yang berbeda, terutama selama pengembangan, mungkin masuk akal untuk menggunakan tabel yang menghasilkan ukuran file yang lebih kecil.
(d) Jejak kaki yang lebih kecil dapat memberikan kenyamanan saat Anda mengembangkan aplikasi pada pengumpulan data spesifik dari satu entitas.
(e) Ini adalah kemungkinan: apa yang Anda pikir sebagai data nilai tunggal dapat berubah menjadi nilai ganda di masa depan. misalnya batas kredit adalah bidang nilai tunggal seperti sekarang. Tetapi besok, Anda dapat memutuskan untuk mengubah nilai sebagai (tanggal dari, tanggal ke, nilai kredit). Tabel terpisah mungkin berguna sekarang.
Pilihan saya adalah untuk beberapa tabel - dengan data yang dibagi dengan tepat.
Semoga berhasil.
sumber
Menggabungkan tabel disebut denormalisasi.
Ini mungkin (atau mungkin tidak) membantu untuk membuat beberapa pertanyaan (yang membuat banyak
JOIN
) untuk berjalan lebih cepat dengan mengorbankan menciptakan neraka pemeliharaan.MySQL
hanya mampu menggunakanJOIN
metode, yaituNESTED LOOPS
.Ini berarti bahwa untuk setiap catatan dalam tabel penggerak,
MySQL
menempatkan catatan yang cocok di tabel didorong dalam satu lingkaran.Menemukan catatan adalah operasi yang cukup mahal yang mungkin memakan waktu puluhan kali selama pemindaian catatan murni.
Memindahkan semua catatan Anda ke dalam satu tabel akan membantu Anda menyingkirkan operasi ini, tetapi tabel itu sendiri bertambah besar, dan pemindaian tabel membutuhkan waktu lebih lama.
Jika Anda memiliki banyak catatan di tabel lain, maka peningkatan dalam pemindaian tabel dapat membebani keuntungan dari catatan yang dipindai secara berurutan.
Neraka pemeliharaan, di sisi lain, dijamin.
sumber
Apakah semuanya berhubungan 1: 1? Maksud saya, jika pengguna dapat menjadi bagian, katakanlah, tingkat pengguna yang berbeda, atau jika minat pengguna direpresentasikan sebagai beberapa rekaman dalam tabel minat pengguna, maka menggabungkan tabel tersebut akan segera keluar dari pertanyaan.
Mengenai jawaban sebelumnya tentang normalisasi, harus dikatakan bahwa aturan normalisasi database telah sepenuhnya mengabaikan kinerja, dan hanya melihat apa itu desain database yang rapi. Seringkali itulah yang ingin Anda capai, tetapi ada kalanya masuk akal untuk melakukan denormalisasi secara aktif untuk mengejar kinerja.
Secara keseluruhan, saya akan mengatakan pertanyaannya adalah berapa banyak bidang yang ada di tabel, dan seberapa sering mereka diakses. Jika aktivitas pengguna sering kali tidak terlalu menarik, mungkin akan merepotkan untuk selalu menyimpannya pada catatan yang sama, karena alasan kinerja dan pemeliharaan. Jika beberapa data, seperti pengaturan, misalnya, sangat sering diakses, tetapi berisi terlalu banyak bidang, mungkin juga tidak nyaman untuk menggabungkan tabel. Jika Anda hanya tertarik pada perolehan kinerja, Anda dapat mempertimbangkan pendekatan lain, seperti menjaga pengaturan tetap terpisah, tetapi menyimpannya dalam variabel sesi sendiri sehingga Anda tidak perlu sering menanyakan database untuk mereka.
sumber
3NF
normalisasi, jadi manfaatkan tabel kedua untuk menyelesaikannya, tetapi tampaknya bukan itu yang dimaksud OP untuk tabel lainnya.)Apakah semua tabel tersebut memiliki
1-to-1
hubungan? Misalnya, akankah setiap baris pengguna hanya memiliki satu baris yang sesuai diuser_stats
atauuser_levels
? Jika demikian, mungkin masuk akal untuk menggabungkannya menjadi satu tabel. Jika hubungannya tidak demikian1 to 1
, mungkin tidak masuk akal untuk menggabungkan (mendenormalisasi) keduanya.Memiliki mereka dalam tabel terpisah vs. satu tabel mungkin akan berdampak kecil pada kinerja kecuali jika Anda memiliki ratusan ribu atau jutaan catatan pengguna. Satu-satunya keuntungan nyata yang akan Anda dapatkan adalah dari menyederhanakan kueri Anda dengan menggabungkannya.
ETA:
Jika kekhawatiran Anda tentang memiliki terlalu banyak kolom , pikirkan tentang hal-hal apa yang biasanya Anda gunakan bersama dan gabungkan semuanya , tinggalkan sisanya dalam tabel terpisah (atau beberapa tabel terpisah jika diperlukan).
Jika Anda melihat cara Anda menggunakan data, perkiraan saya adalah Anda akan menemukan bahwa sekitar 80% kueri Anda menggunakan 20% dari data itu dengan 80% sisanya hanya digunakan sesekali. Gabungkan 20% yang sering digunakan ke dalam satu tabel, dan biarkan 80% yang tidak sering Anda gunakan di tabel terpisah dan Anda mungkin akan mendapatkan kompromi yang baik.
sumber
Membuat satu tabel besar bertentangan dengan prinsip basis data relasional. Saya tidak akan menggabungkan semuanya menjadi satu tabel. Anda akan mendapatkan banyak contoh data berulang. Jika pengguna Anda memiliki tiga minat misalnya, Anda akan memiliki 3 baris, dengan data pengguna yang sama hanya untuk menyimpan tiga kepentingan yang berbeda. Pasti pergi untuk beberapa pendekatan tabel 'dinormalisasi'. Lihat halaman Wiki ini untuk normalisasi database.
Sunting: Saya telah memperbarui jawaban saya, karena Anda telah memperbarui pertanyaan Anda ... Saya setuju dengan jawaban awal saya bahkan lebih sekarang sejak ...
Jika misalnya, pengguna tidak memiliki minat apa pun, jika Anda menormalkannya maka Anda tidak akan memiliki baris dalam tabel minat untuk pengguna itu. Jika Anda memiliki semuanya dalam satu tabel besar, maka Anda akan memiliki kolom (dan tampaknya banyak dari mereka) yang hanya berisi NULL.
Saya telah bekerja untuk perusahaan telepon yang memiliki banyak tabel, mendapatkan data dapat memerlukan banyak penggabungan. Ketika kinerja membaca dari tabel-tabel ini sangat penting, maka prosedur yang dibuat dapat menghasilkan tabel datar (yaitu tabel yang didenormalisasi) yang tidak memerlukan penggabungan, penghitungan, dll. Yang dapat ditunjukkan oleh laporan. Ini di mana kemudian digunakan bersama dengan agen server SQL untuk menjalankan pekerjaan pada interval tertentu (yaitu tampilan mingguan beberapa statistik akan dijalankan seminggu sekali dan seterusnya).
sumber
Mengapa tidak menggunakan pendekatan yang sama yang dilakukan Wordpress dengan memiliki tabel pengguna dengan informasi pengguna dasar yang dimiliki setiap orang dan kemudian menambahkan tabel "user_meta" yang pada dasarnya dapat berupa kunci, pasangan nilai yang terkait dengan id pengguna. Jadi jika Anda perlu menemukan semua informasi meta untuk pengguna, Anda bisa menambahkannya ke kueri Anda. Anda juga tidak selalu harus menambahkan kueri tambahan jika tidak diperlukan untuk hal-hal seperti masuk. Manfaat pendekatan ini juga membuat tabel Anda terbuka untuk menambahkan fitur baru kepada pengguna Anda seperti menyimpan pegangan twitter mereka atau minat masing-masing individu. Anda juga tidak perlu berurusan dengan labirin ID terkait karena Anda memiliki satu tabel yang mengatur semua metadata dan Anda akan membatasinya hanya ke satu asosiasi, bukan 50.
Wordpress secara khusus melakukan ini untuk memungkinkan fitur ditambahkan melalui plugin, oleh karena itu memungkinkan proyek Anda menjadi lebih skalabel dan tidak memerlukan perbaikan database lengkap jika Anda perlu menambahkan fitur baru.
sumber
wp_usermeta
Tabel Wordpress tumbuh secara geometris. Setiap pengguna menambahkan baris X kewp_usermeta
tabel, satu baris untuk setiap bagian informasi meta yang ingin kami simpan untuk pengguna tersebut. Jika Anda menyimpan 8 bidang khusus untuk setiap pengguna, itu berarti wp_usermeta akan menjadiusers * 8
baris yang panjang. Tampaknya ini menyebabkan masalah kinerja, tapi saya tidak yakin apakah itu masalahnya atau bukan…get_users()
) hanya untuk menghitung pagination. Setelah kami mengoreksi kode agar menggunakanSELECT COUNT(…)
kueri untuk penomoran halaman, waktu buka halaman berubah dari 28 detik menjadi sekitar 400ms. Saya masih bertanya-tanya bagaimana kinerja dibandingkan dengan tabel yang digabungkan atau satu tabel datar… Saya kesulitan menemukan metrik kinerja apa pun di web.Saya pikir ini adalah salah satu situasi "itu tergantung". Memiliki banyak tabel lebih bersih dan mungkin secara teoritis lebih baik. Tetapi ketika Anda harus menggabungkan 6-7 tabel untuk mendapatkan informasi tentang satu pengguna, Anda mungkin mulai memikirkan kembali pendekatan itu.
sumber
Saya akan mengatakan itu tergantung pada apa arti sebenarnya dari tabel lain. Apakah sebuah user_details berisi lebih dari 1 lebih / users dan seterusnya. Level normalisasi apa yang paling sesuai untuk kebutuhan Anda bergantung pada permintaan Anda.
Jika Anda memiliki satu tabel dengan indeks yang bagus, itu mungkin akan lebih cepat. Namun di sisi lain mungkin perawatannya lebih sulit.
Bagi saya, sepertinya Anda bisa melewati User_Details karena mungkin ini adalah hubungan 1 banding 1 dengan Users. Tapi sisanya mungkin banyak baris per pengguna?
sumber