实体化视图模式 Materialized View Pattern
描述
从一个或者多个数据存储中获取数据时,数据被格式化成方便我们查询操作的方式。这种模式可以高效查询和提取数据,并提高应用程序的性能。
背景和问题
存储数据的时候,开发者优先考虑数据怎样存储而不是怎样获取,当查询时,可能需要从几个数据源查询才能得到所需要的信息。
解决方案
预生成符合要求的结果集表。
注意事项
- 考虑什么时候更新结果集。
- 考虑存储容量的要求和存储成本。
- 生成的更新结果集时,考虑数据一致性的影响。
何时使用
- 数据查询复杂,性能低下, 需要简化查询,提高性能时。
- 出于安全或隐私原因,隐藏部分细节,只提供部分聚合数据。
结构中包含的角色
- MaterializedView 实体化视图
- OrderTable 订单表
- OrderItemTable 订单明细表
- 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);
推荐文章: