mysql - 多个模型的数据库设计?

标签 mysql database-design

我有这个设计。

模型:

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),有时是 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 列上放置索引,这样您就可以对这些类型的查询进行控制。

只是一个想法。

关于mysql - 多个模型的数据库设计?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42844770/

相关文章:

php - 一种更有效的为枢轴构建数据库的方法

ruby-on-rails - 这是有效的数据库设计还是外键太多?

mysql - 使用 MySQL 创建简单修订系统的最佳方法是什么?

mysql - 在 MySQL 数据库中存储用户名和密码的最佳实践

mysql - 使用 Prisma 的 MySQL 锻炼应用程序架构

php - 将一个简单列表插入 MySQL 表 (php)

php - OrderBy Coupons 基于过期状态 Laravel

php - 如何搭建一个带有倒计时功能的mysql排队系统?

php - 用于检查 MySQL 的 JavaScript 时间戳

php - 从日期范围查找可用房间