编辑1:
因为很少有好的人指出我的问题不是很清楚,我想我会改写它并让它现在更清楚。
所以基本上,我正在创建一个应用程序,它允许用户使用自己的输入字段集创建自己的表单,其中包含名称,类型等数据。创建表单并发布表单后,无论何时出现在表单中输入,数据被保存到db ofcourse中。因为表单本身是动态的。我需要一种方法来保存这些数据。
我的第一选择是JSONizing它和保存。但是因为我不能对它们进行任何SQL查询,如果我以JSON格式保存,我就会删除这个选项。
然后简单的方法存储在像(id,rowid,columnname,value)这样的表中,并且我对所有行数据保持rowid相同。但是这样,如果表单包含30个字段,则在100个条目之后,我的数据库将有3000行。所以从长远来看,它会变得很大,我认为当表中有数百万行时查询会变慢。
然后我得到了一个像(id,rowid,column1,column2 ... column100)这样的表的想法。我会将表单中的所有输入保存为单行。通过这种方式,它每次提交只添加1行,也更容易查询。我将存储实际的列名,并从那里将它们映射到右列(数字)。这是我的想法。 column100因为100是用户可以在其表单中添加的最大输入。
所以我的问题是,我的想法是否合适,还是应该坚持使用经典表格。
答案 0 :(得分:2)
如果我理解了您的问题,您需要设计一个数据库结构来存储您事先不知道其架构的数据。
这很难 - 我所知道的关系数据库中没有“高效”的解决方案。
选项1将改为查看非关系型(NoSQL)解决方案。
我不会详细说明其优点和缺点,因为它们高度依赖于您选择的NoSQL选项。 值得注意的是,许多关系引擎(包括MySQL)允许您存储和查询结构化数据格式,如JSON。我自己没有在MySQL中使用过这个功能,但SQL Server中的类似功能表现得非常好。
在关系数据库中,通用解决方案是“实体/属性/值”(EAV)架构。这有点像你的选择2.
EAV设计理论上可以存储无限数量的列和无限数量的行 - 但常见的查询很快就变得不可能。在您的示例数据中,查找名称以K开头并且功率至少为22的所有记录转变为非常复杂的SQL查询。它还意味着应用程序需要强制执行唯一性规则,强制/可选数据属性以及从一种格式到另一种格式的数据转换。
从性能的角度来看,这并不能真正扩展到复杂的查询。这是因为“where”中的每个子句都需要自联接,索引不会对非文本字符串的搜索产生很大影响(搜索数字“大于20”与搜索文本不同“大于20“。)。
选项3的确是使模式逻辑适合有限数量的列(您的选项1)。
这意味着您对列数有限制,您仍然需要在应用程序中管理强制/可选,唯一性等。但是,查询数据应该更容易 - 找到名称以K开头并且功率至少为22的帐户是一个相当简单的练习。
你确实有很多未使用的列,但这并没有真正影响性能 - 磁盘空间非常便宜,以至于所有浪费的空间都可能比你在智能手机中随身携带的空间要小。
答案 1 :(得分:0)
如果我了解您的要求,我将根据您的要求做的是创建一个多对多的关系:
(tbl1) form:
- id
- field1
- field2
(tbl2) user_added_fields:
- id
- field_name
(tbl3) form_table_user_added_fields:
- form_id (fk)
- user_added_fields_id (fk)
这可能不太可能解决您自己的要求,但我希望这会给您一个提示。快乐的编码! :)