Nasihat tentang desain dasar, desain database pertama kali

8

Saya mengambil kursus untuk menjadi pengembang Java.

Kursus ini melibatkan penggunaan basis data, tetapi sayangnya kami tidak pernah mendesainnya.

Sebagian besar waktu kita mendapatkan basis data yang sudah dibuat sebelumnya dan kita harus menerapkan kode untuk memasukkan, memperbarui, membaca atau menghapus data.

Tetapi ketika tes akhir saya datang, kemungkinan saya akan membuat sesuatu yang melibatkan database dan karena itu saya ingin mencoba merancang beberapa yang lebih kecil untuk memahami desain karena saya perhatikan bahwa desain database yang baik membuat banyak perbedaan ketika menulis kode untuk bekerja dengannya.

Saya harap pertanyaan-pertanyaan semacam ini diperbolehkan di sini dan itu tidak akan terlalu luas.


Ini adalah desain kecil yang saya buat untuk sesuatu yang sederhana seperti clubsdan membersdengan addressesdan phonenumbers.

  • Akan ada beberapa klub.
  • Setiap klub akan memiliki banyak anggota (jelas)
  • Seorang anggota tidak dapat menjadi bagian dari banyak klub
  • Seorang anggota dapat memiliki beberapa nomor telepon dan alamat email
  • Seorang anggota hanya dapat memiliki satu alamat
  • Sebuah alamat dapat berasal dari anggota yang berbeda (pasangan atau saudara kandung)

Kebingungan terbesar saya:

  • Jika saya ingin menambahkan kolom Clubyang menggambarkan pemilik, yang juga akan menjadi anggota, apa pendekatan terbaik tanpa meminta anggota yang sama terdaftar dua kali?

  • Haruskah saya meletakkan semua tabel saya pada kenaikan otomatis id atau apakah ini ide yang buruk? (manfaat / kerugian?)

  • Jika saya menambahkan kunci asing di tab kunci asing, akankah ini secara otomatis sesuai dengan tabel yang benar atau apakah saya harus menambahkan ini ke kolom juga? (lihat gambar 2)

  • Dan pertanyaan noobiest saya mungkin sama sekali ... Apakah saya meletakkan kunci asing phonenumberdan emaildi tabel masing-masing yang terhubung ke person_Id atau haruskah saya memasukkan nomor telepon dan ID email di tabel orang?

(Maafkan saya karena bahasa dalam gambar ini bukan bahasa Inggris, saya harap ini tidak terlalu menjadi masalah)

Rancangan

Kunci asing

Vahx
sumber

Jawaban:

11

Tanggapan untuk pertanyaan pribadi Anda

Jika saya ingin menambahkan kolom Clubyang menggambarkan pemilik, yang juga akan menjadi anggota, apa pendekatan terbaik tanpa meminta anggota yang sama terdaftar dua kali?

Jika — sebagaimana dinyatakan dalam spesifikasi Anda— a Person can be a Member of only one Club, dan Anda tertarik untuk menyimpan datum ini hanya sebagai benar atau salah , satu opsi menambahkan kolom a BIT(1)atau BOOLEAN( TINYINT) ke Persontabel, dan Anda mungkin ingin memanggil kolom ini IsClubOwner. Dengan cara ini, Anda dapat mendaftarkan fakta bahwa orang yang ditentukan adalah pemilik klub secara eksklusif satu kali. Selain itu, metode ini juga memungkinkan kemungkinan mempertahankan beberapa orang sebagai pemilik klub yang sama . Anda dapat melihat gambaran level logis dari pendekatan ini pada Gambar 1 .

Namun, Anda mencari pendekatan terbaik dan, menurut pengalaman saya, pendekatan semacam itu memerlukan pengembangan struktur yang jauh lebih diperluas dan serbaguna. Dalam hal ini, ikuti perkembangan latihan pemodelan untuk poin-poin ini dan lainnya di bawah ini, di bagian berjudul "Meliputi spesifikasi Anda yang tersisa", "Orang sebagai Anggota dari banyak Klub" dan "Anggota dan Pemilik sebagai jenis entitas yang terpisah".

Haruskah saya meletakkan semua meja saya di selisih otomatis idatau apakah ini ide yang buruk? (manfaat / kerugian?)

