2013-10-01 39 views
3

如果我保存這樣我的產品:PHP:高效的方式來使用對象作爲產品數據庫

tbl_products 
id, price, stock 
1, 20, 5 
2, 30, 5 

而且文本是在另一個表:

tbl_texts 
id, item_id, type, field, value 
1, 1, 'product', 'name', 'Programming Book' 
2, 1, 'product', 'description', 'A fine book' 
3, 2, 'product', 'name', 'Bicycle' 
4, 2, 'product', 'description', 'Goes very fast' 

而且競選價格在另一張桌子上:

tbl_product_campaign_prices 
id, item_id, price, valid_from, valid_to 
1, 1, 5, null, null 
2, 2, 10, null, 2014-10-10 

好的,這裏有我想象中的桌子。

我想將產品作爲對象處理,因爲我並不總是希望獲得與產品相關的所有數據,因爲它的數據庫很重,我很少需要訪問所有數據。

例如,有時我只需要產品的名稱或描述。有時我需要競選價格。 tbl_products上的基本信息將始終提取。

真正的問題是,我的代碼選項是什麼?我想出了幾個:

1.

$product_id = 1; 
$fetch_name = 1; 
$fetch_description = 0; 
$fetch_campaign_prices = 0; 
$product = ProductFactory::get($product_id, $fetch_name, $fetch_description, 
      $fetch_campaign_prices); 

// This takes a lot of space and is very impractical 
// when I have to add new data to be fetched. 

// Worst case would be having to add a bunch 
// of null, null, null to get the last data. 

2.

// Same as 1. but adding all the $fetch_ into an array and only use 2 parameters on the 
// get() function. 

$product = ProductFactory::get($product_id, $fetch_array); 

// Still pretty ackward way to fetch data but much easier to add stuff 
// since I don't have to add any new parameters 

3.

$data_to_fetch = array('name', 'description'); 
ProductFactory::Prepare($data_to_fetch); 
$product = ProductFactory::get($product_id); 

有沒有做到這一點的常用方法?一個有效的方法來做到這一點?我從來沒有做過這樣的事情,這些都來自我的頭頂。

感謝您的即將來臨的輸入!

+1

選項#4 - 以設置錯誤級別或排序標誌的方式傳遞一組位圖標誌:'$ product = ProductFactory :: get($ product_id,FETCH_NAME | FETCH_PRICES);' –

+1

Mark有正確的願景。 @MarkBaker,你爲什麼要發表評論?解決問題的最佳方法是使用位掩碼。 –

+0

@Michael - 主要是因爲我認爲,如果我可以用比tweet更少的字符回答問題,它只能作爲評論 –

回答

0

基本上你在問如何表達一小組配置標誌的子集。這與你正在使用的數據庫非常相關。

  1. 使用單獨的參數:難以維護,在一個地方的變化將需要在所有地方的變化。如果沒有合理的默認值,這可能是有意義的。在這種情況下,呼叫失敗可能比錯誤的事情更好。

  2. 使用一個有序的參數數組非常難看,因爲您必須記住訂單的含義,並且更難以分辨何時發生呼叫不正確。不要這樣做。

  3. 名單列表:非常靈活,易於閱讀。這可能是python的方式來做事情。但是檢查包含哪些值以及哪些值不需要進行字符串比較,因此這可能有點貴。雖然可能不超過中等數據庫查詢。要考慮的一件事是,是否檢查被調用函數不知道的名稱。您可能會報告這些錯誤以避免拼寫錯誤,或者您可能會選擇忽略它們。向前兼容性。

  4. 位掩碼:正如Mark Ba​​ker指出的那樣,您可以定義許多具有可讀名稱和值的常量,這些常量的值是2的冪。你可以或者使用|來形成一個單一的值。然後,您可以使用按位並從函數中的組合值中提取單個位。這是C做事的方式。它具有高性能,低拼寫錯誤的風險。但它可能會用這些符號常量來打破你的命名空間。

  5. 配置對象:您可以爲傳遞給該函數的參數定義一個類。你可以讓安裝者設置各種標誌。最重要的是,你會有一個可以設置默認值的構造函數。所以這裏最關鍵的好處就是你可以建立合理的默認值,即使某些東西應該被默認提取而其他人不應該,並且不需要調用像FETCH_FOODONT_FETCH_BAR這樣的常量名。

我會去4.

0

首先,我想這是一個假設的例子 - 但要小心,你的性能和複雜性之間做出權衡 - 你可能會發現, PHP代碼中的額外複雜性成爲維護問題。反過來,你也可能發現額外的PHP代碼超過了不加載額外數據的好處。其次,大多數對象關係映射框架解決這個問題的方式是通過「延遲加載」。 ORM只會在需要時從您的廣告系列價格表中加載數據;這對開發人員來說通常是透明的。

當然,這並不適用於您的「文本」表,它實際上是一個實體屬性值存儲。在這種情況下,這取決於您的文本模式的固定程度。如果你知道你總是有「名稱」和「描述」,你可以將其硬編碼爲一個位掩碼。然而,這種設計會隨着時間的推移而增長(否則,您會更好地在產品表上添加「名稱」和「描述」列)。在這種情況下,我會堅持將文本類型作爲字符串參數傳遞 - 「名稱」,「描述」。這意味着當您添加新的文本類型 - 「shortDescription」時 - 您不必重新訪問productFactory代碼以使其知道新的文本類型。