Mysql
 sql >> Teknologi Basis Data >  >> RDS >> Mysql

Skema basis data untuk Buku, Penulis, Penerbit, dan Pengguna dengan rak buku

Anda memerlukan tautan N:M di antara books dan authors , karena sebuah buku mungkin memiliki beberapa penulis dan setiap penulis mungkin telah menulis lebih dari satu buku. Dalam RDBMS itu berarti Anda memerlukan written_by tabel.

Tautan antara books dan publishers namun berbeda. Buku apa pun hanya dapat memiliki satu penerbit (kecuali di sistem Anda, edisi buku yang berbeda dianggap sebagai buku yang sama). Jadi yang Anda butuhkan di sini adalah publisher_id kunci asing di books

Terakhir, dan yang paling penting Anda melihat pembaca/pengguna. Dan hubungannya dengan buku. Secara alami, ini juga merupakan relasi N:M. Saya sangat berharap bahwa orang membaca lebih dari satu buku (kita semua tahu apa yang terjadi jika Anda hanya membaca satu...) dan tentunya sebuah buku dibaca oleh lebih dari satu orang. Itu membutuhkan book_users meja koneksi. Pertanyaan sebenarnya di sini adalah, bagaimana merancangnya. Ada tiga desain dasar.

  1. Pisahkan tabel menurut jenis relasi . (seperti yang digariskan oleh @just_somebody ) Keuntungan:Anda hanya memiliki INSERTS dan DELETES, tidak pernah UPDATES. Meskipun ini terlihat rapi, dan agak membantu pengoptimalan kueri, sebagian besar waktu ini tidak memiliki tujuan sebenarnya selain memamerkan bagan basis data yang besar.

  2. Satu tabel dengan status indikator . (seperti yang digariskan oleh @Hardcoded) Keuntungan:Anda hanya memiliki satu tabel. Kekurangan:Anda akan memiliki INSERTS, UPDATES, dan DELETES - sesuatu yang dapat dengan mudah ditangani oleh RDBMS, tetapi memiliki kekurangan karena berbagai alasan (lebih lanjut tentang itu nanti) Juga, satu status bidang menyiratkan bahwa satu pembaca hanya dapat memiliki satu koneksi ke buku setiap saat, artinya dia hanya bisa berada di plan_to_read , is_reading atau has_read status pada setiap titik waktu, dan mengasumsikan urutan waktu ini terjadi. Jika orang itu berencana untuk membacanya lagi , atau jeda, lalu baca ulang dari awal dll, rangkaian indikator status yang begitu sederhana dapat dengan mudah gagal, karena tiba-tiba orang tersebut is_reading sekarang, tetapi juga has_read hal. Untuk sebagian besar aplikasi, ini masih merupakan pendekatan yang masuk akal, dan biasanya ada cara untuk mendesain bidang status sehingga keduanya saling eksklusif.

  3. Sebuah log . Anda MASUKKAN setiap status sebagai baris baru dalam tabel - kombinasi buku dan pembaca yang sama akan muncul lebih dari sekali. Anda INSERT baris pertama dengan plan_to_read , dan stempel waktu. Satu lagi dengan is_reading . Kemudian satu lagi dengan has_read . Keuntungan:Anda hanya perlu INSERT baris, dan Anda mendapatkan kronologi yang rapi dari hal-hal yang terjadi. Kekurangan:Penggabungan tabel silang sekarang harus menangani lebih banyak data (dan lebih kompleks) daripada pendekatan yang lebih sederhana di atas.

Anda mungkin bertanya pada diri sendiri, mengapa ada penekanan pada apakah Anda INSERT, UPDATE atau DELETE dalam skenario apa? Singkatnya, setiap kali Anda menjalankan pernyataan UPDATE atau DELETE, kemungkinan besar Anda sebenarnya kalah data. Pada saat itu Anda perlu berhenti dalam proses desain Anda dan berpikir "Apa yang saya hilangkan di sini?" Dalam hal ini, Anda kehilangan urutan kronologis peristiwa. Jika apa yang dilakukan pengguna dengan buku mereka adalah pusat dari aplikasi Anda, Anda mungkin ingin mengumpulkan data sebanyak mungkin. Bahkan jika itu tidak penting sekarang, itu adalah jenis data yang memungkinkan Anda untuk melakukan "keajaiban" di kemudian hari. Anda dapat mengetahui seberapa cepat seseorang membaca, berapa banyak upaya yang mereka butuhkan untuk menyelesaikan sebuah buku, dll. Semua itu tanpa meminta masukan tambahan dari pengguna.

Jadi, jawaban terakhir saya sebenarnya adalah sebuah pertanyaan:

Sunting

Karena mungkin tidak jelas seperti apa log itu, dan bagaimana fungsinya, berikut adalah contoh tabelnya:

CREATE TABLE users_reading_log (
  user_id INT,
  book_id INT,
  status ENUM('plans_to_read', 'is_reading', 'has_read'),
  ts TIMESTAMP DEFAULT NOW()
)

Sekarang, alih-alih memperbarui tabel "user_read" dalam skema yang Anda rancang setiap kali status buku berubah, Anda sekarang MASUKKAN data yang sama di log yang sekarang diisi dengan kronologi informasi:

INSERT INTO users_reading_log SET 
  user_id=1,
  book_id=1,
  status='plans_to_read';

Ketika orang itu benar-benar mulai membaca, Anda melakukan penyisipan lagi:

INSERT INTO users_reading_log SET 
  user_id=1,
  book_id=1,
  status='is_reading';

dan seterusnya. Sekarang Anda memiliki database "peristiwa" dan karena kolom stempel waktu secara otomatis terisi sendiri, Anda sekarang dapat mengetahui apa yang terjadi kapan. Harap perhatikan bahwa sistem ini tidak memastikan bahwa hanya ada satu 'is_reading' untuk pasangan buku pengguna tertentu. Seseorang mungkin berhenti membaca dan kemudian melanjutkan. Gabung Anda harus memperhitungkan itu.



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. Bisakah saya menggunakan banyak pernyataan dalam kueri yang disiapkan JDBC?

  2. PHP password_verify tidak bekerja melawan database

  3. Memasukkan kode html dalam tabel mysql

  4. Bagaimana cara menghindari kutipan tunggal dalam string literal menggunakan MySQL dari Java

  5. Pilih N *grup* pertama menggunakan mysql