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

Apa cara merancang database relasional guru-mata pelajaran-siswa-batch sederhana?

Anda melewatkan tabel yang mengaitkan mata pelajaran dan siswa (per poin 2):

// student [student_id] takes subject [subject_id]
takes(student_id, subject_id)

Perhatikan bahwa setiap tabel dasar memiliki template pernyataan terkait untuk pernyataan tentang situasi bisnis, yang diparameterisasi oleh nama kolom--predikat (karakteristik) . Baris yang membuat predikat benar masuk ke dalam tabel. Perhatikan bahwa definisi tabel terlihat seperti singkatan dari predikat.

// teacher [id] named [name] with email [email] teaches subject [subject_id]
teacher(id, name, email, subject_id)

// subject [id] named [name] is [description]
subject(id, name, description)

// student [id] named [name] lives at [location])
student(id, name, location)

// batch [id] at venue [venue] was taught by teacher [teacher_id] on date [date]
batch(id, venue, teacher_id, date)

// student-batch [id] reports student [student_id] being in batch [batch_id]
student-batch(id, student_id, batch_id)
// CHECK student [student_id] takes the subject that is taught by the teacher of batch [batch_id]

Karena Anda tampak bingung tentang ini, saya akan menurunkannya dalam hal bagaimana kita dapat beralasan untuk tabel, batasan, dan desain kueri. Salah satu cara untuk mengekspresikan batasan yang Anda inginkan adalah dengan PERIKSA yang dikomentari di atas.

Untuk mengekspresikan tabel, batasan, atau kueri apa pun dalam SQL, pertama-tama kita tentukan predikatnya. Kemudian kita dapat mengubah predikat menjadi singkatan. Kemudian kita dapat mengonversi steno ke SQL.

Predikat:

student [student_id] takes the subject that is taught by the teacher of batch [batch_id]

Menggunakan predikat tabel dasar:

FOR SOME k.*, t.*, b.* (
    student_id = k.student_id AND batch_id = b.bid
AND student [k.student_id] takes subject [k.subject_id]
AND teacher [t.id] named [t.name] with email [t.email] teaches subject [t.subject_id] 
AND batch [b.id] at venue [b.venue] was taught by teacher [b.teacher_id] on date [b.date]
AND [k.subject_id] = [t.subject_id]
AND [t.id] = [b.teacher_id])

Menggunakan singkatan:

FOR SOME k.*, t.*, b.* (
    student_id = k.student_id AND batch_id = b.bid
AND takes(k.student_id, k.subject_id)
AND teacher(t.id, t.name, t.email, t.subject_id)
AND batch(b.id, b.venue, b.teacher_id, date)
AND k.subject_id = t.subject_id
AND t.id = b.teacher_id)

Dalam FROM setiap (mungkin implisit) alias mewakili tabel seperti nama tabel dasar yang diberikan dan/atau subquery tetapi dengan setiap kolom dalam nilai &predikatnya diganti namanya menjadi alias .kolom .

Kami mendapatkan baris yang memenuhi AND dari dua predikat dengan MENGGABUNGKAN tabel predikat dalam SQL. Jika kita ingin baris memenuhi AND dari suatu kondisi maka kita menggunakan ON atau WHERE dalam SQL.

Klausa SELECT mengembalikan baris di mana UNTUK BEBERAPA nilai kolom titik-titik, kolom yang dikembalikan (tanpa titik) sama dengan fungsi kolom titik-titik yang memenuhi predikat FROM.

SQL:Ganti pernyataan dengan tabelnya, AND dengan JOIN atau ON atau WHERE, dan outer FOR BEBERAPA &ADA ADA dengan SELECT:

SELECT t.student_id AS student_id, b.bid AS batch_id
FROM takes k JOIN teacher t JOIN batch b
WHERE k.subject_id = t.subject_id
AND t.id = b.teacher_id
AND student_id = t.student_id
AND batch_id = b.id

