【问题标题】:Database design to create tables on the fly动态创建表的数据库设计
【发布时间】:2012-08-21 02:30:59
【问题描述】:

我需要在数据库中动态创建动态表。例如,在数据库中,我将有名为:

Table
Column
DataType
TextData
NumberData
DateTimedata
BitData

在这里,我可以在名为 table 的表中添加一个表,然后我可以在 columns 表中将所有列添加到该表中,并将数据类型与每一列相关联。

基本上我想创建表而不实际在数据库中创建表。这甚至可能吗?如果是这样,您能指导我到正确的地方以便我进行研究吗?另外,我更喜欢 sql server 或任何免费的数据库软件。

谢谢

【问题讨论】:

  • 您知道它将如何处理 1000 条条目吗?另外,我不知道这些列将是什么。
  • 是的 - 它会将数千个条目复制到临时表中,你真正的问题是什么
  • 此动态表将加载到可能包含 1000 或数百列和条目的网页上。恐怕表演时间太长了。基本上,我不知道针对此类问题的良好数据库设计。
  • 卢克,您是在寻求特定解决方案的帮助,而不是如何解决问题的帮助。您的解决方案无疑存在缺陷(没有难过的感觉),因此您可能希望发布有关实际问题的更多信息以获得更好的解决方案。
  • 对于 PostgreSQL,这可以使用 hstore 数据类型有效地实现并避免 EAV(反)模式。

标签: mysql sql sql-server oracle postgresql


【解决方案1】:

您所描述的是entity-attribute-value model (EAV)。这是设计数据模型的一种非常糟糕的方式。

虽然数据模型相当灵活,但查询这样的数据模型却相当复杂。如果您想选择或过滤n 不同的属性,您经常不得不自加入表n 次。这变得缓慢而缓慢,并且相对较快地变得相当难以优化。

另外,您通常最终会构建数据库或 ORM 将提供的许多功能。

【讨论】:

  • PostgreSQL 的 hstore 功能提供了一种方法来做这件事。 hstores 基本上是字符串字典,即键/值映射,就像任何其他数据类型一样存储在数据库字段中。见postgresql.org/docs/current/static/hstore.html。这比 EAV 好多了。
【解决方案2】:

我不确定您遇到的真正问题是什么,但您提出的解决方案是“数据库中的数据库”反模式,这让很多人感到畏缩。

根据您查询数据的方式,如果您要按照您的计划构建事物,您要么需要一堆分段查询,这些查询连接在中间件中(慢),要么需要一个庞大的整体查询(缓慢或造成大量索引膨胀),如果有可能的话。

如果您必须即时创建表,请了解您正在使用的特定数据库引擎的 CREATE TABLE ALTER TABLEDROP TABLE DDL 语句。更好的是,找到一个可以为您执行此操作的 ORM。如果您的真正问题是需要存储非结构化数据,请查看 MongoDB、Redis 或其他一些 NoSQL 变体。

我的最后一个建议是将你试图解决的实际问题写成一个单独的问题,这样你可能会学到更多。

【讨论】:

    【解决方案3】:

    对文档执行此操作可能会更容易。或许你应该看看像mongoDB 这样的noSQL 解决方案。

    【讨论】:

    • 另外,MongoDB 是网络规模的!
    • Eesh...我认为如果数据库讨论存在戈德温定律的变体,“网络规模”将是值得的短语...
    • @BenBurns:“web scale”在“bullshit bingo”中也能获得高分;)
    • 公平地说,MongoDB 可以处理具有1,000100k 记录的表,而 MySQL 不能。
    • 对不起@CraigRinger,我认为你不太明白。我的评论是讽刺的。我很清楚 RDBMS 可以很好地处理大量记录。我和他们一起工作,有许多表,记录数以亿计。如果您阅读链接的 cmets,我会说没有必要更改为 NoSQL 解决方案而不是 RDBMS,因为表中有 10 万条记录。
    【解决方案4】:

    或者您仍然可以创建临时表,但使用 cronjob 并每隔 %% 小时创建一次临时表,并在查询完成后将其重命名为正确的名称。所以你的网站还在空中

    您尝试归档的内容还不错,但您必须以正确的逻辑方式使用它。

    *对不起我的英语不好

    【讨论】:

      【解决方案5】:

      我在 LedgerSMB 中做了类似的事情。虽然我们将 EAV 建模用于一些事情(需要灵活性并且我们正在执行的查询类型是直接的,例如菜单节点部分使用它),但一般来说,您希望尽可能远离这种情况尽可能。

      更好的方法是执行您正在执行的所有操作,但数据列除外。然后你可以(震惊)创建表格。这会为您提供一个已添加内容的目录,以便您的应用知道这一点(如果您需要检查,您可以从系统目录中进行区分!),但同时您可以获得实际的关系建模。

      我们在 LedgerSMB 中所做的是让存储过程接受表名存在('extends_' || 提供的名称)。如果是这样,将添加一个具有所需数据类型的列并将其写入应用程序目录。这为我们提供了扩展属性的关系建模。在加载时,应用程序加载应用程序目录并在适当的点写入查询以加载/保存数据。实际上,它工作得很好。

      【讨论】:

        猜你喜欢
        • 2015-06-24
        • 1970-01-01
        • 2011-01-22
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-03-23
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多