Cara menangani desain tabel dengan kolom variabel

17

Saya memiliki skenario desain tabel dan sebagai tipe non-DBA, ingin pendapat yang lebih mudah diukur.

Katakanlah Anda diminta untuk mencatat informasi tentang rumah-rumah untuk wilayah metro, dimulai dengan lingkungan kecil (200 rumah) tetapi akhirnya tumbuh hingga 50.000.000 rumah.

Anda diharuskan untuk menyimpan informasi dasar: ID # (Banyak unik # yang dapat kita gunakan sebagai indeks unik), Addr, Kota, Negara, Zip. Baik, meja sederhana akan menanganinya.

Tetapi setiap tahun, Anda akan diminta untuk mencatat informasi tambahan tentang semua rumah - dan informasi APA akan berubah setiap tahun. Jadi, misalnya, tahun pertama, Anda diminta untuk mencatat nama belakang pemilik dan cuplikan kotak. Tahun kedua, Anda diminta untuk menyimpan nama belakang, tetapi membuang rekaman persegi dan bukannya mulai mengumpulkan nama depan pemilik.

Terakhir - setiap tahun # kolom tambahan akan berubah. Mulai dengan 2 kolom tambahan, lalu ke 6 tahun depan, lalu kembali ke 2.

Jadi pendekatan satu tabel adalah mencoba menambahkan informasi khusus sebagai kolom di tabel rumah sehingga hanya ada satu tabel.

Tapi saya punya situasi di mana seseorang meletakkan meja untuk ini sebagai:

Kolom "House Table": ID, Addr, City, State, Zip - dengan satu baris per rumah

ID   Addr              City     State  Zip 
-------------------------------------------
1    10 Maple Street   Boston      MA  11203

2    144 South Street  Chelmsford  MA  11304

3    1 Main Avenue     Lowell      MA  11280

Kolom "Info Kustom Tabel": ID, Nama, Nilai - dengan tabel tampak seperti:

ID   Name             Value

1    Last Name        Smith

2    Last Name        Harrison

3    Last Name        Markey

1    Square Footage   1200

2    Square Footage   1930

3    Square Footage 

Jadi ada beberapa baris untuk setiap record rumah individu. Setiap tahun ketika informasi opsional memerlukan perubahan, tabel ini secara harfiah dibangun kembali, jadi tahun depan akan terlihat seperti:

1    Last Name    Smith

2    Last Name    Harrison

3    Last Name    Markey

1    First Name   John

2    First Name   Harry

3    First Name   Jim

Akhirnya Anda mengumpulkan 100.000 baris rumah DAN satu tahun ada 10 informasi tambahan; tabel kedua sekarang adalah 1.000.000 baris informasi, banyak di antaranya memiliki informasi yang berlebihan (deskripsi). Persyaratan basis data secara keseluruhan adalah bahwa orang perlu mendapatkan informasi baris rumah + nilai bidang kustom terkait ribuan kali per hari.

Jadi pertanyaan saya: Apakah praktik yang buruk (atau mengerikan) adalah:

A) Letakkan tabel rumah dengan tebakan di maks # kolom khusus (disebut mungkin "1" hingga "10") dan masukkan nilai-nilai khusus tersebut tepat di baris rumah

ATAU

B) Menyimpan informasi khusus di tabel rumah, tetapi setiap tahun ketika persyaratan berubah, buat ulang tabel rumah hanya dengan # kolom yang diperlukan untuk informasi khusus, dengan gagasan bahwa persyaratan dapat menjadi gila dan Anda tidak pernah tahu berapa banyak maksimum bidang opsional mungkin diminta?

Terima kasih, harap ini masuk akal!

Schmitty23
sumber
Hai, bagaimana Anda mengelola masalah Anda? Saya menjalankan skenario yang sama dan saya akan membuat satu tabel relasional per info tambahan, dan menjadikannya dengan pandangan sebagai "tabel tunggal".
Benj

Jawaban:

15

Anda memiliki 4 pilihan:

NoSQL - definisi Setiap catatan disimpan sebagai satu set pasangan Key / Value. Ini sangat fleksibel dan cepat. Tidak semua penulis laporan di luar sana mendukung gaya penyimpanan ini. Ada banyak contoh implementasi database NoSQL. Yang tampaknya paling populer saat ini, adalah MongoDB.

EAV - definition Di sinilah Anda mengubah seluruh tabel atau sebagian (di tabel lain) di sisinya. Ini adalah pilihan yang baik jika Anda sudah memiliki in-house database relasional yang tidak dapat Anda hindari dengan mudah. Contoh tabel info khusus yang Anda berikan adalah contoh yang baik dari tabel EAV.

