[英]Database design for multiple models?
I have this design. 我有这个设计。
Table models
: 桌子models
:
id - primary key
title - varchar(256)
Table model_instances
: 表model_instances
:
id - primary key
model_id - foreign key to app_models.id
title - varchar(256)
Table model_fields
: 表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']
Table model_field_values
: 表model_field_values
:
instance_id - forein key model_instance.id
field_id - foreign key to model_fields.id
value - text
Also there can be many values
for some field (like for multiple select dropdown) 此外,某些字段可能有很多values
(例如,多选下拉列表)
The problem is: value
is always text
field, because I want to store different types of data (text, datetime, integer) and this table contains all values for all instances of all models. 问题是: value
始终是text
字段,因为我想存储不同类型的数据(文本,日期时间,整数),并且此表包含所有模型的所有实例的所有值。
For example, if I have 10 models and every model has 1000 instances with 10 fields then model_field_values (at minimum) would contain 100000 rows, if some fields are multiple, then it would contain (120000-150000 rows). 例如,如果我有10个模型,而每个模型有1000个实例,其中包含10个字段,则model_field_values(至少)将包含100000行,如果某些字段为多个,则它将包含(120000-150000行)。
SQL's select using value
field would be slow. SQL的使用value
选择字段会很慢。
Solution 1: 解决方案1:
For every model create new model_field_values like:
model.id = 1, model_field_values_1
...
model.id = 10, model_field_values_10
Solution 2: 解决方案2:
Because model_fields contains all fields for model, we can create model_field_values like this 因为model_fields包含模型的所有字段,所以我们可以像这样创建model_field_values
model_fields for model.id=1 (by primary key): 1 - text, 2 - integer, 3 - datetime, 4 - smalltext model.id = 1的model_fields(通过主键):1-文本,2-整数,3-日期时间,4-小文本
Fields for model_field_values_1: field_1 text, field_2 integer, field_3 datetime, field_4 varchar(256) model_field_values_1的字段:field_1文本,field_2整数,field_3日期时间,field_4 varchar(256)
This solution is not good for fields with multiple values, because every multiple
value should have another table with link to the row in model_field_values_1, but it is good for searching through database because mysql would use native datatypes in where clauses (not text fields). 该解决方案不适用于具有多个值的字段,因为每个multiple
值都应具有另一个表,该表具有链接到model_field_values_1中的行的链接,但是它对数据库的搜索非常有用,因为mysql会在where子句(而非文本字段)中使用本机数据类型。
May be I miss something? 可能我想念什么吗? May be there is a better design? 可能会有更好的设计?
This database would be used in crm-system, where user can create different model with many instances in these models, so I can not preconfigure all tables with all columns. 该数据库将在crm系统中使用,在该系统中,用户可以使用这些模型中的许多实例创建不同的模型,因此无法对所有具有所有列的表进行预配置。
Note: 200,000 rows (two tenths of a megarow) is, in the usual operation of MySQL, a medium sized table. 注意:在MySQL的常规操作中,200,000行(兆行的十分之二)是一个中等大小的表。 It's generally possible to index such a table fairly efficiently. 通常可以相当有效地为这样的表建立索引。 http://use-the-index-luke.com/ http://use-the-index-luke.com/
That being said, I think I understand your problem. 话虽如此,我想我理解您的问题。 It is, in the jargon of object-oriented design, polymorphism. 在面向对象设计的术语中,它是多态。
You have this model_field_value
table, containing 您有此model_field_value
表,其中包含
instance_id
field_id
value
Your problem is, the value's native data type is sometimes VARCHAR(255)
, sometimes DATETIME
or maybe TIMESTAMP
, and sometimes INT
. 您的问题是,值的本机数据类型有时是VARCHAR(255)
,有时是DATETIME
或TIMESTAMP
,有时是INT
。
And you'll sometimes need to do queries like this one 而且有时您需要执行类似这样的查询
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'
to find DATETIME
values that happened in calendar year 2017. For example. 查找在2017日历年中发生的DATETIME
值。例如。
This is generally a pain in the neck with key/value storage like what you need. 像您需要的那样,键/值存储通常会给您带来麻烦。 For a query like my example to be sargable , you need to be able to put an index on a DATETIME
column. 对于像我的例子查询要优化搜索 ,你需要能够把指数上DATETIME
列。 But if you don't have such a column, you can't index it. 但是,如果您没有这样的列,则无法为其编制索引。 Duh. 咄。
Here's a suggestion. 这是一个建议。 Give your table these columns. 给您的表这些列。
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
This table will contain redundant data, and you'll have to be very careful when you're writing it to make sure it's correct. 该表将包含冗余数据,并且在编写时必须非常小心以确保其正确。 But you will be able to put indexes on the value_ts
and value_double
columns, so you can make those kinds of queries sargable. 但是您将能够在value_ts
和value_double
列上放置索引,因此可以使这类查询成为可查询的。
Just an idea. 只是一个主意。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.