Apakah ini cara konyol untuk menyusun skema DB, atau apakah saya benar-benar kehilangan sesuatu?

61

Saya telah melakukan sedikit pekerjaan dengan database relasional, dan saya pikir saya memahami konsep dasar desain skema yang baik dengan cukup baik. Baru-baru ini saya ditugaskan untuk mengambil alih sebuah proyek di mana DB dirancang oleh konsultan yang dibayar tinggi. Tolong beri tahu saya jika usus saya intinct - "WTF ??!?" - Dijamin, atau apakah orang ini jenius sehingga dia beroperasi di luar wilayah saya?

DB yang dimaksud adalah aplikasi internal yang digunakan untuk memasukkan permintaan dari karyawan. Hanya dengan melihat sebagian kecil saja, Anda memiliki informasi tentang pengguna, dan informasi tentang permintaan yang dibuat. Saya akan mendesain seperti ini:

Tabel pengguna:

UserID (primary Key, indexed, no dupes)
FirstName
LastName
Department

Tabel permintaan

RequestID (primary Key, indexed, no dupes)
<...> various data fields containing request details
UserID -- foreign key associated with User table

Sederhana bukan?

Konsultan mendesainnya seperti ini (dengan data sampel):

Tabel Pengguna

UserID  FirstName   LastName
234     John        Doe
516     Jane        Doe
123     Foo         Bar

Tabel Departemen

DepartmentID   Name
1              Sales
2              HR
3              IT

Tabel UserDepartment

UserDepartmentID   UserID   Department
1                  234      2
2                  516      2
3                  123      1

Tabel Permintaan

RequestID   UserID   <...>
1           516      blah
2           516      blah
3           234      blah

Seluruh basis data dibangun seperti ini, dengan setiap bagian data dienkapsulasi dalam tabelnya sendiri, dengan ID numerik yang menghubungkan semuanya menjadi satu. Rupanya konsultan telah membaca tentang OLAP dan menginginkan 'kecepatan pencarian integer'

Dia juga memiliki sejumlah besar prosedur tersimpan untuk referensi silang semua tabel ini.

Apakah desain ini valid untuk SQL DB kecil hingga menengah?

Terima kasih atas komentar / jawaban ...

Jim
sumber
12
Oh nak, jika ini membuat Anda mengatakan WTF, maka Anda mungkin belum melihat tabel dengan 200+ kolom dan prosedur tersimpan lebih dari 1000 baris.
Pekerjaan
42
+1 karena tidak dihapus setelah merasa malu. Terima kasih telah meninggalkan ini sehingga orang lain dapat belajar.
Wayne Koorts
2
@ Pekerjaan - sebenarnya, saya belum - Saya bukan DBA oleh perdagangan (cukup jelas sekarang! Lol), jadi ambang batas SQL WTF saya cukup rendah. Meskipun, saya benar-benar kehilangan titik desain konsultan membuat saya memiliki kemampuan sendiri. Pernahkah hari di mana Anda merasa bodoh ?
Jim
9
@ Jim: Selamat, Anda telah mengubah hari yang bodoh menjadi hari yang tercerahkan .
Wayne Koorts
3
Terkutuklah para konsultan yang dibayar tinggi itu!
davidsleeps

Jawaban:

73

Masuk akal bagi saya. Itu hanya sangat dinormalisasi, yang memberikan banyak fleksibilitas yang Anda tidak akan sebaliknya. Data yang dinormalkan adalah rasa sakit di pantat.

Blrfl
sumber
jawaban Anda masuk akal, dan melihat pertanyaan saya dan skema mungkin hanya jumlah tabel yang dia gunakan yang membingungkan saya. Saya sangat menyederhanakan contoh untuk pertanyaan saya, tetapi saya melihat bagaimana konsepnya masuk akal - dia hanya memecah hal-hal jauh lebih banyak daripada saya. Sigh, kurasa itu hal yang baik aku bukan DBA! :)
Jim
Belajar mendesain dengan aturan sepuluh menit: "Apa yang berlaku sekarang mungkin tidak akan dalam sepuluh menit." Pastikan desain Anda dapat menangani perubahan.
Blrfl
1
Skema ini sebenarnya memiliki keuntungan bahwa ketika seorang karyawan dimasukkan, departemen mereka harus ada.
Simon Richter
@SimonRichter: Itu tidak benar. Karyawan dapat dibuat tanpa ada Departemen yang ada, dan juga sebaliknya.
Daniel Dinnyes
@SimonRichter Manfaat dari desain ini adalah, pertama, bahwa Departemen adalah entitas yang terpisah, dan kedua, bahwa ada banyak-ke-banyak hubungan antara Departemen dan Karyawan, sebagai lawan dari contoh OP, di mana ia "banyak- to-one-ish "(tidak bisa mengatakan banyak-ke-satu, karena tidak ada entitas Departemen yang terpisah yang disebut sebagai hubungan).
Daniel Dinnyes
48

