我有这个设计。
表models
:
id - primary key
title - varchar(256)
表model_instances
:
id - primary key
model_id - foreign key to app_models.id
title - varchar(256)
表model_fields
:
id - pk
model_id - foreign key to models.id
instance_id - foreign key to model_instances.id
title - name of the field
type - enum [text, checkbox, radio, select, 'etc']
表model_field_values
:
instance_id - forein key model_instance.id
field_id - foreign key to model_fields.id
value - text
对于某些字段,也可能有许多values
(例如多个选择下拉菜单)
问题是:value
始终是text
字段,因为我想存储不同类型的数据(文本,日期时间,整数),此表包含所有模型的所有实例的所有值。
例如,如果我有10个模型,每个模型有1000个实例,10个字段,那么model_field_values(至少)将包含100000行,如果某些字段是多个,那么它将包含(120000-150000行)。
使用value
字段进行SQL选择会很慢。
解决方案1:
For every model create new model_field_values like:
model.id = 1, model_field_values_1
...
model.id = 10, model_field_values_10
解决方案2:
因为model_fields包含模型的所有字段,所以我们可以像这样创建model_field_values
model.fields for model.id = 1(按主键):1 - 文本,2 - 整数,3 - 日期时间,4 - smalltext
model_field_values_1的字段:field_1 text,field_2 integer,field_3 datetime,field_4 varchar(256)
此解决方案不适用于具有多个值的字段,因为每个multiple
值都应该有另一个表,其中包含指向model_field_values_1中行的链接,但它有利于搜索数据库,因为mysql将使用本机数据类型从句(不是文本字段)。
我可能会错过什么?可能有更好的设计吗?
此数据库将在crm-system中使用,用户可以在这些模型中创建具有多个实例的不同模型,因此我无法预先配置所有列的所有表。
答案 0 :(得分:0)
注意:在MySQL的通常操作中,200,000行(megarow的十分之二)是一个中等大小的表。通常可以相当有效地索引这样的表。 http://use-the-index-luke.com/
话虽如此,我认为我理解你的问题。在面向对象设计的术语中,它是多态的。
你有这个model_field_value
表,包含
instance_id
field_id
value
您的问题是,该值的原生数据类型有时为VARCHAR(255)
,有时为DATETIME
或TIMESTAMP
,有时为INT
。
你有时候需要做这样的查询
SELECT fv.instance_id
FROM model_field_value fv
WHERE fv.field_id = something
AND fv.value >= '2017-01-01'
AND fv.value < '2018-01-01'
查找2017日历年中发生的DATETIME
值。例如。
这通常是颈部疼痛的关键/值存储,就像你需要的那样。对于像我的示例sargable这样的查询,您需要能够在DATETIME
列上放置索引。但是,如果您没有这样的列,则无法将其编入索引。咄。
这是一个建议。给你的表这些列。
instance_id INT pk fk
field_id INT pk fk
value VARCHAR(255) a text representation of every value.
value_double DOUBLE a numeric representation of every numeric value, or NULL
value_ts TIMESTAMP a timestamp value if possible, or NULL
此表格将包含冗余数据,您在编写时必须非常小心,以确保其正确无误。但是您可以在value_ts
和value_double
列上放置索引,这样您就可以进行这类查询。
只是一个想法。