我们正在开发一个大型内部项目,使用户能够上传excel文件,并最终对从这些Excel中收集的所有数据执行搜索.在开始设计之前,我正在尝试做功课,并提出最佳解决方案.
要求是 –
>用户可以根据需要上传包含尽可能多列的Excel文件,因此excel没有预定义的结构.
>与第一点相反,我们假设用户拥有一些字段.例如 – 名字,姓氏.这些列不一定存在.
>搜索选项将如下工作 – 当用户搜索时,他可以按特定列搜索 – 预定义的列,我们期望他的excel文件具有. (在我们的例子中 – 名字和姓氏).
他还可以在“其他”字段下搜索所有其他列.
关于其他搜索字段的另一个词 – 此字段将遍历所有不符合预定义列的Excel文件中的所有列. I.E – 一个文件有一个年龄列,另一个文件有一个出生地列,“其他”字段将搜索所有这些列.
最好的方法是什么?
>为每个上传的excel动态创建一个新的django模型,其中包含excel的所有列?
>为每个文件动态创建一个新的django模型,包含所有预定义的列(如果它们存在!),以及一个“其他”文本字段,它将连接所有不相关的字段?
>有一个大的django模型(在我的数据库中只有1个表),它有我所有的预定义字段(也可以是null),还有一个名为“others”的字段,它将连接所有不相关的列?
>我可以让我的主表具有所有预定义列,另一个表具有主表的外键,其中每行代表一个“其他”字段.
第四种解决方案的示例 –
+----+--------+--------+--------+
| id | field1 | field2 | field3 |
+----+--------+--------+--------+
| 1 | val1 | val1 | val1 |
| 2 | val2 | val2 | val2 |
| 3 | val3 | val3 | val3 |
+----+--------+--------+--------+
和尺寸表 –
+----+------+------+
| fk | key | val |
+----+------+------+
| 1 | key1 | val1 |
| 1 | key2 | val2 |
| 1 | key3 | val3 |
| 2 | key4 | val4 |
+----+------+------+
至于缩放 – 我们预计最终不会有超过1500个excel文件,每个文件包含100到大约100个. 100,000行(我们可能会将每个excel文件的行数限制为100k).我们从excels中得到的统计数据表明,我们不会超过3000万行.
我们将使用Django与MySQL或PostgreSQL.
我希望我的问题很明确,而且不是太不透明.
谢谢!
最佳答案 编辑:你改变了你的问题.我在你的模型4上添加了一个简短的部分.
我强烈建议不要动态创建表.这很麻烦,我怀疑它会表现良好.您的数据库将为您将查询的每个数据库表创建一个访问路径,因此如果您创建多个数据库文件,则需要搜索所有这些数据库.
您可能需要模型3的变体.
这意味着您使用一个表,但是为每个字段使用列,您可以为excel列名创建一个列,为其值创建一个列.您还需要一些其他条目来标识哪个Excel列和值属于哪个Excel电子表格.
从概念上讲,而不是建模:
field1 field2 field3 field4 other
------------------------------------
x y z a etc=xyz
你这样建模:
sheet fieldname value
------------------------------------
key field1 x
key field2 y
key field3 z
key field4 a
key etc xyz
这种模式的优点是编程搜索变得更容易.您可以将任何搜索简单地建模为select * from data where fieldname =’%s’和value =’%s’.如果在fieldname上创建数据库索引(可能是用于标识excel表的键的索引),那么对于模型3的原始概念应该没有性能损失.
你的模型4也可以.它的优点是,对于预定义字段,用户的查询语句可以轻松映射到SQL select语句.它的缺点是您需要以与用户搜索条件的其余部分不同的方式处理“其他”列.您还指出用户有时不会输入您希望在那里的列.这意味着您必须使这些列可以为空,这会增加存储要求.
总的来说,我认为我建议的方法比你的选项4更好,因为它在概念上更简单.您表示您认为它会创建太多行.事实上,这将创建更多的行,但MySQL和PostgresSQL可以很容易地创建行数. PostgresSQL可以存储无限数量的行. MySQL可以存储4000到10000行(如果需要更多,你可以使用–big-tables编译MySQL).
在性能方面,只要你在该领域有一个索引,你的桌子有多大就没有什么区别.