Jika Anda menghadapi eksplisit persyaratan yang menunjukkan definisi tabel dengan kolom karakteristik tersebut, dan kolom yang memiliki makna kontekstual yang valid atau memiliki tujuan tertentu seperti menjadi pengganti untuk lebar PRIMARY KEY alami (PK), maka ya, Anda harus melanjutkan dengan cara itu.

Jika tidak, jika Anda tidak mengatakan persyaratan, saya menganggap itu akan unnecesary karena Anda harus menyimpan dan mengelola kolom tambahan berarti dan (mungkin?) Juga INDEX tambahan dalam database Anda.

Seperti biasa, Anda harus menganalisis setiap kasus beserta dampak keseluruhannya untuk memutuskan bagaimana melanjutkannya.

Jika saya menambahkan kunci asing di tab kunci asing, akankah ini secara otomatis sesuai dengan tabel yang benar atau apakah saya harus menambahkan ini ke kolom juga?

Dalam hal ini, saran saya untuk Anda adalah membuat struktur database Anda secara manual, untuk mengkode DDLpernyataan Anda sendiri sampai Anda mendapatkan pemahaman yang kuat tentang subjek. Jika Anda melakukannya, akan lebih mudah bagi Anda untuk memahami proses yang dilakukan alat grafis “di bawah tenda”.

Bagi saya, misalnya, membuat pernyataan seperti berikut:

CONSTRAINT FK_PersonPhoneNumber_to_Person FOREIGN KEY (PersonId)
REFERENCES Person (PersonId)

Jauh lebih instruktif daripada menggunakan alat GUI untuk menjalankan tugas semacam ini, terutama sekarang karena Anda sedang membangun desain pertama Anda.

Dan pertanyaan saya yang mungkin paling noobiest dari semua ... Apakah saya meletakkan kunci asing phone_numberdan emaildi meja masing-masing yang terhubung ke person_idatau haruskah saya letakkan phone_numberdan email idsdi meja orang?

Secara pribadi, saya pikir ini dan semua pertanyaan Anda yang lain benar - benar valid dan dikontekstualisasikan dengan baik .

Kembali ke aspek teknis yang menjadi perhatian kami, penyelidikan yang tepat ini menawarkan kesempatan yang baik untuk meninjau kembali dua pernyataan berikut:

  • A Person can be reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber can be used to reach one-to-many People

Jadi, orang dapat menyimpulkan bahwa ada banyak-ke-banyak hubungan antara Persondan PhoneNumber, oleh karena itu, saya menyarankan pembuatan tabel asosiatif yang dinamai PersonPhoneNumberuntuk mewakili hubungan tersebut dalam database Anda. PK dari tabel ini harus terdiri dari dua kolom berbeda: PersonId(a ASING KUNCI [FK] menunjuk ke Person.PersonId) dan PhoneNumber(sebuah FK yang membuat referensi ke PhoneNumber.Number). Untuk deskripsi level logis dari semua hal di atas, lihat Gambar 1 .

Di sisi lain, mari kita periksa dua proposisi berikut:

  • A Person can be contacted via zero-one-or-many EmailAddresses
  • An EmailAddress can be used to contact exactly one Person

Maka, ya, Anda harus menetapkan referensi FK Persondari EmailAddresstabel, dan tabel ini harus memiliki PK komposit juga, yang akan terdiri dari kolom PersonIddan Address. Dengan cara ini, Anda dapat memastikan bahwa kombinasi yang sama EmailAddress.PersonIddan EmailAddress.Addressdapat dimasukkan hanya sekali.

Jika Anda juga ingin memastikan bahwa yang diberikan EmailAddres.Addressdapat disimpan dalam satu baris tunggal, Anda hanya perlu membuat CONSTRAINT UNIK untuk kolom ini.

Model data logis yang diajukan

Untuk mengekspos saran saya lebih jelas, saya memasukkan empat model logis IDEF1X [1] yang ditunjukkan pada Gambar 1 , Gambar 2 , Gambar 3 dan Gambar 4 . Saya akan memberikan penjelasan tentang fitur yang paling relevan yang ditampilkan di masing-masing fitur tersebut di bagian yang sesuai. Anda juga dapat mengunduh dari Dropbox, PDF yang terintegrasi dalam model tunggal, sebagian besar elemen yang sedang dibahas.

