2013-10-01 20 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代码以使其知道新的文本类型。