Saya tidak berpikir bahwa WTF dijamin atau bahwa orang itu melakukan segala jenis desain jenius gila - itu normalisasi basis data standar.

Alasan untuk tabel departemen adalah bahwa jika Anda tidak menempatkan departemen ke dalam tabel terpisah, Anda harus berurusan dengan pengguna di bagian "Penjualan", "penjualan", "Penjual", "Layar", dan "Penjualan", kecuali Anda melakukan sesuatu untuk mencegahnya. Dan memiliki meja tambahan adalah (bagian dari) cara terbaik yang saya tahu untuk melakukan itu.

Apakah harus ada tabel UserDepartment adalah panggilan yang lebih sulit, yang tentu saja berarti tidak ada keputusan yang keluar dan gila. Di satu sisi itu adalah rasa sakit ketika semua desain dan logika tabel Anda telah mengasumsikan satu departemen per pengguna dan kemudian berubah, di sisi lain melakukan join tambahan tanpa alasan selama bertahun-tahun adalah kemungkinan nyata dan juga rasa sakit.

Saya pribadi akan setuju dengan Anda bahwa tabel UserDepartment mungkin berlebihan. Bahkan jika itu termasuk, kemungkinannya adalah bahwa seiring waktu orang akan menulis pertanyaan yang menganggap hanya ada satu pengguna per departemen, sehingga Anda akan berakhir dengan yang terburuk dari kedua dunia - gabung tambahan tanpa alasan sebelum membutuhkan tabel, dan kode tetap tidak berfungsi setelah lebih dari satu departemen per pengguna diizinkan.

EDIT - Pendorong utama apakah hubungan banyak ke banyak harus didukung adalah jika aturan bisnis jelas. Jika Anda tidak tahu bagaimana seorang pengguna di banyak departemen bahkan bekerja, tidak ada gunanya menambahkan tabel, karena kode Anda tidak mungkin menangani kasus-kasus di mana pengguna berada di banyak departemen dengan benar.

Bayangkan Anda mengizinkan banyak departemen per pengguna, untuk berjaga-jaga. Anda kemudian menerapkan aturan bisnis untuk menetapkan komisi, berdasarkan departemen. Kemudian beberapa departemen diizinkan. Untungnya, Anda juga memiliki pandangan ke depan untuk menulis kode komisi Anda dengan cara yang memperhitungkan hal ini. Sayangnya, Anda menambahkan komisi dari masing-masing departemen untuk pengguna di keduanya. Manajemen ingin Anda mendasarkan pada peran orang untuk setiap penjualan. Jadi, seberapa bagus meja itu di muka? Bagaimana dengan tabel lain yang Anda miliki "berjaga-jaga" yang tidak pernah dibutuhkan sama sekali?

EDIT KEMUDIAN - Alasan lain konsultan mungkin ingin menambahkan semua tabel perantara dibahas dalam pertanyaan lanjutan ini , jawaban yang memberikan beberapa alasan mengapa refactoring database biasanya lebih sulit daripada refactoring kode, yang cenderung mendorong Anda ke arah pendekatan "masukkan semua tabel yang mungkin Anda butuhkan".

psr
sumber
Saya pikir Anda memasukkan kata-kata apa WTF saya - pria itu menggunakan BANYAK dari tabel intemediary ini, dan itu tampak sangat bodoh bagi saya. Sekarang saya telah memecahnya menjadi contoh yang jauh lebih kecil untuk pertanyaan ini, saya merasa agak bodoh untuk mempostingnya karena sepertinya tidak terlalu buruk.
Jim
5
Seperti yang dapat Anda lihat dari banyak komentar, ada skeptisisme yang sehat tentang komentar "hanya akan ada satu X per Y". Konsultan menutupi dirinya dari keluhan "kenapa hanya ada satu X per Y". Beberapa di antaranya mungkin akan muncul. Tetapi dia tidak akan bertanggung jawab untuk memelihara kode yang memiliki banyak gabungan (tidak terlalu buruk, tetapi lebih sulit) dan itu harus benar terhadap aturan bisnis yang belum ada (buruk) - bayangkan pertanyaan "mengapa pengguna mendapatkan SEMUA izin dari masing-masing departemen, mereka harus mendapatkan TERENDAH dari setiap izin "atau semacamnya.
psr
@psr Saya pikir ada salah ketik: tidak boleh "kueri yang menganggap hanya ada satu pengguna per departemen" menjadi "kueri yang menganggap pengguna hanya dalam satu departemen"?
BiAiB
@BiAiB - Anda benar, itulah yang ingin saya katakan.
psr
14

