【问题标题】:Super general database structure超通用的数据库结构
【发布时间】:2016-05-24 07:42:37
【问题描述】:

假设我有一家商店,销售属于各种类别的产品...并且每个类别都有相关的属性...例如钻头可能具有涂层、直径、螺旋角或其他。问题是我希望用户能够编辑这些属性。如果我对让用户更改属性不感兴趣,并且我正在为一组特定类别构建商店,那么我将有一个用于钻头等的表。或者,我可以只在线修改模式,但是似乎并不经常这样做(除非我们在谈论 phpmyadmin 或其他东西),而且这根本不适合模型与表的耦合方式。

一般来说,我有兴趣在 mysql.xml 中实现具有各种数据类型的多表数据库结构(因为直径可能是小数,涂层可能是表中的字符串/索引等)。知道如何做到这一点吗?

【问题讨论】:

    标签: mysql ruby-on-rails


    【解决方案1】:

    如果我正确理解您的要求,那么一个公认的 hacky 解决方案是拥有一个 products 表,该表必须与相关表 product_propertiesproduct_properties_lookup (或更好的名称),其中 @987654324 @ 为product 可以拥有的每个可能的属性都有一个条目,其中product_properties 包含属性的值,作为带有属性ID 和产品ID 的字符串。然后,您可以将属性值强制转换为您想要的任何类型。不理想,但我不确定除了为属性类型添加单个列到数据库之外还能做什么。

    【讨论】:

      【解决方案2】:

      只使用数据库。它已经完成了所有这些。免费。而且速度很快。产品表指向具有数据类型的属性表与具有列的表有何不同?它不是。如果您使用 DBs 表,您可以使用 SQL 以比您自己的方式更简洁有效的方式查询它(交叉表吸收 SQL dbs)。

      买一个新产品,做一张新桌子。没什么大不了。获取新属性,更改表。如果您在该表中有 1M 产品,是的,这可能是一个缓慢的更新(取决于数据库)。你有1M的产品吗?我不认为沃尔玛有 100 万种产品。

      在数据库之上构建数据库是一件愚蠢的事情。只需使用那里的那个。它是你手中的腻子。随心所欲地塑造它。

      【讨论】:

      • 我认为 Evan 想要在飞行中做这件事。我不会因为用户添加新属性而发布 alter table 声明感到自在。
      • 为什么不呢?数据库整天都在这样做。 Alter 表有效地锁定了该表。大不了。我刚刚更改了一个包含 630,000 行的(非平凡的)Postgres 表,添加一列需要 1 秒。删除列需要 66 毫秒。您认为这些表格中有多少项目?如果有问题,请在人流量少的地方进行。数据库可以很好地完成这一切,所以我们不必这样做。
      【解决方案3】:

      首先创建一个属性表。这将包含所有属性。它应该(至少)有一个名称列和一个类型列('string'、'boolean'、'decimal'等)。注意:所有这些表都隐含了主键。

      接下来,创建一个 CategoryProperty 表。在这里,您将能够将属性分配给一个类别。它应该有这些列:CategoryID、PropertyID。两个外键。

      然后,创建一个 Category 表。这描述了类别。它应该有一个 Name 列,可能还有其他一些列,例如 Description。

      然后,创建一个 ProductCategory 表。在这里,您将为每个产品分配类别。它应该有这些列:CategoryID、ProductID。两个外键。

      接下来,创建一个 PropertyValue 表。在这里,您将“实例化”这些属性并为其赋值。列包括 ProductID、PropertyID 和 PropertyValue。主键可以由 ProductID 和 PropertyID 组成。

      最后,创建一个产品表,用名称、价格等列来描述每个产品。

      注意每个关系如何有一个单独的表。如果您只希望每个产品有一个类别,则可以取消 ProductCategory 表,只需在 Product 表中放置一个 CategoryID 字段。同样,如果您希望每个属性只属于一个类别,您可以在 Category 表中放置一个 PropertyID 列,并去掉 CategoryProperty 表。

      最后,您将无法验证每个属性的数据类型,因为每个属性都有不同的类型(它们是行,而不是列)。因此,只需将 PropertyValue 列设为字符串,然后作为 触发器 或在您的应用程序中通过检查该属性的 Property 表的 Type 列来执行验证。

      【讨论】:

        【解决方案4】:

        如果您使用的是最新版本的 mysql(5.1.5 或更高版本),您可以将数据作为 XML 存储在数据库中。然后,您可以使用这样的方式查询该数据。

        假设我有一个包含一些项目的表,并且我有一个包含许多 小部件。我可以获得我的小部件总数:

        SELECT SUM( EXTRACTVALUE( infoxml, '/info/widget_count/text()' ) ) as widget_count 
          WHERE product_type="widgetpack"
        

        假设该表有一个 infoxml 列,并且每个 widgetpacks infxml 列都包含如下所示的 XML

        <info>
          <widget_count>10</widget_count>
          <!-- Any other unstructured info can go in here too -->
        </info>
        

        DB 纯粹主义者会对此感到畏缩,这有点 hacky。但通常更容易将所有非结构化数据保存在一个地方。

        【讨论】:

        • 我正在处理我正在进行的一个项目中的这种情况。我不喜欢的部分是我可以升级 xml 格式的唯一方法是使用 XSLT 转换......关于升级数据的更好方法的任何建议?
        【解决方案5】:

        【讨论】:

          【解决方案6】:
          猜你喜欢
          • 2011-01-10
          • 2010-10-30
          • 2012-01-04
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2013-09-13
          相关资源
          最近更新 更多