【问题标题】:Database Design: Is it practical to modify table schema in runtime?数据库设计:在运行时修改表模式是否可行?
【发布时间】:2010-11-29 01:14:42
【问题描述】:

假设我有一个 products 表,其中一些字段将被保留,所有其他属性都是用户生成的可为空的列。

 (reserved)
     __
    /  \
   /    \
--------------------------------------
| id | name | color | height | width | 
--------------------------------------

与 EAV 一样,它允许任意数量的属性,但属性也可以查询。这种方法的潜在缺点是什么?

  • 如果用户在 ADD/DROP COLUMN 语句中控制的唯一内容是字段名称(将始终验证以防止删除保留字段),我们能否排除安全问题?

  • 当表变得非常大时,ADD/DROP COLUMN 语句可能会变得多么昂贵?假设我们设置了速率限制以避免用户滥用系统。

  • 从性能角度来看,单个表有多少列(可为空、非索引)过多?

【问题讨论】:

    标签: database database-design data-modeling


    【解决方案1】:

    您最好使用带有键/值对的第二个表。

    是什么让您认为第二种表方法不可查询?

    DDL 语句不能在事务中。它可能取决于您使用的数据库引擎,但如果 DDL 必须等到所有其他事务完成,和/或它会在等待其他事务完成时阻塞所有其他事务,我不会感到惊讶。换句话说,性能会很糟糕。

    【讨论】:

    • 嗯,这就是我们通常所做的,只是想知道这种替代方案可能有什么缺点。如果我将键/值对存储在单独的表中,那么我必须加入 3 个表来查询产品属性(产品、产品属性、属性值)
    【解决方案2】:

    在运行时为关系数据库动态修改架构非常昂贵,并且通常会产生一些不良影响(不是到释放东西和吃孩子的地步,而是接近;))

    所以我会考虑两种选择。

    1. 保留不同类型的通用字段名称,并使用配置数据库映射用户选择使用这些额外字段的目的,以便您在自定义报告流程中拥有适当的列标题等(我已经看到了用于多个 ERP 软件包)。

    2. 考虑使用允许存储不同对象(通常以 JSON 等格式)的非关系型数据库

    【讨论】:

    • 我不同意。考虑到用户在运行时修改和吃自己的孩子之间的选择,我必须考虑相当长的时间才能做出选择。
    【解决方案3】:

    与其向现有表中添加列,不如创建第二个表,其中包含属性的键值对,并使用 products 表的外键?这将允许产品的任意数量和种类的属性,并且可以通过在主键-外键上连接表来轻松查询。

    【讨论】:

      【解决方案4】:

      在生产中修改数据库模式是一件令人头疼的事情。 用户修改数据库模式是当有人在卡车上碾过你,然后倒退并再次击中你时,你会感到头疼的那种。

      用户在正常业务处理过程中添加到数据库的信息(包括新属性的名称)是数据,而不是模式信息,应该这样对待。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2011-07-16
        • 1970-01-01
        • 1970-01-01
        • 2017-04-26
        • 2010-10-14
        • 1970-01-01
        • 1970-01-01
        • 2014-05-27
        相关资源
        最近更新 更多