2016-01-03 91 views
0

你好我是相當新的數據庫和有設計問題/問題。SQL數據庫設計外鍵

我有一張名爲「產品」的表,其中包含以下各列,並存儲有關產品的信息以及三篇文章的相對較大的圖片。

id = primary key 
product_id = int 
product_name = varchar 
product_description = text 
image1_name = varchar 
image1_data = longblob 
image2_name = varchar 
image2_data = longblob 
image3_name = varchar 
image3_data = longblob 

我也有我的網站上,這是爲了顯示五張圖片,我作爲該網站的管理員可以選擇與它顯示產品名稱jQuery的動畫幻燈片元素。

爲此我想到了創建持有不超過五個條目,基本上指向任何imagedata1,imagedata2或imagedata3和產品

id = primary key 
product_name = product.product_name 
imagedata = imagedata 1 or 2 or 3 

的PRODUCT_NAME據我知道有第二臺幻燈在SQL中沒有指針。這是如何實現的?我必須改變我的設計嗎?

回答

0

這種情況可以有兩種方法。

  1. 1nF的
  2. 3NF或BCNF

1NF:

一個表一樣的你: 只需添加一列,說明滑數爲您的產品。 5列爲您的圖像名稱。 如果要存儲的圖像數據庫,然後5個colums與BLOB數據類型

3 NF:

1表產品的詳細信息

product_id = int (primary key) 
product_name = varchar 
product_description = text 

第二表格圖像信息

id (primarykey) 
product_id (foreign key) 
slider_image_name varchar 
image_sequence int 
imagedata (only if you want to store image in database) 
image_status (tinyint) [1 for active o for inactive] 

我更喜歡以文件格式保存圖像並存儲完整的網址以加載數據庫。 櫃面你也想通過URL來加載它,那麼你可以刪除的圖象 - 列

3NF或BCNF形式更prefred

+0

我認爲這個答案是最有意義的,因爲它考慮到一個產品有很多圖像,並且有必要有一個布爾變量來表示該圖像是否是幻燈片的一部分/按照它出現的順序。 – frankBang

0

我最初的想法是你會有兩張桌子。

-- product table -- 
id = primary key 
product_id = int 
product_name = varchar 
product_description = text 

-- product_image_table -- 
id = primary key 
product_table_id = {product table id} 
image_name = varchar 
image_data = longblob 

然後在您正在考慮的新表上,將在product_image_table中引用記錄,並可能在產品表中引用記錄。這樣做的好處在於,您不必限制在產品表上可以存儲多少圖像,並且如果您需要存儲更多的圖像,則不必添加更多的列,並且對於產品數量少於你最大的圖像數量。

0

讓我們想想,目前需要在幻燈片放映3個圖像的產品,但是,明天你可能需要1個,或者你可能需要5個特定產品,那麼顯然你的設計不夠靈活或過於靈活。

那麼...這裏的正確模型是什麼?

One-To-many

這將允許你最大的靈活性W/O任何冗餘列

認爲它是一個產品有許多圖像,你將如何模型?

您當前的產品表將沒有圖像的知識,您將添加一個新的表,稱爲product_images

product_images 
id | int 
product_id | int 
image_url | varchar 

,所以如果你有一個產品,你可以做另一個查詢爲它的圖像

SELECT * FROM product_images WHERE product_id = ? 

或接受某些產品的所有圖像

SELECT * FROM product_images WHERE product_id IN (?) 

額外:讓我們說你有很多車型需要圖像功能,你可以創建一個polymorphic table名爲images,一張桌子它不僅包含REFERENCE_ID,而是一個額外的列其中也有reference_type

images 
id | int 
reference_id | int 
reference_type | varchar 
image_url | varchar 

現在如果你有一個產品,你可以爲它的圖像

SELECT * FROM product_images WHERE reference_id = ? and reference_type = 'product' 

或接受某些產品的所有圖像做一個查詢

SELECT * FROM product_images WHERE reference_id IN (?) AND reference_type = 'product' 

當然,您可以隨心所欲地查詢另一個reference_type。

0

幾乎總是要把設計正常化。規範化的目的是最小化進入數據庫的異常數據。例如,你想讓它不可能插入第四行,只有三行是允許的。在行定義中創建三對列也可以實現這一點,但是會以額外的未使用空間和未來增強的嚴格限制爲代價。

關係基數一直存在限制。我們可以自然地定義一對多的關係(實際上:1到零或更多),但我們不能在本地定義1對3的關係(1到0或更多到3)。

因此,當我們必須在原生關係定義之外實現一個功能時,我們會做我們經常做的事情:我們作弊。

有很多方法可以在這裏作弊,當然,每個人的優點和缺點。我最喜歡的是繼續前進,創造一個1米表一點點額外的約束:

create table ProductImages(
    ProdID int not null, 
    Card  tinyint not null, 
    Name  varchar not null, 
    Image longblob not null, 
    constraint PK_ProductImages primary key(ProdID, Card), 
    constraint CK_CardRange check(Card between 1 and 3), 
    constraint FK_ProdImageProd foreign key(ProdID) 
     references Products(ID) 
); 

的優點在這裏是你得到你想要的東西,即與任何特定相關的零,1,2或3張圖片產品。

的缺點是

  • 你必須以編程方式確定的基數的值:1,2或3。這不能自動生成。
  • 基數值必須介於1和3之間,但可以按任何順序插入,也可以缺少值。

由於缺點,這些很容易在應用程序代碼中處理。你保留了正常化的所有好處。