Menutupi spesifikasi yang tersisa

Menghubungkan Orang dan Alamat

Mari kita periksa dua pernyataan berikut (sedikit ditulis ulang) yang relevan untuk orang dan alamat :

  • A Person can only have one Address
  • An Address can belong to different People (couples or siblings)

Jadi, untuk menghadapi pembatasan ini, Anda dapat memilih untuk mengimplementasikan model data yang mirip dengan yang dapat Anda lihat pada Gambar 1 .

Gbr. 1. Model Data Klub dan Anggota - Spesifikasi Pertama

Dengan mempertimbangkan model yang dimaksud, Anda harus mengikuti langkah-langkah berikut:

  1. Buat tabel yang disebut PersonAddressmemperbaiki hubungan antara Persondan Address. Atur kolom PersonIddan AddressIdsebagai senyawa PK dari tabel ini.

  2. Konfigurasikan KONSTRA UNIK untuk PersonAddress.PersonIdkolom untuk memastikan bahwa nilai tertentu dapat dimasukkan paling banyak pada satu baris tabel tersebut. Pada tingkat logis, keadaan ini menyiratkan bahwa PersonAddress.PersonIdtelah menjadi KUNCI ALTERNATE [2] .

  3. Jika nilai AddressIddalam PersonAddressupaya penyisipan yang ditentukan belum disimpan, maka biarkan penyisipan berlanjut, jika tidak, ketika nilai tersebut sudah ada dalam satu baris, Anda harus memeriksa bahwa (a) PersonIdsiapa yang telah terdaftar yang AddressIdjuga terdaftar sebagai Marriage.WifeIdjika itu PersonIdadalah laki-laki (datum berasal dari Person.GenreCode) atau (b) bahwa itu PersonIdadalah Marriage.HusbandIdketika PersonIdadalah perempuan (berasal berdasarkan Person.GenreCode, juga). Jika salah satu dari kondisi ini terpenuhi dalam situasi yang sesuai, maka Anda harus membiarkan INSERT berjalan.

  4. Jika kondisi di atas tidak terpenuhi, masih ada peluang untuk PersonAddresspenyisipan mencoba untuk berhasil. Anda harus memeriksa bahwa PersonIdnilai yang terlibat dalam penyisipan kata mencoba berbagi setidaknya satu Progeny.ParentIddengan PersonIdyang sudah terdaftar PersonAddress.AddressId. Jika kondisi ini terpenuhi, maka itu berarti mereka disimpan seperti Siblingsdalam database, jadi INSERT ini harus berhasil.

Seperti dalam implementasi basis data relasional, Anda harus secara serius mempertimbangkan untuk mengeksekusi DMLoperasi Anda di dalam Transaksi ACID sehingga Anda dapat melindungi integritas dan konsistensi data yang Anda kerjakan.

Menghadiri persyaratan yang Anda tambahkan dalam komentar: Alamat dan Nomor Telepon melayani Klub dan Orang yang sama

Dengan syarat Anda ingin memberikan kesempatan untuk alamat dan nomor telepon untuk melayani orang dan klub , Anda dapat menggunakan hubungan supertipe-subtipe . Berikut ini adalah jawaban di mana saya memberikan perawatan yang lebih rinci untuk struktur semacam ini, jika Anda tertarik.

Dalam skenario ini, Anda dapat mendefinisikan Persondan Clubsebagai subtipe dari entitas baru yang dinamai Party, istilah yang biasa digunakan dalam lingkaran hukum untuk membela (a) seseorang atau (b) sekelompok orang (sebagaimana disebutkan dalam pengertian nomor 6 ). Dengan metode ini, hubungan antara Addresses(atau PhoneNumbers) Peopledan Clubsakan ditentukan melalui Party, supertype. Lihat Gambar 2 untuk penggambaran saran ini.

Gbr. 2. Model Data Klub dan Anggota - Spesifikasi Kedua

Pesta dan Alamat