Tabel baris yang memenuhi OR dari dua predikat adalah UNION tabelnya. Untuk AND NOT kami menggunakan KECUALI (alias MINUS) (atau idiom LEFT JOIN). UNTUK BEBERAPA atau ADA ADA di semua kolom tidak dapat dikueri dalam SQL, tetapi jika kita ingin mengetahui apakah ada baris yang memenuhi predikat maka kita dapat menggunakan ADA di sekitar subkueri dengan predikat itu.

Misalkan kita ingin membatasi tabel dasar sehingga setiap baris memenuhi predikat pada beberapa kolom. Yaitu UNTUK SEMUA kolom JIKA mereka memenuhi predikat dasar MAKA mereka memenuhi predikat kueri. Yaitu UNTUK SEMUA kolom JIKA baris yang mereka bentuk ada di dasar MAKA itu ada di kueri. Jadi kami membutuhkan dalam SQL yang TIDAK ADA (PILIH kolom DARI basis KECUALI kueri). Atau untuk setiap baris di basis yang kita butuhkan dalam SQL yang ADA(query).

Dalam SQL Standar Anda dapat MENCIPTAKAN PERIKSA ASSERSI(TIDAK ADA (PILIH student_id, batch_id FROM student-batch KECUALI query)) atau dalam CREATE TABLE student-batch Anda bisa CHECK(EXISTS(query)). Sayangnya ini tidak didukung oleh MySQL atau kebanyakan DBMS. Jika Anda INSERT ke batch siswa setelah batch maka Anda dapat meminta pemicu yang ADA (permintaan). Atau Anda dapat menambahkan batasan kolom &komposit FK (foreign key) tertentu.

Sekarang kami sedang menulis kueri. Kami ingin baris di mana:

FOR k.*, t.*, b.*, s.*, sb.* (
    batch = b.id AND teacher = t.name AND student = s.name
AND takes(k.student_id, k.subject_id)
AND teacher(t.id, t.name, t.email, t.subject_id)
AND batch(b.id, b.venue, b.teacher_id, b.date)
AND student(s.id, s.name, s.location)
AND student-batch(sb.id, sb.student_id, sb.batch_id)
AND k.subject_id = t.subject_id
AND t.id = b.teacher_id
AND s.id = k.student_id
AND sb.student_id = k.student_id
AND sb.batch_id = b.id
AND @date = b.date)

Ini terlihat seperti predikat kendala dengan kolom kembali yang berbeda dan baris yang ditambahkan. SQL juga diterjemahkan secara langsung. Kami menambahkan bergabung dengan siswa untuk mendapatkan nama siswa. Kami menambahkan gabungan dengan siswa-batch karena kendala tidak menanganinya; konteks menggunakan kueri kendala memeriksa apakah siswa-batch (student_id, batch_id) subrows ada di dalamnya.

SELECT b.id AS batch, t.name AS teacher, s.name AS student
FROM takes k JOIN teacher t JOIN batch b JOIN student s JOIN student-batch sb
WHERE ... AND @date = date

Anda dapat mencoba versi AKTIF:

SELECT b.id AS Batch, t.name AS Teacher, s.name AS Student
FROM takes k
JOIN teacher t ON k.subject_id = t.subject_id
JOIN batch b ON t.id = b.teacher_id
JOIN ...
WHERE @date = b.date



  1. Database
  2.   
  3. Mysql
  4.   
  5. Oracle
  6.   
  7. Sqlserver
  8.   
  9. PostgreSQL
  10.   
  11. Access
  12.   
  13. SQLite
  14.   
  15. MariaDB
  1. MySQL:mengisi bidang kosong dengan nol saat menggunakan GROUP BY

  2. bagaimana cara mengulang dari terminal tanpa permintaan kata sandi yang berlebihan?

  3. Ubah gabungan kueri mentah menjadi laravel Eloquent

  4. Apa arti dari karakter kutipan aksen kuburan (AKA backtick) di MySQL?

  5. PHP PDO::lastInsertId() mengembalikan 0