多个模型的数据库设计?

时间:2017-03-16 21:05:30

标签: mysql database-design

我有这个设计。

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中使用,用户可以在这些模型中创建具有多个实例的不同模型,因此我无法预先配置所有列的所有表。

1 个答案:

答案 0 :(得分:0)

注意:在MySQL的通常操作中,200,000行(megarow的十分之二)是一个中等大小的表。通常可以相当有效地索引这样的表。 http://use-the-index-luke.com/

话虽如此,我认为我理解你的问题。在面向对象设计的术语中,它是多态的。

你有这个model_field_value表,包含

 instance_id
 field_id
 value

您的问题是,该值的原生数据类型有时为VARCHAR(255),有时为DATETIMETIMESTAMP,有时为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_tsvalue_double列上放置索引,这样您就可以进行这类查询。

只是一个想法。