【问题标题】:PHP MySQL table inheritancePHP MySQL 表继承
【发布时间】:2017-11-24 02:28:30
【问题描述】:

我正在实现两个对象,比如 HotDog 和 Burger,它们都是 Food 的子类。

我正在开发的系统将用于创建热狗和汉堡,可能还有其他类型的食物,但绝不会用于创建通用的“食物”对象。

食物

class Food{
    //some fields
    protected $cooked_by;
    protected $use_before_date;
}

热狗:

class HotDog extends Food{
    //some fields specicifc to HotDog
    private $sauage_type;
}

汉堡

class Burger extends Food{
    //some fields specicifc to Burger 
    private $burger_type;
}

这些模型有一个对应的 DB Table,即 Food、HotDog 和 Burger。

如果我想选择某个酋长烹制的所有 HotDog,目前我必须像这样循环遍历 HotDog 的每一行:

SELECT food_id FROM hotdog

然后遍历整个结果集,为每一行做:

SELECT * FROM food WHERE food_id = x AND cooked_by=chief0001

我希望您了解我在这里尝试构建的结构。目前必须获取每个 HotDog 行的所有 food_id,然后从食物表中逐一选择是严重的性能损失。

如果能够这样做就好了:

SELECT * FROM hotdog WHERE cooked_by = chief0001

但是,如您所见,当前实现模型和表的方式不允许我这样做。当然,我可以在 HotDog 和 Burger 表中添加另一列,但是,如果我需要查询除cooked_by 之外的任何内容,我将不得不在这两个表中添加另一列。

最后,我将把 Food 表中的所有列添加到 HotDog 和 Burger 中。

这是进行表继承的正确方法吗?我觉得这里有些不对劲,应该有一个更清洁、更好的解决方案。然而,我正在努力想出一个克服这个问题的好方法。

【问题讨论】:

    标签: php mysql inheritance


    【解决方案1】:

    一种常见的解决方案。 hotdog 和 burger 表中有特定的字段,food 表中有所有常见的字段。然后你只需加入表来获取所有字段。喜欢:

    SELECT f.*, h.* FROM food f JOIN hotdog h ON f.id = h.food_id
    WHERE f.chief_id = chief0001
    

    去买热狗。

    【讨论】:

    • 谢谢!现在我觉得自己像个不了解 SQL JOIN 的白痴,哈哈。 JOIN 操作一般很慢吗?
    • JOIN 是 SQL 的重要组成部分,因此任何好的 sql 引擎都必须为此进行很好的优化。还要确保你有 ON 子句中使用的两个字段的索引(在我们的例子中是 f.id 和 h.food_id)。它必须工作得很好:)
    • @Vadim 这个解决方案非常适用于 SQL 查询,但如果您需要经常执行涉及FoodBurgerBurger POST 操作或PUT 操作怎么办?每次都需要更新两张表,会不会对性能造成很大的影响?
    • @Vadim 作为一般规则,如果您的模型有很多共同的属性但同时又有很多不常见的属性,那么多表继承 (MTI) 是更可取的。如果不是这种情况,您可能应该实现单表继承 (STI),并在它们几乎没有不常见的属性时将它们放在同一个表中,或者根本不实现任何继承,并在它们几乎没有常见的属性时将它们保存在单独的表中。 . 另见:stackoverflow.com/questions/6073617/…
    【解决方案2】:

    对于此类问题,我通常使用两种方案。

    a) 所有元素的基表,带有 type_name 字段 - 这是对应于具体类名的字符串,以及具体类型的附加表

    你的例子:

    food:
        id
        name
        creation_time
        type_name (hamburger|hotdog) 
    
    hamburger:
        food_id
        with_cheese
    
    hotdog:
        food_id
        with_salad
    

    b) 所有元素的基表,带有 type_name 字段,同上,第二个表用于存储具体类型的值

    food:
        id
        name
        creation_time
        type_name (hamburger|hotdog) 
    
    food_options:
        food_id
        option_name
        option_value
    

    【讨论】:

      猜你喜欢
      • 2012-04-14
      • 1970-01-01
      • 1970-01-01
      • 2012-10-27
      • 2013-10-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多