Jadi kita dapat membaca dalam model baru ini bahwa:

  • A Party keeps zero-one-or-many Addresses
  • An Address is kept by one-to-many Parties

Dengan demikian, ada banyak-ke-banyak hubungan yang melibatkan Partydan Addressyang diungkapkan melalui PartyAddressentitas.

Pesta dan Nomor Telepon

Selanjutnya, kita dapat menafsirkan bahwa:

  • A Party is reached through zero-one-or-many PhoneNumbers
  • A PhoneNumber is used by one-to-many Parties

Itulah sebabnya saya menambahkan PartyPhoneNumberentitas yang menggambarkan asosiasi banyak ke banyak yang berlaku antara jenis Partydan PhoneNumberentitas.

Pesta dan Klub atau Orang

Kemudian, dapat juga dibaca bahwa:

  • A Party is either a Club or a Person

Karenanya, Partymemasok koneksi dari salah satu Clubs atau People ke Addresses(atau PhoneNumbers).

Pribadi sebagai Anggota beberapa Klub

Seperti @aldwinaldwin menyebutkan dalam jawabannya, jika Anda ingin memberikan fungsionalitas bagi seseorang untuk menjadi anggota dari beberapa klub , maka Anda dapat menyertakan tabel yang disebut ClubMemberyang akan bertindak sebagai hubungan banyak-ke-banyak lainnya, kali ini, tentu saja , interkoneksi Persondan Club.

Saya akan menambahkan di atas bahwa tabel ini juga dapat berguna dalam tujuan menyimpan orang konkret sebagai pemilik beberapa klub , dengan cara memasukkan IsClubOwnerkolom boolean yang telah disebutkan . Bahkan, dapat dikatakan bahwa tabel baru ini adalah representasi dari tipe entitas integral dalam haknya sendiri.

Seperti ditunjukkan pada Gambar 3 , tabel tersebut membutuhkan PK komposit yang terdiri dari kolom ClubIddan MemberId( nama peran [3] diberikan kepada PersonId), dan kolom ini harus didefinisikan juga sebagai FK yang menunjuk, sesuai, ke Clubdan Person.

Gbr. 3. Model Data Klub dan Anggota - Orang sebagai Anggota Banyak Klub

Struktur yang lebih mudah beradaptasi

Dengan menggunakan pengaturan ini, Anda juga dapat mematuhi aturan awal yang menyatakan itu a Person can be a member of only one Club, tetapi Anda hanya perlu menambahkan CONSTRAINT UNIK ke MemberIdkolom, sehingga nilai tertentu dapat dimasukkan dalam tidak lebih dari satu kali. Jadi, seperti yang Anda perhatikan, struktur ini jauh lebih mudah beradaptasi bahwa yang ditunjukkan pada Gambar 1 , karena dengan menjatuhkan UNIK CONSTRAINT (atau INDEX) Anda akan membuka fungsi tersebut perijinan sebuah seseorang untuk menjadi anggota dari berbagai klub di waktu yang sama.

Anggota dan Pemilik sebagai jenis entitas terpisah

Seperti yang Anda tahu, penyimpanan beberapa fakta tentang peran yang dilakukan oleh orang sebagai pemilik dari klub -besides keberadaan belaka dalam benar atau salah attribute- bisa sangat menguntungkan. Sebagai contoh, Anda mungkin ingin menyimpan tanggal efektif di mana pasti orang menjadi pemilik dari sebuah klub , maka Anda dapat mengelola situasi ini dengan memperkenalkan jenis entitas yang terpisah yang disebut ClubOwner, seperti disajikan pada Gambar 4 .

Gambar 4. Model Data Klub dan Anggota - Anggota dan Pemilik sebagai Jenis Entitas Terpisah

Setelah Anda membuat tabel berdasarkan tipe entitas baru ini, Anda bisa menambahkan kolom pas yang mewakili karakteristik yang berperan secara eksklusif ketika a Personadalah Ownera dari a Club. Seperti yang digambarkan, tabel ini akan menampung PK yang terdiri dari kolom-kolom FK yang merujuk Person.PersonIddan Club.ClubId, dengan cara ini kombinasi ClubOwner.OwnerId(atau ClubOwner.PersonId, jika Anda mau) dan ClubOwner.ClubIddapat dimasukkan hanya dalam satu kesempatan.

