介绍
我一直在阅读有关EAV数据库的信息,而大多数缺点似乎都与EAV设计确实非常糟糕或很难从数据中生成报告有关。
通常,当您看到人们抱怨EAV时,他们使用少于三个的表来尝试复制RDBMS中单独的表+列的功能。有时,这意味着将所有内容(从小数到字符串)都存储在单个TEXT值列中。EAV还会破坏数据完整性的安全保护措施,如果您不小心的话,这可能会很糟糕。
但是,EAV确实提供了一种轻松的方式来跟踪历史数据,并允许我们在SQL和键值存储系统之间来回移动系统的某些部分。
如果我们根据类型区分不同的实体属性该怎么办。除了与特定属性和实体相关的正确索引值之外,这还使我们仍然可以处理belongsTo,Has,HasMany和HasManyThrough关系。
考虑以下两个基本实体
products (price -> decimal, title -> string, desc -> text, etc...)
attributes
options
[...]
int
datetime
string
text
decimal
relation
[id,foreign_key]
users (gender -> options, age -> int, username -> string, etc...)
attributes
options
[...]
int
datetime
string
text
decimal
relation
[id,foreign_key]
RDBMS架构设计
众所周知,用户资料和产品是世界上最多样化的产品。每个公司处理它们的方式都不一样,并且针对他们的需求具有不同的“列”或“属性”。
以下是如何处理多个(嵌套和/或关系)实体的视图。
想法是,对于每个实体都有此主属性表,然后该主表指定如何查找和解释这些值。这使我们能够处理特殊情况,例如指向其他实体的外键以及诸如“选项”或十进制数字之类的东西。
查询样例
首先,实体是什么“类型”?(用户,帖子,评论等。)
SELECT * FROM entity_type et LEFT JOIN entity e ON e.entity_type_id = et.id WHERE e.id = ?
接下来,该实体的属性是什么?(表属性)
SELECT * FROM attr WHERE entity_id = ?
接下来,此实体的属性中存在哪些值?(attr _ ###表)
SELECT * FROM attr_option, attr_int, attr_relation, attr_text, ... WHERE entity_id = ?
vs
SELECT * FROM attr_option WHERE entity_id = ? if( ! multiple) ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_int WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_relation WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
SELECT * FROM attr_text WHERE entity_id = ? ORDER BY created_at DESC LIMIT 1
...
该实体存在什么关系?
假设我们有一个ID为34的“发布”实体,并且我们想要它的“注释”(entity_type = 2),这可以允许我们在产品实体上获取评论实体ID:
SELECT * FROM entity AS e
LEFT JOIN attr_relation AS ar ON ar.entity_id = e.id
WHERE ar.entity_id = 34 AND e.entity_type = 2;
除了多个查询(无论如何,键值存储都需要这些查询)之外,这种方法还会存在哪些问题?
慕姐4208626
人到中年有点甜
慕妹3242003
相关分类