Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/77.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Sql ORACLE表设计:M:N表最佳实践_Sql_Oracle_Database Design_Rdbms - Fatal编程技术网

Sql ORACLE表设计:M:N表最佳实践

Sql ORACLE表设计:M:N表最佳实践,sql,oracle,database-design,rdbms,Sql,Oracle,Database Design,Rdbms,我想听听你对这个基本问题的建议: 想象一下这三张桌子: --DROP TABLE a_to_b; --DROP TABLE a; --DROP TABLE b; CREATE TABLE A ( ID NUMBER NOT NULL , NAME VARCHAR2(20) NOT NULL , CONSTRAINT A_PK PRIMARY KEY ( ID ) ENABLE );

我想听听你对这个基本问题的建议:

想象一下这三张桌子:

    --DROP TABLE a_to_b;
    --DROP TABLE a;
    --DROP TABLE b;
    CREATE TABLE A
      (
        ID   NUMBER NOT NULL ,
        NAME VARCHAR2(20) NOT NULL ,
        CONSTRAINT A_PK PRIMARY KEY ( ID ) ENABLE
      );
    CREATE TABLE B
      (
        ID   NUMBER NOT NULL ,
        NAME VARCHAR2(20) NOT NULL ,
        CONSTRAINT B_PK PRIMARY KEY ( ID ) ENABLE
      );
    CREATE TABLE A_TO_B
      (
        id         NUMBER NOT NULL,
        a_id       NUMBER NOT NULL,
        b_id       NUMBER NOT NULL,
        somevalue1 VARCHAR2(20) NOT NULL,
        somevalue2 VARCHAR2(20) NOT NULL,
        somevalue3 VARCHAR2(20) NOT NULL
      ) ;
您将如何设计表a到表b? 我将首先介绍一些讨论:

  • 合成id PK列或组合a_id、b_id-PK(删除“id”列)
    • 合成时:还有哪些其他指标/约束
    • 组合时:是否也在b_id上建立索引?甚至是b_id,a_id(我不这么认为)
    • 当这些条目本身被引用时,是否也会合并
    • 当这些条目将来可能被引用时,是否也会合并
  • 堆或索引组织表
    • 始终或最多x个“somevalue”-列
我知道其中一种设计的决定与表格的使用方式(读写比、密度等)密切相关,但也许我们可以得到一个20/80的解决方案作为未来读者的蓝图

我期待着你的想法


bumma

在您的示例中,我总是将PK设置为两个fk的组合,即a_id和b_id。将合成id字段添加到此表中没有任何好处,因为您永远不会基于对其id的了解来查找行

使用复合PK可以提供一个约束,防止a和b之间的关系的同一实例被插入两次。如果需要允许重复条目,那么您的数据模型在概念级别上就有问题

您在幕后获得的索引(对于我所知道的每个DBMS)将有助于加快公共连接。b_id上的额外索引有时很有用,具体取决于您经常使用的联接类型


作为旁注,我并没有在所有合成pk列中使用名称“id”。我更喜欢a_-id,b_-id。这样可以更容易地管理元数据,即使需要额外键入一点。

在您的示例中,我总是将PK设置为两个fk,a_-id和b_-id的组合。将合成id字段添加到此表中没有任何好处,因为您永远不会基于对其id的了解来查找行

CREATE TABLE A_TO_B
      (
        a_id       NUMBER NOT NULL REFERENCES A (a_id),
        b_id       NUMBER NOT NULL REFERENCES B (b_id),
        PRIMARY KEY (a_id, b_id),
        ...
      ) ;
使用复合PK可以提供一个约束,防止a和b之间的关系的同一实例被插入两次。如果需要允许重复条目,那么您的数据模型在概念级别上就有问题

您在幕后获得的索引(对于我所知道的每个DBMS)将有助于加快公共连接。b_id上的额外索引有时很有用,具体取决于您经常使用的联接类型

作为旁注,我并没有在所有合成pk列中使用名称“id”。我更喜欢a_id,b_id。它使元数据的管理更容易,尽管它需要额外键入一点

CREATE TABLE A_TO_B
      (
        a_id       NUMBER NOT NULL REFERENCES A (a_id),
        b_id       NUMBER NOT NULL REFERENCES B (b_id),
        PRIMARY KEY (a_id, b_id),
        ...
      ) ;
除了您拥有的任何其他键之外,ORMs还需要(或者,在更复杂的ORMs中,希望需要)一个名为“id”的整数列,这并不罕见。除此之外,没有必要这样做。这样的id号使表更宽(通常只会略微降低I/O性能),并添加严格来说不必要的索引。不需要识别实体——现有的键就可以识别实体——而且它会导致新开发人员养成坏习惯。(具体地说,为每个表指定一个名为“id”的整数列,并相信只有该列才是所需的唯一键。)

您可能需要一个或多个索引

  • 身份证
  • b_id
  • {a_id,b_id}
  • {b_id,a_id}
我认为Oracle应该自动索引{a_id,b_id},因为这是主键。Oracle不会自动为外键编制索引。你是在线的

一般来说,您需要仔细考虑是否需要更新级联上的
或删除级联上的
。在Oracle中,您只需仔细考虑是否需要删除级联
。(Oracle不支持更新级联时的

除了您拥有的任何其他键之外,ORMs还需要(或者,在更复杂的ORMs中,希望需要)一个名为“id”的整数列,这并不罕见。除此之外,没有必要这样做。这样的id号使表更宽(通常只会略微降低I/O性能),并添加严格来说不必要的索引。不需要识别实体——现有的键就可以识别实体——而且它会导致新开发人员养成坏习惯。(具体地说,为每个表指定一个名为“id”的整数列,并相信只有该列才是所需的唯一键。)

您可能需要一个或多个索引

  • 身份证
  • b_id
  • {a_id,b_id}
  • {b_id,a_id}
我认为Oracle应该自动索引{a_id,b_id},因为这是主键。Oracle不会自动为外键编制索引。你是在线的


一般来说,您需要仔细考虑是否需要更新级联上的
或删除级联上的
。在Oracle中,您只需仔细考虑是否需要删除级联
。(Oracle不支持更新级联

到目前为止,其他评论都很好


还考虑将RealthDT和EndoTdT添加到关系中。通过这种方式,你可以在一段时间内处理好关于每一段关系的大量问题。(考虑基线问题)

到目前为止,其他评论都很好

还考虑将RealthDT和EndoTdT添加到关系中。通过这种方式,你可以在一段时间内处理好关于每一段关系的大量问题。(考虑基线问题)