2016-09-12 239 views
0

我正在使用MySQL,但這是一般的關係數據庫查詢。HAS_MANY與主數據庫的關係數據庫設計BELONGS_TO

我們有一個博客CMS,用戶可以在上線後更改博客的URL,並且我們想301將舊博客URL更改爲新博客。

我下面兩個表選項之間徘徊(所有領域NOT NULL):

選項1 - HAS_MANY原發性標誌

  • 網址

    • ID(PK )
    • url(UNIQUE)
    • blog_id(FK博客 - ID)
    • is_primary(0或1)
  • 博客

    • ID(PK)
    • ... 等領域 ...

缺點:可能的完整性問題其中博客沒有或多個主要網址。

優點:許多或一個類似的關係結構。

選項2 - HAS_MANY和belongs_to的混合

  • URL

    • ID(PK)
    • URL(唯一的)
    • blog_id(FK博客 - 編號)
  • 博客

    • ID(PK)
    • url_id(FK到主網址 - ID)
    • ... other_fields ...

缺點:可能的完整性問題博客的url_id和url的blog_id不匹配。

優點:保證每個博客一個主網址。


有沒有人有任何這些選項的經驗,或可以想到任何其他原因使用/打折一個或另一個?或者可能是更好的第三種選擇?

UPDATE

剛剛意識到選項2呈現的INSERT語句中不可能沒有允許空無論是在URL的blog_id或博客的url_id。

+0

什麼是'primary_flag'? –

+0

@RickJames要指示當前的活動URL,可能是一個令人困惑的術語可供選擇。 – Arth

回答

1

代替上述情況,我會考慮這樣的事情:

  • 博客

    • ID
    • url_id
  • 網址

    • ID
    • 網址
    • redirect_url_id

在這種情況下,redirect_url_id是從URL表自referntial外鍵本身。如果某個網址需要重定向,則需要將該網址中需要重定向到的URL的ID。

這樣可以避免您列出的兩個選項的缺點。唯一的缺點是,對於主URL,您只需將redirect_url_id保留爲NULL,但這是可以接受的。

絕對避免選項2無論你做什麼,雙向鑰匙 - 正如你已經注意到 - 不可行。

+0

與選項1相比,存在一些潛在的缺點1.博客的網址可能會重定向到其他博客的網址。 2.添加一個新的url涉及兩個表上的操作(或者複雜的選擇來查找博客的主要url)。 – Arth

1

如果我理解正確,博客通常有一個URL,它可能隨時間而改變。你想保留舊的URL,並重定向它。這可能會發生幾次,並且可能會有幾個舊的URL。有時博客沒有活動的URL,但它從來沒有兩個。

那麼我們先從Blog開始,因爲那是我們關心的事情。

create table blog 
(id ... primary key 
, url ... unique 
); 

現在捕捉舊網址:

create table url 
(blog_id ... 
, url ... 
, primary key (blog_id, url) 
, foreign key (blog_id) references blog(id) 
); 

如果blog.url必須是NULL,那也無妨。你只需要處理這種可能性,當你將URL加入到博客中時,你可能會得到一個NULL url來重定向到。一個完美的機會使用​​3210。 ;-)

在你的設計中,url.id沒有真正的目的,據我所知。博客與其URL不同,因此可能需要ID。舊網址OTHO只屬於他們曾經屬於的博客。給他們一個ID只是給你另一個數字拖動。

+0

謝謝,一些優秀的點,但一些額外的東西。 1.我真的希望所有的網址都在一張表中,這樣我就可以確保舊的重定向網址不是另一個博客的活動URL(我可以在插入之前使用UNION查詢)。 2.我不確定我喜歡博客的網址爲NULL並具有不活動的重定向的想法..我想我可以404它們,但爲什麼要保留它們。 3.額外的ID不是必需的,但是可以幫助我們與我們正在使用的框架進行交互。 – Arth

+1

您可以通過以下任何一種方式付費:將所有URL都放在一個表中,必須保留當前/歸檔標誌或優先級值(並且對當前使用例如max(優先級))。閱讀比寫更頻繁,我會保持與其博客的URL。觸發器可以確保沒有歸檔的URL也處於活動狀態。即使電流不爲NULL的當天爲NULL,也要保留封存的URL。 :-) –

1

由於似乎沒有任何關於URL的額外數據,爲什麼將它放在單獨的表中?

table blog 
    id (PK) 
    url (unique) 
    ...other_fields.. 

但是,URL數據可能會發生變化,您希望隨時跟蹤這些更改。太好了,現在你有充分的理由將其移動到一個單獨的表:

table blog 
    id (PK) 
    ...other_fields.. 

table URLs 
    blogID 
    url 
    EffDate 
    Primary key(blogID, url, EffDate) 

要與當前的URL顯示博客數據:

select b.ID, u.url, b.* -- the other fields 
from blog b 
join URLs u 
    on u.blogID = b.ID 
    and u.EffDate = (
      select Max(EffDate) 
      from URLs u2 
      where ur.blogID = b.ID 
       and ur.EffDate <= @today) 
where b.ID = @MyblogID; 

這個查詢的好處是,看什麼網址是在以往任何特定日期,只需用你感興趣的日期更換@today

當你的應用程序很可能會感興趣的是與當前的URL,使用查詢不where子句的視圖。對於當前的URL,查詢將是:

select * 
from Current_blogs 
where ID = @MyblogID;