【问题标题】:database table design for some unknown data一些未知数据的数据库表设计
【发布时间】:2011-07-01 09:49:03
【问题描述】:

因此,我没有数据库设计背景,我的任务是设计一个 Web 应用程序,最终用户将在其中输入产品及其产品的规格。通常我认为我会为他们将要输入的每种规格类型创建行。相反,他们有各种不共享相同规格类型的产品,所以我的问题是,组织这些数据的最有效和面向未来的方法是什么?我倾向于将序列化对象推入通用“数据”行,但是您是否能够对这些数据进行全文搜索?还有其他探索途径吗?

【问题讨论】:

    标签: php mysql database database-design codeigniter


    【解决方案1】:

    将产品和规格分成两个表格,如下所示:

    products
    id name
    
    specifications
    id name value product_id
    

    当您知道产品 ID 时,获取产品的所有规格:

    SELECT  name,
            value
    FROM    specifications
    WHERE   product_id = ?;
    

    当您知道产品 id、规范名称和该规范的值时,为产品添加规范:

    INSERT INTO specifications(
        name,
        value,
        product_id
    ) VALUES(
        ?,
        ?,
        ?
    );
    

    因此,在您向产品添加规格之前,该产品必须存在。此外,您不能重复使用多个产品的规范。这将需要一个更复杂的解决方案:) 即...

    这次是三张桌子:

    products
    id name
    
    specifications
    id name value
    
    products_specifications
    product_id specification_id
    

    当您知道产品 ID 时,获取产品的所有规格:

    SELECT  specifications.name,
            specifications.value
    FROM    specifications
    JOIN    products_specifications
    ON      products_specifications.specification_id = specifications.id
    WHERE   products_specifications.product_id = ?;
    

    现在,添加规范变得有点棘手,因为您必须检查该规范是否已经存在。所以这会比第一种方法要重一些,因为数据库上有更多的查询,应用程序中有更多的逻辑。

    首先,找到规范的id:

    SELECT  id
    FROM    specifications
    WHERE   name = ?
    AND     value = ?;
    

    如果没有返回id,则表示该规范不存在,所以必须创建:

    INSERT INTO specifications(
        name,
        value
    ) VALUES(
        ?,
        ?
    );
    

    接下来,要么使用 select 查询中的 id,要么获取最后一个插入 id 以找到新创建的规范的 id。将该 id 与获得新规范的产品的 id 一起使用,并将两者联系在一起:

    INSERT INTO products_specifications(
        product_id,
        specification_id
    ) VALUES(
        ?,
        ?
    );
    

    但是,这意味着您必须为每个特定规范创建一行。例如如果你有鞋子的尺码,那么每个已知的鞋码都会有一排

    specifications
    id name value
    1  size 7
    2  size 7½
    3  size 8
    

    等等。我认为这应该足够了。

    【讨论】:

    • 这似乎是一条非常稳固的前进道路 - 所以,因为每个规格值仅与 1 个特定产品相关联,如果产品共享相同的值,我可以复制该行并更改 product_id,正确的?这会在数据库中产生大量额外数据,但不会影响性能或其他任何事情,对吧?
    • 那将是冗余数据,是的。一个巨大的缺点是:如果您想更改该规范,以便同时更改所有类似产品,那么您将处于紧要关头。如果这是您认为自己想要做的事情,那么您需要一个连接表。
    • 我编辑了我的答案并添加了一个带有连接表的解决方案
    【解决方案2】:

    你可以看看使用EAV model

    【讨论】:

    • 如何使用 EAV 模型撰写报告?
    【解决方案3】:

    我从未建立过产品数据库,但我可以为您指出一个数据模型。它是 Database Answers 提供的 200 多种模型之一。 Here is the model

    如果您不喜欢这个,您可以为面向产品的数据库找到 15 种不同的数据模型。单击“数据模型”以获取列表并向下滚动到“产品”。

    你应该在那里找到一些好的设计理念。

    【讨论】:

      【解决方案4】:

      这是一个很常见的问题 - 针对不同的场景有不同的解决方案。

      如果不同类型的产品及其属性在开发时是固定的并且是已知的,您可以查看 Craig Larman 的书中的描述 (http://www.amazon.com/Applying-UML-Patterns-Introduction-Object -Oriented/dp/0131489062/ref=sr_1_1/002-2801511-2159202?ie=UTF8&s=books&qid=1194351090&sr=1-1) - 有一节介绍对象关系映射以及如何处理继承。 这归结为“将所有可能的列放入一个表中”,“为每个子类创建一个表”或“将所有基类项放入一个公共表中,并将子类数据放入它们自己的表中”。

      这是迄今为止使用关系数据库最自然的方式 - 它允许您创建报告、使用现成的工具进行对象关系映射(如果您喜欢的话),并且您可以使用标准概念,例如“非空”,索引等。

      当然,如果您在开发时不了解数据属性,则必须创建灵活的数据库模式。

      我见过 3 种通用方法。

      第一个是 davogotland 所描述的。我为电子商务商店建立了类似的解决方案;它工作得很好,让我们对产品数据库非常灵活。它表现得非常好,即使有 50 万种产品。 主要缺点是创建检索查询 - 例如“在类别 y 中查找价格低于 x 的所有产品,其制造商是 z”。引入新开发人员也很棘手——他们的学习曲线相当陡峭。 它也迫使我们将很多关系概念推入应用层。例如,很难为其他表(例如“制造商”)创建外键并使用标准 SQL 功能强制执行它们。

      我看到的第二种方法是您提到的方法 - 以某种序列化格式存储可变数据。这在查询时很痛苦,并且与关系模型有同样的缺点。总的来说,我只想对您不必查询或推理的数据使用序列化。

      我看到的最终解决方案是接受添加新产品类型总是需要一定程度的开发工作 - 如果没有别的,您必须构建 UI。我见过使用脚手架样式方法在创建新产品类型时自动生成底层数据库结构的应用程序。 这是一项相当大的工作——只适合大型项目,尽管使用 ORM 工具通常会有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2016-12-21
        • 1970-01-01
        • 1970-01-01
        • 2012-02-04
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多