实体化视图模式 Materialized View Pattern

未匹配的标注

描述

    从一个或者多个数据存储中获取数据时,数据被格式化成方便我们查询操作的方式。这种模式可以高效查询和提取数据,并提高应用程序的性能。

背景和问题

    存储数据的时候,开发者优先考虑数据怎样存储而不是怎样获取,当查询时,可能需要从几个数据源查询才能得到所需要的信息。

解决方案

预生成符合要求的结果集表。

注意事项

  1. 考虑什么时候更新结果集。
  2. 考虑存储容量的要求和存储成本。
  3. 生成的更新结果集时,考虑数据一致性的影响。

何时使用

  1. 数据查询复杂,性能低下, 需要简化查询,提高性能时。
  2. 出于安全或隐私原因,隐藏部分细节,只提供部分聚合数据。

结构中包含的角色

  1. MaterializedView 实体化视图
  2. OrderTable 订单表
  3. OrderItemTable 订单明细表
  4. GoodTable 商品表

可用到的设计模式思维

每个表都可以抽象成一个独立的子系统,实体化视图是这些系统的前置系统,符合门面模式的概念。

最小可表达代码

class OrderTable
{
    protected $data = [
        ['id' => 1, 'order_sn' => '9527'],
    ];

    public function all() : array
    {
        return $this->data;
    }
}

class OrderItemTable
{
    protected $data = [
        ['order_id' => 1,'good_id' => 1],
        ['order_id' => 1,'good_id' => 2],
    ];

    public function all() : array
    {
    return $this->data;
    }
}

class GoodTable
{
    protected $data = [
        ['id' => 1, 'name' => '某商品A'],
        ['id' => 2, 'name' => '某商品B'],
    ];

    public function all() : array
    {
    return $this->data;
    }
}

class MaterializedView
{
    protected $orders = [];

    public function reload()
    {
        $goodIdNameMap = [];
        $allGood = (new GoodTable())->all();
        foreach ($allGood as $good) {
            $goodIdNameMap[$good['id']] = $good['name'];
        }

        $orderGoodMap = [];
        $orderItems = (new OrderItemTable())->all();
        foreach ($orderItems as $orderItem) {
            $orderGoodMap[$orderItem['order_id']][] = [
                'good_id' => $orderItem['good_id'],
                'good_name' => $goodIdNameMap[$orderItem['good_id']],
            ];
        }

        $this->orders = [];
        $orders = (new OrderTable())->all();
        foreach ($orders as $order) {
            $orderId = $order['id'];
            $this->orders[$orderId] = [
                'id' => $orderId,
                'order_sn' => $order['order_sn'],
                'good_items' => $orderGoodMap[$orderId],
            ];
        }
    }

    public function findOrderById($id)
    {
        return $this->orders[$id] ?? [];
    }
}

$materializedView = (new MaterializedView);
$materializedView->reload();
$order = $materializedView->findOrderById(1);
var_dump($order);

本文章首发在 LearnKu.com 网站上。

上一篇 下一篇
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 0
发起讨论 只看当前版本


暂无话题~