2011-09-22 17 views
5

İşte basit bir örnek:Veritabanı tablosunda bir müşterinin varsayılan gönderim adresini nasıl belirlerim?

Adres tablosuna birebir çok ilişkisi olan bir müşteri çizelgesine sahip olduğumu varsayalım (bir müşterinin birden çok gönderi adresi olabilir, ancak bir gönderim adresi yalnızca tek bir müşteriye ait olabilir)).

Customer Table 
------------- 
customer_id (PK) 


Address Table 
------------- 
address_id (PK) 
customer_id (FK) 

Artık her müşterinin varsayılan gönderim adresi belirleyebilmesini istiyorum.

2 yolu düşünebilirim fakat her ikisinin de dezavantajları vardır.

Seçenek 1

"is_default" denilen adres tablosunu bir Boole sütun ekleyin.

Artıları

  1. seç sorgularının

Eksileri

  1. uygulamadır DB modeli görürseniz diğer insanlar için Kolay
  2. anlamak için basit olan fo zorlamak ve sürdürmek için "tek sıra bir varsayılan olabilir" kısıtlaması.
  3. Varsayılan alanın güncellenmesi, uygulamanın önceki varsayılan seçeneği işaretleyip sıfırlamasını gerektirdiğinden bir acıdır. 2

Opsiyon "address_id" denilen Müşteri tabloya bir sütun ekleyin ve bir yabancı anahtar yapmak (ayrıca boş değerlere hiçbir adres Varlığından sadece durumda izin). kullanıcı bunu değiştirmeye karar verirse

Artıları

  1. Kolay varsayılan adresi güncellemek için.
  2. Veritabanı "yalnızca bir satır varsayılan olabilir" kısıtlamasını korur.

Eksileri

  1. Ben Müşteriler Tablo I varsayılan meta çeşit eklemeye karar her zaman yeni endeksli sütun eklemek gerekir.

  2. Belkide benim senaryo bu tür işlemek için standart bir yol yoktur,

Sorum şu kesmek gibi görünüyor? Tabii ki başka seçenekler de var (belki bir EAV varsayılan seçenek tablosu oluşturuyorsunuz?). Ancak, değişiklik olabildiğince basit tutmayı tercih ediyorum, çünkü herhangi bir şeyi kırmak istemiyorum.

cevap

1

(belki bir EAV varsayılan seçenekleri tablo oluşturma?)

Bunu yapacağını, mevcut kodu kırma konusunda endişeleriniz özellikle.

Customer_Defaults 
------------------------------------ 
customer_id       PK, FK -> Customer 
default_shipping_address_id   FK -> Address 

Bu düzenli değil mi? Her şeyi ayrı bir masaya çekerek, mevcut tabloları yalnız bırakırsınız. Bir çeşit ORM katmanı kullanıyorsanız, bu yeni tablonun üzerindeki nesne doğrudan sorgulanabilir ve daha sonra Adres nesnesine yürüyebilirsiniz. Yeni nesneyi mevcut Müşteri veya Adres nesnelerine tanıtmaya bile gerek yok.

+0

Bu aklıma ama sonra varsayılan bir deyişle kredi kartı –

+0

@BillH hesapları gerektiren her tablo için yeni "varsayılan tablo" oluşturmak zorundayız: Neden? Credit_Card tablosuna işaret eden başka bir sütun olan "default_credit_card_id" eklemenizi engelleyen hiçbir şey yok. Tablonun adı, müşteri için * tüm * varsayılanları yakalamak için yeterince geneldir. – Mac

0

Yeni gereksinimleriniz büyüdükçe yeni tabloları düşünün. Sorununuza yaklaşmanın iki farklı yolu vardır. Birincisi ikincisinden daha az katıdır. (İkincisini kullanırdım.) "Adres Tablosu" nun "customer_addresses" olarak adlandırılacağını varsayalım.

create table default_shipping_addresses (
    customer_id integer primary key references customers (customer_id), 
    shipping_addr_id integer not null unique references addresses (addr_id) 
); 

create table default_shipping_addresses (
    customer_id integer primary key references customers (customer_id), 
    shipping_addr_id integer not null unique references addresses (addr_id), 

    -- Add a UNIQUE constraint on customer_addresses (customer_id, address_id). 
    -- Since address_id is the primary key, it's unique, so (customer_id, 
    -- address_id) will also be unique. But you need the UNIQUE constraint to 
    -- allow a foreign key to reliably reference it, even in MySQL. 
    foreign key (customer_id, shipping_addr_id) 
    references customer_addresses (customer_id, address_id) 
); 
+0

Müşteri_kimliği ile shipping_addr_id arasında, kendi kaynaklarına işaret eden 2 yabancı anahtar ile bileşik birincil anahtar oluşturamadım. –

İlgili konular