我有这个设计。
表模型
:
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
某些字段还可以有许多值
(例如多选下拉列表)
问题是:value
始终是text
字段,因为我想存储不同类型的数据(文本、日期时间、整数),并且该表包含所有模型的所有实例。
例如,如果我有 10 个模型,每个模型有 1000 个实例和 10 个字段,则 model_field_values(至少)将包含 100000 行,如果某些字段是多个,则它将包含(120000-150000 行)。
SQL 使用 value
字段进行选择会很慢。
解决方案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.id=1 的 model_fields(按主键):1 - 文本、2 - 整数、3 - 日期时间、4 - 小文本
model_field_values_1 的字段:field_1 文本、field_2 整数、field_3 日期时间、field_4 varchar(256)
此解决方案不适用于具有多个值的字段,因为每个 multiple
值应该有另一个表,链接到 model_field_values_1 中的行,但它适合搜索数据库,因为 mysql 将使用 native where 子句中的数据类型(不是文本字段)。
我可能错过了什么吗?也许有更好的设计?
该数据库将在 crm 系统中使用,用户可以在这些模型中创建具有多个实例的不同模型,因此我无法预先配置包含所有列的所有表。
最佳答案
注意:在 MySQL 的通常操作中,200,000 行(兆行的十分之二)是一个中等大小的表。通常可以相当有效地对这样的表建立索引。 http://use-the-index-luke.com/
话虽这么说,我认为我理解你的问题。用面向对象设计的术语来说,它就是多态性。
您有这个model_field_value
表,其中包含
instance_id
field_id
value
您的问题是,该值的 native 数据类型有时是 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
列上放置索引,这样您就可以对这些类型的查询进行控制。
只是一个想法。
关于mysql - 多个模型的数据库设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42844770/