Tentu saja, dengan konfigurasi ini Anda masih dapat memperoleh dalam bentuk boolean jika a Personadalah yang Ownerkhusus Clubdengan bantuan kueri yang mengembalikan nilai skalar yang dapat dievaluasi menjadi benar atau salah .


Catatan

1. Definisi Integrasi untuk Pemodelan Informasi ( IDEF1X ) adalah teknik pemodelan data yang sangat direkomendasikan yang didefinisikan sebagai standar pada bulan Desember 1993 oleh Institut Standar dan Teknologi Nasional ( NIST ) Amerika Serikat . Hal ini kokoh didasarkan pada (a) beberapa makalah teoritis ditulis oleh pencetus dari Relational Model , yaitu, Dr EF Codd ; pada (b) teori Entity-Relationship , yang dikembangkan oleh Dr. PP Chen ; dan juga pada (c) Teknik Desain Basis Data Logis , yang dibuat oleh Robert G. Brown . Perlu dicatat bahwa IDEF1X adalahdiformalkan dengan cara logika tingkat pertama .

2. ALTERNATE KEY adalah atribut (atau kombinasi dari atribut) yang menyimpan nilai-nilai yang secara unik mengidentifikasi kejadian entitas tetapi tidak dipilih sebagai PK dari jenis entitas terkait; setiap tipe entitas dapat memiliki nol, satu atau lebih tombol ALTERNATE. Dalam model IDEF1X, mereka diindikasikan sebagai "AK" ditambah nomor masing-masing, misalnya, AK1, AK2, dll. Mereka biasanya diimplementasikan dalam struktur SQL DDL melalui KONSTRA UNIK (atau INDIK UNIK ).

3. Nama peran adalah denotasi (atau alias) yang ditugaskan untuk atribut FK untuk mengekspresikan makna yang mereka pegang dalam lingkup entitas masing-masing. Penggunaannya direkomendasikan sejak 1970 oleh Dr. Codd dalam makalah seminalnya yang berjudul “Model Data Relasional untuk Bank Data Bersama Besar” . Untuk bagiannya, IDEF1X — menjaga kesetiaan dalam praktik relasional — juga menganjurkan penamaan peran.

MDCCL
sumber
2
  1. Jika seorang pemilik selalu menjadi anggota klubnya. Tambahkan ownerId ke Club-table, dan letakkan personId di sana dari anggota yang adalah pemilik.
  2. Peningkatan Otomatis Id bagus. Anda bisa menambahkan 'kode' bidang lain, di sana Anda memasukkan kode anggota pada kartu klub di sana.
  3. Seharusnya secara otomatis ok (saya pikir)
  4. Masukkan personId dalam Nomor telepon dan tabel email.

... Anda tidak dapat menjadi anggota dari beberapa klub? Jika Anda bisa, buat tabel ClubMember dengan clubId dan personId. Dengan begitu Anda dapat menghubungkan seseorang ke beberapa klub.

aldwinaldwin
sumber
1
Bagaimana jika saya ingin klub saya memiliki nomor telepon aswel? Apakah saya memasukkan clubIdnomor telepon juga dan membiarkan klub atau orang tidak ada?
Vahx
Saya tidak akan 'terlalu' memisahkan semua objek (normalisasi data). Cukup masukkan 1 nomor telepon di meja klub. Normalisasi itu baik, tetapi terlalu banyak normalisasi dapat menyebabkan masalah.
aldwinaldwin
1
tapi seandainya saya ingin melakukan ini? saya akan mengambil alamat sebagai contoh, anggota memiliki alamat tetapi klub juga akan memerlukan alamat
Vahx
1
Buat alamat-catatan dan masukkan addressId di klub. Karena klub memiliki 1 alamat, seorang anggota memiliki 1 alamat. Untuk nomor telepon, Anda perlu memasukkan orang ke catatan nomor telepon agar memiliki 1 hingga banyak. ..... Anda bisa membuat table personPhoneNumber (personId, phonenumberId) + table clubPhoneNumber (clubId, phonenumberId) yang menjadikannya lebih banyak-banyak-hubungan saat itu.
aldwinaldwin