Jika persyaratannya adalah memiliki beberapa departemen per pengguna, desain ini masuk akal. Satu-satunya keluhan tentang itu adalah UserDepartmentTablememiliki kunci pengganti UserDepartmentIDyang tidak diperlukan (hanya membuat UserIddan DepartmentIdkunci primer komposit).

Jika pengguna hanya milik satu departemen, desain Anda masuk akal (meskipun tabel pencarian departemen masih merupakan hal yang baik).

Oded
sumber
18
... Hingga lebih dari satu departemen dimungkinkan per pengguna.
Blrfl
1
Tepatnya, @ Bllfl. Hari ini yang tidak akan pernah terjadi adalah sang CEO-akan-memiliki-aneurisma-karena-itu-tidak-melakukan-itu.
Adam Crossland
2
Bagian dari memutuskan apa yang layak untuk perawatan semacam itu adalah memahami domain masalah. Dalam beberapa aplikasi, mungkin penting untuk mengetahui bahwa karyawan # 3804 telah dikenal oleh perusahaan sebagai Ann Smith dan Ann Jones (setelah menikah), yang akan membuat normalisasi nama dari meja karyawan menjadi hal yang wajar untuk dilakukan. Dalam kasus Jim, mungkin perlu memperluas tabel pemutus untuk menjaga sejarah sehingga jika Ann pindah dari HR ke IT, fakta bahwa permintaan lama yang terikat padanya dapat mencerminkan bahwa itu benar-benar permintaan HR dan bukan IT.
Blrfl
8
YAGNI - database dapat di refactored.
JeffO
2
@Oded, Beberapa pemetaan ORM seperti Entity Framework tidak berfungsi dengan baik dengan tabel yang memiliki kunci primer komposit.
maple_shaft
5

Beberapa persyaratan tidak jelas dalam pertanyaan Anda. Jawaban yang benar tergantung pada apa yang diinginkan pelanggan Anda - Jika saya adalah Anda, saya akan bertanya kepada pelanggan tentang ini:

0-Apa perbedaan antara pengguna dan karyawan?

1-Dengan asumsi seorang karyawan = pengguna, bagaimana jika seorang karyawan mengubah departemen?

2-Bisakah sekelompok karyawan membuat 1 permintaan?

3-Bisakah seorang karyawan menjadi anggota lebih dari satu departemen? Bagaimana dengan CEO

4-Apakah ada sebagian karyawan yang diizinkan membuat permintaan?

5-Apa yang terjadi pada permintaan ketika catatan karyawan dihapus (jika pernah)?

6-Bisakah Anda menghapus permintaan? Apa yang terjadi ketika permintaan dihapus (pastikan Anda tidak menghapus catatan karyawan oleh RI)

7-Bisakah karyawan membuat permintaan "sama" lebih dari satu kali (mendefinisikan "sama")

8-Bagaimana menangani permintaan untuk karyawan ketika mereka meninggalkan perusahaan (membatalkan permintaan mereka atau menghapus permintaan?)

Mungkin ada lebih banyak pertanyaan, tetapi poin saya adalah bahwa solusinya tergantung pada persyaratan yang tepat dan ruang lingkup proyek. Setelah itu ditentukan skema dapat diturunkan secara langsung. Dengan demikian kedua solusi yang disajikan mungkin benar.

Tidak mungkin
sumber
+1 ini adalah pertanyaan hebat yang perlu diklarifikasi sebelum merancang jenis skema ini. Saya suka aliran logika Anda.
@ Surfer513: Saya menghargai komentar Anda yang bagus.
NoChance
1

