Bu tabloyu kayıpsız bir şekilde parçalayabilir miyim?


10

Ligimin dışında bir veritabanı tasarım sorunuyla karşılaştım ve benim DBA gurum yangın tatbikatlarında kapalı.

Özünde, aşağıdaki birincil anahtar (kısaltma için PK) içeren bir tablo var:

child_id   integer
parent_id  integer
date       datetime

child_idve parent_idvarlık tablolarının yabancı anahtarlarıdır. "Alt" tablonun kendisi de "üst" tablonun yabancı bir anahtarını içerir ve her biri, her child_idzaman parent_idyukarıdaki tablonun beklediği ile aynıdır . Aslında, ikisini senkronize tutan bazı ekstra kodlar olduğu ortaya çıkıyor.

Bu da bu aşırı hevesli normalleşme acemisine "Bunun yerine işten çıkarmayı kaldırmalıyım!"

Aşağıdakilere ayrıştım:

Table_1 PK:
child_id   integer
date       datetime

Table_2 PK:
parent_id  integer
date       datetime

Table_3: (already exists)
child_id   integer PRIMARY KEY
parent_id  integer FOREIGN KEY

Ve bu adamlara doğal yolla katıldığımda orijinal masayı kurtarıyorum. Bunu 5NF yapan benim anlayışım.

Ancak, şimdi gizli bir iş kuralı olduğunun farkındayım.

Normalde, belirli child_idbir tarihle ilişkili tarihler, karşılık gelen tarihlerin bir alt kümesi olmalıdır parent_id. İlk tablonun bu kuralı uyguladığını görebilirsiniz.

Ayrışmam kuralı uygulamıyor, çünkü tarihler çok büyüyene kadar Tablo 1'e özgürce ekleyebilirsiniz.

Bu da beni şu sorulara götürüyor:

  1. Bu ayrışma 5NF mi? Ekleme anormalliklerine izin verdiğini söylesem de, kendisi de bu kılavuzu takip eden Wiki örneğini takip ediyor gibi görünüyor . "Vurgu mayın" ifadesi "tüm gerçek gerçekleri üç ayrı kayıt türünden oluşan normalleştirilmiş bir formdan yeniden oluşturabiliriz" ifadesi bana özel bir duraklama veriyor, çünkü ne kadar çöp Table_1pompaladığım önemli değil, doğal birleşim hala görmezden geliyor.

  2. Diyelim ki bu ayrışmayı sevmiyorum (sevmiyorum). Pratik çözümün tabloyu ve kodu olduğu gibi bırakmak olduğunu serbestçe kabul ediyorum. Fakat teoride, ben ilk tablodan kurtulmak şekilde ve ayrıştırmak / veya kısıtlamaları eklemek için bir yol yoktur ve benim iş kurallarını korumak?


1
Orijinal tablonuzdaki anahtarlar nelerdir? Hangi bağımlılıkları satsify etmek gerekiyor? Child_id-> parent_id öğesinin olduğunu söylüyorsunuz, bu durumda child_id ve parent_id öğelerinin ikisi de bu tabloda aynı anahtarın parçası olamaz.
nvogel

1
@trevor: Buradaki cevapları hiç gözden geçirdiniz mi? En son sorduktan 19 dakika sonra görüldü. Cevaplar daha sonra geldi.
gbn

Yanıtlar:


9

Normalizasyon fonksiyonel bağımlılıklara dayanır. İşlevsel bağımlılıklar anlambilim ile ilgilidir; verilerin ne anlama geldiğiyle ilgilidir . Gerçek dünyadaki bir sorunu "parent_id, child_id, date" düzeyine sadeleştirdiğinizde ve örnek veri eklemediğinizde, vicdanlı bir veritabanı tasarımcısının size verebileceği yardım miktarını gerçekten sınırlarsınız.

Bir tabloda anahtar {child_id, parent_id, date} anahtarınızın olması ve alt tabloda benzersiz bir çift {child_id, parent_id} olması, kombinasyonun bir kısmının gereksiz olduğu anlamına gelmez . Bu, birincil anahtar olarak {child_id, parent_id, date} olan tabloda, {child_id, parent_id} öznitelik çiftinin ilk olarak alt tabloya başvurması gerektiği anlamına gelebilir.

Eğer durum buysa, kullanabilirsiniz FOREIGN KEY (child_id, parent_id) REFERENCES child (child_id, parent_id). Bunu yapmak için, "child" tablosundaki sütun çifti (child_id, parent_id) üzerinde UNIQUE sınırlamasına ihtiyacınız vardır; bu, child_id birincil anahtarı ise sorun olmamalıdır.

Ancak, verilerin ne anlama geldiğini bilmeden anlamanın bir yolu yoktur ve bu ileti dizisinde bunu bilen tek kişi sizsiniz. (Ama bunu bize açıklamanıza izin vermekten mutluluk duyarız.)

Orijinal tablo söz konusu olduğunda, child_id -> parent_id diyorsunuz. Bu durumda, parent_id neden orijinal tabloda ilk etapta? Neden anahtar (child_id, date) sadece "child" tablosuna yabancı anahtar referansı ile değil? Bana öyle geliyor ki, bahsettiğiniz yedeklilik türü "parent_id" sütununu bırakarak çözülebilir.

SQL DDL ve INSERT ifadeleri biçimindeki örnek veriler size yardımcı olmamıza yardımcı olur. DDL ve INSERT ifadeleri açıklamalardan daha kesindir.


1
"Fonksiyonel bağımlılık" hatırlatıcısı için +2
jcolebrand

3

Bunu dene...

  • (child_id,parent_id)Alt tabloya benzersiz kısıtlama ekleyin
  • Geçerli tablonuz (PK,FK:child_id, PK,FK:parent_id, PK:date)olduğu gibi kalır, FK yeni benzersiz kısıtlamanın 2 sütunundadır

veya

  • FK'yi geçerli alt tablodan kaldırın
  • Alt öğe (PK,FK:child_id, FK:parent_id)ile 1: 1 olan yeni bir tablo oluşturun
  • Geçerli tablonuz (PK,FK: child_id, PK,FK: parent_id, PK:date)olduğu gibi kalır. ancak FK yeni tablodaki 2 sütunda

Başka bir şey yoksa, size ilham verebilir ...

Doğru anladıysam, artıklık ve kodu kaldıracak ...

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.