如何在关系数据库中有效地存储无模式数据?

tec*_*nce 7 mysql schema database-design

我试图在可搜索性和速度之间取得很好的平衡。我正在尝试不同的方法。

选项 1:将数组序列化为 JSON/PHP 序列化数组并将其存储在“元”列中。

   id  |  name   | meta  
1       Bob       {"city":"GoTown","birthdate":"1980\/8\/14","cat":"Felix"}
2       Alice     {"city":"Streamville","birthdate":"1986\/6\/6","dog":"Rex"}
Run Code Online (Sandbox Code Playgroud)

选项 2:将键和值一起存储在堆栈中。

user_id  |    key   |   value   
1         name       Bob
1         city       GoTown
1         birthdate  1980/8/14
1         cat        Felix
2         name       Alice
2         city       Streamville
2         birthdate  1986/6/6
2         dog        Rex
Run Code Online (Sandbox Code Playgroud)

选项 3:3 个表:实体、键、值。每个键名只存储一次。

user_id  |   name   
1         Bob
2         Alice

key_id   |   keyname   
1         city
2         birthdate
3         cat
4         dog

user_id   |   key_id   |   value
1          1            GoTown
1          2            1980/8/14
1          3            Felix
2          1            Streamville
2          2            1986/6/6
2          4            Rex
Run Code Online (Sandbox Code Playgroud)

使用这些策略有什么陷阱吗?如果它们有无法克服的缺点,我想消除其中的一些。

编辑:添加了一些数据来表示无模式数据

Ray*_*and 4

这些表会发生一些非常讨厌的问题(想法)

  1. 数据冗余(重复的数据),你需要保持同步(你会检查这个,因为 MySQL 没有一个很好的 JSON 记录功能?)

  2. 您不能在数据库上强制使用正确的值(对数据完整性说再见,向垃圾输入垃圾输出数据问好)示例键生日可以具有值“hello”

并且您需要某种类型的数据透视查询来获取键/值

如果您确实需要动态键值 (EAV) 存储,还有更多选择: