Contoh sederhana: ada meja pelanggan.
create table Customers (
id integer,
constraint CustomersPK primary key (id)
)
Semua data lain dalam database harus terhubung ke Customer
, jadi misal Orders
terlihat seperti ini:
create table Orders (
id integer,
customer integer,
constraint OrdersPK primary key (customer, id),
constraint OrdersFKCustomers foreign key (customer) references Customers (id)
)
Misalkan sekarang ada tabel yang menghubungkan ke Orders
:
create table Items (
id integer,
customer integer,
order integer,
constraint ItemsPK primary key (customer, id),
constraint ItemsFKOrders foreign key (customer, order) references Orders (customer, id)
)
Haruskah saya menambahkan kunci asing terpisah dari Items
ke Customers
?
...
constraint ItemsFKCustomers foreign key (customer) references Customers (id)
Sebagai gantinya gambar: haruskah saya menambahkan garis putus-putus / FK?
Sunting: Saya telah menambahkan definisi kunci utama ke tabel. Saya ingin mengulang kembali pada poin yang saya buat di atas: basis data pada dasarnya dibungkam oleh pelanggan, sebagai ukuran kebenaran / keamanan. Oleh karena itu, semua kunci utama berisi customer
ID.
database-design
foreign-key
vektor
sumber
sumber
Jawaban:
Saya pikir ini adalah ide asli.
Hal pertama yang perlu diperhatikan adalah bahwa PK pada tabel LineItem memiliki tiga atribut
{CustomerID, CustomerOrderNo, OdrerItemNo}
, bukan hanya dua dalam contoh Anda.Hal kedua yang perlu diperhatikan adalah kebingungan yang dihasilkan dari penggunaan
id
nama generik untuk atribut.The
CustomerOrderNo
idealnya harus (1,2,3 ..) untuk setiap pelanggan danOrderItemNo
(1,2,3 ...) untuk setiap pesanan.Yah, ini bagus jika memungkinkan, tetapi membutuhkan kueri yang mencari nilai maks sebelumnya, seperti
yang sering tidak disukai di lingkungan volume transaksi tinggi, jadi itu umum untuk melihat ini digantikan oleh kenaikan otomatis, pada dasarnya melayani tujuan yang sama. Memang benar bahwa incremet otomatis ini sekarang unik, sehingga dapat digunakan sebagai KUNCI - tetapi Anda dapat memilih untuk melihatnya sebagai kompromi yang diperlukan untuk
OrderItemNo
.Jadi, dengan beberapa penggantian nama
CustomerOrderNo -> OrderNo
danOrderItemNo
->ItemNo
Anda dapat tiba di model iniJadi sekarang jika Anda melihat
Order
yang berikut ini adalah unikCatatan yang
{CustomerID, OrderNo}
disebarkan keLineItem
untuk melayani sebagai FK.Jika Anda sedikit menyipit, ini dekat dengan contoh Anda, tetapi dengan
PKs {ItemNo} and {OrderNo}
hanya - yang bertentangan dengan dua PK kolom dari contoh Anda.Sekarang pertanyaannya adalah, mengapa tidak menyederhanakan sesuatu seperti ini?
Yang baik-baik saja, tetapi memperkenalkan PATH DEPENDENCE - Anda tidak dapat bergabung
LineItem
denganCustomer
langsung, harus menggunakanOrder
dalam bergabung.Saya lebih suka case pertama jika memungkinkan - Anda memilih favorit Anda. Dan jelas, tidak ada kebutuhan untuk FK langsung dari
LineItem
keCustomer
tiga kasus ini.sumber
"Item" tidak boleh merujuk "pelanggan" secara langsung, karena ini tersirat oleh "pesanan" item. Jadi, Anda tidak memerlukan kolom "pelanggan" pada tabel "item" sama sekali.
Hubungan barang dengan pelanggan dipastikan dengan kunci asing yang ada.
Jika orders.id adalah kolom identitas, pertimbangkan untuk menghapus item.customer semuanya.
sumber
customer
semua tabel (dan dengan demikian silo DB) adalah pendekatan yang tidak biasa. Saya harus mengakui bahwa itu hanya sesuatu yang saya lihat dalam pekerjaan saya sebelumnya. Apakah itu masuk akal bagi Anda? Pernahkah Anda melihat desain seperti itu sebelumnya?