Saya ingin menambahkan beberapa catatan formulir poin berbicara secara eksplisit tentang beberapa keuntungan potensial dari menggunakan tabel bergabung dengan cara yang dilakukan konsultan Anda yang dibayar tinggi.

  • Diindeks dengan benar (misalnya, jika UserDepartmentTable mengindeks dua kunci asing), hanya ada sedikit kerugian kinerja tabel gabungan seperti ini karena kunci asing tidak unik. Jika kunci asing dijamin unik, dengan teori basis data kecil yang saya tahu, mencari UserDepartmentTable.Departmenttidak lebih "sulit" daripada mencari kolom lain dalam Usertabel.
  • Tabel bergabung memberi Anda lebih banyak fleksibilitas untuk mengatur informasi lain tentang hubungan antara pengguna dan departemen (misalnya, cap waktu pembuatan).
  • Tabel bergabung memungkinkan Anda untuk "versi" asosiasi dengan cukup mudah (misalnya, ketika pengguna mengubah departemen, memicu beberapa bendera boolean indeks seperti UserDepartmentTable.Activefalse dan membuat asosiasi baru yang aktif). Dimungkinkan juga untuk membuat versi asosiasi departemen dengan model dua-tabel (hanya Pengguna dan Departemen), tetapi lebih sulit dan mengharuskan menambahkan setidaknya satu kolom lagi atau melakukan akrobat database untuk menghindari duplikasi kunci primer.
  • Ini memungkinkan Anda untuk menetapkan asosiasi satu-ke-banyak atau banyak-ke-satu atau banyak-ke-banyak dengan mudah.

Yang sedang berkata, ada beberapa alasan untuk TIDAK melakukan apa yang konsultan bayaran Anda lakukan.

  • Semua manfaat di atas semua mengantisipasi kemungkinan kebutuhan di masa depan, hal-hal yang terlalu rumit untuk hari ini. Itu tidak sesuai dengan YAGNI. Sangat sulit nantinya untuk menulis migrasi yang bergerak dari model dua tabel Anda ke model tabel bergabung. Anda dapat melakukannya ketika kebutuhan bisnis muncul. Melakukannya sebelum itu bisa membingungkan.
  • Ini membingungkan pengembang lain. Sementara, ya, saya akan mengatakan harapan untuk seorang pengembang web dari status Anda (di mana Anda meninjau keputusan konsultan) adalah untuk memahami dan mengenali tabel bergabung, itu masih lebih rumit daripada yang diperlukan dan mengingat kurangnya kebutuhan bisnis, itu menyebabkan kebingungan.
Steven
sumber
analisis yang bagus - namun, saya tidak akan mengatakan saya memiliki status sebagai dev dalam pekerjaan saya, kecuali bahwa saya adalah satu-satunya di sini yang tahu apa - apa tentang db / c # / vb / dll ... jadi kira saya bagian waktu dev secara default. ini adalah proyek yang cukup kecil, sehingga para konsultan banyaknya meja dan bergabung meninggalkan saya mengatakan "wtf" (tapi terima kasih kepada Anda orang baik saya sekarang mengatakan "oic ...")
Jim
Topik yang cukup lama, tetapi masih relevan ... refactoring mungkin sangat sulit, bayangkan Anda membutuhkan beberapa departemen di masa depan, bukan hanya satu, tetapi hanya memiliki ID departemen di Pengguna sebagai FK. Anda mungkin akan berakhir dengan rujukan duplikat (Users.DeptID dan UsersDepartmentsTable) atau menyelesaikan sampah, seperti daftar yang dipisahkan koma di Users.DeptID, atau XML. Solusi yang benar tidak dapat dengan mudah ditambahkan, seperti yang disarankan oleh YAGNI atau KISS, tetapi akan terhambat.
Erik Hart
0

Tanpa struktur penuh informasi yang dibutuhkan, saya tidak dapat mengatakan apakah ini mengerikan atau tidak. Tetapi setidaknya potongan yang ditampilkan bukan dari desain "WTF". Itu hanya tampak sebagai Bentuk Normal 3-rd dari struktur data (well, kami secara teoritis juga 4-rd dan 5-th juga)

Beberapa pembicaraan dapat memiliki tempat untuk UserDepartmentTable antara dua sekolah kunci "alami" dan "buatan" di bagian yang ditampilkan. Tidak ada yang lebih, seperti yang saya lihat

Normalisasi adalah aturan DB-developer / designer yang baik karena banyak alasan, * de * normalisasi kadang-kadang digunakan di tengah perkembangan untuk memenangkan-menang sebagian besar

Malas Badger
sumber