Tabel standar dengan kolom XML - Pikirkan ini karena NoSQL memenuhi tabel relasional. Data yang disimpan dalam kolom XML dapat berupa format apa pun yang didukung XML, termasuk beberapa sub-data berkorelasi. Untuk kolom yang Anda tahu akan menjadi kolom "biasa", mereka dapat dibangun sebagai jenis kolom yang sesuai untuk menyimpan data (Nama Belakang, Alamat, Kota, Negara, dll.).

Tabel standar dengan banyak kolom tambahan - Anda memiliki basis data relasional, Anda tidak dapat menggunakan XML atau EAV, dan NoSQL bukan opsi. Tambahkan banyak kolom tambahan untuk setiap jenis. Saya kira 30 atau lebih varchar, 30 atau lebih bilangan bulat, 15 atau lebih banyak angka. Dan begitu Anda menggunakan kolom untuk suatu nilai, jangan menggunakannya kembali . Dan jangan hapus kolomnya juga.

Dari semua solusi ini, pendapat saya sendiri adalah Anda akan menemukan pendekatan NoSQL atau EAV menjadi yang paling sukses dengan jumlah refactoring kode dan skema Anda yang paling sedikit.

Anda akan memiliki situasi di mana Anda mengumpulkan data satu tahun, bukan yang berikutnya, dan kemudian mengumpulkannya lagi sesudahnya. Mencoba mendapatkan data yang lebih lama diperbarui dengan informasi yang benar itu bermasalah dan mahal. Penyimpanan tidak ada.

Adam Zuckerman
sumber
Saya mendengar Anda juga dapat menggunakan tabel pivot atau sesuatu seperti itu
Alexander Mills
2

Untuk menjawab pertanyaan Anda tentang 2 opsi itu, tidak ada yang benar bagi saya. A) akan mengunci Anda dan B) banyak pekerjaan. Skema saat ini yang Anda gambarkan tidak terlalu buruk (kecuali untuk memiliki nama informasi ("nama depan", "kaki persegi", dll.) Sebagai string alih-alih ID yang dirujuk ke tabel pencarian.

Namun, bagi saya ini sepertinya adalah kandidat yang baik untuk database NoSQL ( http://en.wikipedia.org/wiki/NoSQL ). Meskipun saya tidak pernah bekerja dengan database seperti itu, apa yang Anda gambarkan adalah skenario khas yang dipecahkan ini.

ETL
sumber
0

Jika jumlah kolom kustom bersamaan terbatas dan batasnya diketahui (mis. Tidak lebih dari 10-20 kolom Kustom untuk String, tidak lebih dari x kolom untuk bilangan bulat, dll.)
Anda bisa menggunakan tabel dasar dengan bidang tambahan per datatype dan sebagai gantinya membangun kembali tabel setiap tahun membuat tampilan untuk tahun itu termasuk hanya kolom khusus yang relevan dan mengganti nama bidang generik untuk mencerminkan konten untuk tahun itu.

House Table:
ID, Addr, City, State, Zip, custom_string1,cs_2,cs_3,custom_integer_1,ci_2,ci_3 ...

create view house_2014 as 
select ID, Addr, City, State, Zip,
custom_string1 as last_name,cs_2 as first_name ...

Masalah dengan pendekatan ini adalah, bahwa Anda tidak memiliki riwayat tetapi Anda dapat dengan mudah membuat salinan setiap tahun sebelum mengubah persyaratan kolom.

create table house_2014_archive as select * from house_2014;
drop house_2014;
create view house_2015 as "select column list for new year";
scheelec
sumber
0

Bisakah Anda menghitung semua skenario yang ingin Anda simpan data ini?

jika ada jumlah terbatas kombinasi kolom yang dapat diterapkan pada tabel, maka cobalah untuk memodelkan "tabel dasar" dengan kolom umum yang gpoing untuk diterapkan ke semua skenario, lalu buat lebih banyak tabel (untuk mengimplementasikan beberapa jenis warisan; ini dikenal sebagai subtipe / supertipe dalam ERD dan desain basis data.)

satu tabel untuk setiap skenario, dengan cara ini setidaknya Anda akan menjaga tabel tetap bersih dan Anda akan dapat menghindari menyimpan alamat jalan di kolom "nama belakang" ...

lihat pertanyaan desain ini: /programming/554522/something-like-inheritance-in-database-design

joe
sumber