【问题标题】:Database "pointers" to rows?数据库“指针”指向行?
【发布时间】:2010-12-05 11:49:18
【问题描述】:

有没有办法在数据库中拥有“指向行的指针”?

例如,我有 X 个产品行,所有这些行都代表不同的产品,但许多行具有相同的字段值,只是它们的“id”和“color_id”不同。

我想只是复制行,但这可能容易出错,而且必须对几行进行小改动,这又是错误的。


问题:有没有办法完全填充某些行,然后使用特殊值“指向”某些字段值?

例如:

编号 |字段1 |字段2 |字段3 | color_id ----------------------------------------------------------- 1 |值1 |值2 |价值3 |蓝色 2 |点[1] |点[1] |点[1] |红色(与第 1 行相同,除了 id 和颜色) 3 |点[1] |点[1] |点[1] |绿色(与第 1 行相同,除了 id 和颜色) 4 |值A |值B |价值C |橘子 5 |点[4] |点[4] |点[4] |棕色(与第 4 行相同,除了 id 和颜色) 6 |值X |值Y |值Z |粉色的 7 |点[6] |点[6] |点[6] |黄色(与第 6 行相同,除了 id 和颜色)

我正在使用 MySQL,但这是一个更普遍的问题。此外,如果这完全违背了数据库理论,我们将不胜感激地解释一下为什么这是不好的。

【问题讨论】:

    标签: mysql database-design rdbms


    【解决方案1】:

    这确实违背了数据库设计。寻找规范化和关系代数的描述。这很糟糕,主要是因为您发表的评论“复制了行,但这可能容易出错,而且必须对几行进行小幅更改,这又是错误的。”

    关系数据库的理念是对数据集进行操作,并通过匹配主键和外键来查找内容,绝对不使用或考虑指针。

    如果每个产品都有共同的数据,那么就创建一个产品表

    create table product (
      product_id int,
      field1 ...,
      field2 ...,
      field3
    )
    with primary key on product_id
    

    主表将包含字段 id、color_id 和 product_id

    如果产品表看起来像

    product_id | field1   | field2   | field3  
    -----------------------------------------------
    1          | value1   | value2   | value3  
    2          | valueA   | valueB   | valueC  
    3          | valueX   | valueY   | valueZ   
    

    主表看起来像

    id | product_id | color_id
    --------------------------------
    1  | 1          | blue
    2  | 1          | red
    3  | 1          | green  
    4  | 2          | orange
    5  | 2          | brown
    6  | 3          | pink
    7  | 3          | yellow
    

    【讨论】:

      【解决方案2】:

      当然有一种方法可以让指针指向数据库中的行。只是不要使用关系 DBMS。在 1960 和 1970 年代,有几个非常成功的 DBMS 产品完全基于通过在其他记录中嵌入指向记录的指针来将记录链接在一起。其中最著名的也许是 IMS。

      在其他记录中具有指向记录的指针的缺点是生成的数据库远不如关系数据库灵活。对于预先确定的访问路径,建立在指针网络上的数据库实际上比关系数据库更快。但是,当您想以多种方式组合数据时,缺乏灵活性会害死您。

      这就是关系 DBMS 在 1980 年代和 1990 年代接管该领域的原因,尽管分层数据库和网络数据库仍然存在于相当专业的工作中。

      正如其他人所建议的,您应该学习规范化。当您这样做时,您将学习如何将表分解为每个表中具有较少列(字段)的较小表。当您需要以联接方式使用数据时,可以使用关系联接将数据重新组合在一起。关系连接几乎可以与指针导航一样快,尤其是在您构建了正确的索引的情况下。

      规范化将帮助您避免有害的冗余,这是您在问题中强调的问题。

      【讨论】:

        【解决方案3】:

        这样做的一种方法是将似乎具有重复数据的列分开并将其放在单独的表中。给这个新表中的每一行一个唯一的 id。在原始表中添加一列,其中包含新表中的 id。然后在原表和新表的 id 列之间使用 FOREIGN KEY 关系。

        【讨论】:

          【解决方案4】:

          好吧,在正常情况下这将被称为规范化 .. 它的全部意义在于处理那种情况 .. 所以不,它不能按照您想要的方式完成.. 您需要对数据进行规范化正确。

          【讨论】:

            【解决方案5】:

            为 field1、field2 和 field 三个值创建单独的表。 将现有值放在那里,并通过将它们的 id 放入当前表来引用它们。

            【讨论】:

              【解决方案6】:

              如果您使用通用字符串值,最好将字符串存储在单独的表中并使用外键引用它们。如果您要存储整数之类的东西,那就不值得了——指针的大小与数据本身的大小相当。

              【讨论】:

                【解决方案7】:

                它确实违反了数据库理论,因为您将数据库的关系部分抛到了窗外。

                方法是创建一个 ObjectID 列,其中包含您要指向的行的键。

                编号 |字段1 |字段2 |字段3 | color_id | object_id | -------------------------------------------------- ---------- 1 |值1 |值2 |价值3 |蓝色 2 |空 |空 |空 |红色 | 1 | 3 |空 |空 |空 |绿色 | 1 | 4 |值A |值B |价值C |橘子 5 |空 |空 |空 |棕色 | 4 | 6 |值X |值Y |值Z |粉色的 7 |空 |空 |空 |黄色 | 6 |

                但请记住:这是个坏主意。不要这样做。如果您确实想这样做,那就是这样。

                在某些情况下需要它;但是在处理了一个普遍存在的系统之后,我总是会尝试寻找另一种方法,即使这意味着复制数据并让您的业务层保持一切正常。

                我在一个系统中工作,这在整个系统中都完成了,当你因为有人想变得聪明而不得不重新创建关系的功能时,这很让人抓狂。

                【讨论】:

                • 如果你必须这样做,我会让你在这里显示的表格成为规范化表格的视图
                【解决方案8】:

                您希望在数据库中实现此功能的方式是创建两个表:

                object_id | field1 | field2 | field3
                

                instance_id | object_id | colour
                

                然后第二个的行将指向第一个,您可以通过

                动态生成所需的完整数据表
                select t1.*, t2.colour from t1 join t2 on (t1.object_id=t2.object_id)
                

                【讨论】:

                  【解决方案9】:

                  您可能应该有两个具有外键关系的表。

                  例子

                  Products:
                    Id
                    field1
                    field2
                    field3
                  
                  ProductColors:
                    Id
                    ProductId
                    Color
                  

                  【讨论】:

                    猜你喜欢
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2023-04-05
                    • 1970-01-01
                    • 1970-01-01
                    • 1970-01-01
                    • 2016-07-30
                    相关资源
                    最近更新 更多