ОРАКУЛ Дизайн стола: M: N таблица лучших практик - PullRequest
1 голос
/ 16 сентября 2011

Я бы хотел услышать ваши предложения по этому основному вопросу:

Представьте себе эти три таблицы:

    --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_to_b?

Я дам несколько обсуждений для начала:

  • синтетический столбец id-PK или комбинированный a_id, b_id-PK (удаление столбца «id»)
    • При синтетическом: какие еще индексы / ограничения?
    • При комбинировании: также индексировать по b_id? Или даже b_id, a_id (не думаю)?
    • Также объединяется, когда эти записи сами ссылаются?
    • Также в сочетании, когда эти записи, возможно, будут ссылаться сами в будущем?
  • Таблица с кучей или индексами
    • Всегда или только до x "somevalue" -колонок?

Я знаю, что решение для одного из проектов тесно связано с вопросом, как будет использоваться таблица (соотношение чтения / записи, плотность и т. Д.), Но, возможно, мы получим решение 20/80 в качестве плана на будущее читатели.

Я с нетерпением жду ваших идей!

Blama

Ответы [ 3 ]

6 голосов
/ 16 сентября 2011

Я всегда делал, чтобы PK был комбинацией двух FK, a_id и b_id в вашем примере.Добавление синтетического поля id в эту таблицу не принесет пользы, так как вы никогда не будете искать строку, основанную на знании ее id.

Использование составного PK дает вам ограничение, которое не позволяет дважды вставить один и тот же экземпляр отношения между a и b.Если необходимо разрешить повторяющиеся записи, что-то не так с вашей моделью данных на концептуальном уровне.

Индекс, который вы получаете за кулисами (для каждой известной СУБД), будет полезен для ускорения общих объединений.Дополнительный индекс для b_id иногда полезен, в зависимости от типов соединений, которые вы часто делаете.

Как примечание, я не использую имя "id" для всех моих синтетических столбцов pk.Я предпочитаю a_id, b_id.Это облегчает управление метаданными, даже несмотря на то, что это немного лишний набор текста.

1 голос
/ 16 сентября 2011
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» и полагая, что только этот столбец - единственный ключ, который вам нужен.)

Вам, вероятно, понадобится один или несколько из этих проиндексированных.

  • a_id
  • b_id
  • {a_id, b_id}
  • {b_id, a_id}

Я считаю, что Oracle должен автоматически индексировать {a_id, b_id}, потому что это первичный ключ. Oracle автоматически не индексирует внешние ключи. Руководство Oracle по индексированию в сети.

В общем, вам нужно тщательно подумать, нужно ли вам ON UPDATE CASCADE или ON DELETE CASCADE. В Oracle вам нужно только тщательно продумать, нужно ли вам ON DELETE CASCADE. (Oracle не поддерживает ON UPDATE CASCADE.)

0 голосов
/ 16 сентября 2011

остальные комментарии пока хороши.

также рассмотрите возможность добавления begin_dt и end_dt к взаимосвязи.таким образом, вы можете управлять большим количеством вопросов о каждой взаимосвязи во времени.(рассмотрим базовые вопросы)

...