"水平"与"垂直"表设计,SQL

flu*_*uke 9 php mysql database

抱歉,如果过去已经彻底涵盖了这一点 - 我已经看到了一些相关的帖子,但没有发现任何令我满意的特定情况.

我最近一直在寻找一个相对简单的游戏,大约有1万名玩家.在游戏中,你可以捕捉并培育具有某些属性的宠物(即翅膀,角,鬃毛).目前数据库中有一个表格如下所示:

-------------------------------------------------------------------------------
| pet_id | wings1 | wings1_hex | wings2 | wings2_hex | horns1 | horns1_hex | ...
-------------------------------------------------------------------------------
|      1 |      1 |     ffffff |   NULL |       NULL |      2 |     000000 | ...
|      2 |   NULL |       NULL |   NULL |       NULL |   NULL |       NULL | ...
|      3 |      2 |     ff0000 |      1 |     ffffff |      3 |     00ff00 | ...
|      4 |   NULL |       NULL |   NULL |       NULL |      1 |     0000ff | ...
etc...
Run Code Online (Sandbox Code Playgroud)

该表继续这样,目前有100多列,但一般来说,一只宠物只有大约1-8个属性.每1-2个月添加一个新属性,这需要添加表列.该表很少更新并经常阅读.

我一直在提议我们采用更垂直的设计方案以获得更好的灵活性,因为我们希望将来开始添加更大量的属性,即:

----------------------------------------------------------------
| pet_id | attribute_id | attribute_color | attribute_position |
----------------------------------------------------------------
|      1 |            1 |          ffffff |                  1 |  
|      1 |            3 |          000000 |                  2 |  
|      3 |            2 |          ffffff |                  1 |  
|      3 |            1 |          ff0000 |                  2 |  
|      3 |            3 |          00ff00 |                  3 |  
|      4 |            3 |          0000ff |                  1 | 
etc...
Run Code Online (Sandbox Code Playgroud)

老开发人员担心这会产生性能问题,因为用户经常搜索具有特定属性的宠物(即必须具有这些属性,必须至少有一个在此颜色或位置,必须具有> 30个属性).目前搜索速度非常快,因为不需要JOINS,但引入垂直表可能意味着搜索的每个属性都有一个额外的连接,并且还会使行数增加三倍左右.

我的问题的第一部分是,是否有人对此提出任何建议?我对数据库设计或优化并不是特别熟悉.

我已经针对各种情况进行了测试,但它们在很大程度上尚无定论 - 我运行的所有查询(即半秒到20秒之间)的时间变化非常大,所以我想第二部分我的问题是,在PHP中使用microtime(true)是否有更可靠的分析查询时间的方法.

谢谢.

Thi*_*ilo 17

这称为实体 - 属性 - 值 - 模型,关系数据库系统根本不适合它.

引用某人​​认为这是不要做的五个错误之一:

那么EAV的优势有哪些?好吧,没有.由于EAV表将包含任何类型的数据,因此我们必须使用适当的列将数据PIVOT到表格表示,以使其有用.在许多情况下,有中间件或客户端软件在幕后执行此操作,从而为用户提供他们正在处理精心设计的数据的错觉.

EAV模型存在许多问题.

首先,大量数据本身基本上是无法管理的.

其次,没有可能的方法来定义必要的约束 - 任何潜在的检查约束都必须包括对适当属性名称的广泛硬编码.由于单个列包含所有可能的值,因此数据类型通常为VARCHAR(n).

第三,甚至不要考虑使用任何有用的外键.

最后,查询的复杂性和尴尬性.有些人认为在必要时能够将各种数据插入单个表中是有益的 - 他们称之为"可扩展".实际上,由于EAV将数据与元数据混合在一起,因此即使对于简单的要求,操作数据也要困难得多.

EAV噩梦的解决方案很简单:分析和研究用户的需求并预先确定数据需求.关系数据库维护数据的完整性和一致性.如果没有明确定义的要求,设计这样的数据库几乎是不可能的.期.


该表继续这样,目前有100多列,但一般来说,一只宠物只有大约1-8个属性.

这看起来像规范化的情况:将表分成多个,例如一个用于喇叭,一个用于翅膀,所有都通过外键连接到主实体表.但请确保每个属性仍然映射到一个或多个列,以便您可以定义约束,数据类型,索引等.