我想听听你对这个基本问题的建议:
想象一下这三个表:
--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
) ;
我会给一些讨论初学者:
我知道其中一个设计的决定与表格的使用方式(读/写比率,密度等)密切相关,但也许我们得到一个20/80的解决方案作为未来的蓝图读者。
我期待着你的想法!
Blama
答案 0 :(得分:6)
我总是让PK成为你的例子中两个FK,a_id和b_id的组合。将合成id字段添加到此表没有任何好处,因为您永远不会根据其id的知识来查找行。
使用复合PK为您提供一个约束,以防止a和b之间的关系的同一实例被插入两次。如果需要允许重复的条目,那么在概念级别上您的数据模型就会出现问题。
您在幕后获得的索引(对于我所知道的每个DBMS)将有助于加速常见联接。 b_id上的额外索引有时很有用,具体取决于您经常进行的连接类型。
正如旁注,我不会对我的所有合成pk列使用名称“id”。我更喜欢a_id,b_id。它使管理元数据变得更容易,即使它有点额外的输入。
答案 1 :(得分:1)
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),
...
) ;
除了你拥有的任何其他密钥之外,ORM要求(或者,在更有意义的ORM中,希望)一个名为“id”的整数列并不罕见。除此之外,没有必要。像这样的id号会使表更宽(这通常会略微降低I / O性能),并且添加一个严格来说不必要的索引。没有必要识别实体 - 现有密钥就是这样 - 并且它会导致新开发人员陷入不良习惯。 (具体来说,为每个表提供一个名为“id”的整数列,并且相信该列是唯一需要的键。)
您可能需要这些索引中的一个或多个。
我相信Oracle应该自动索引{a_id,b_id},因为这是主键。 Oracle不会自动索引外键。 Oracle's indexing guidelines在线。
一般来说,您需要仔细考虑是否需要ON UPDATE CASCADE
或ON DELETE CASCADE
。在Oracle中,您只需要仔细考虑是否需要ON DELETE CASCADE
。 (Oracle不支持ON UPDATE CASCADE
。)
答案 2 :(得分:0)
还考虑将begin_dt和end_dt添加到关系中。通过这种方式,您可以随时间管理关于每种关系的大量问题。 (考虑基线问题)