Реализация отношения 1: N в postgreSQL (объектно-реляционная) - PullRequest
2 голосов
/ 15 июля 2011

Я борюсь с postgreSQL, так как не знаю, как связать один экземпляр типа A с набором экземпляров типа B. Я приведу краткий пример:

Допустим, мы хотим создать БД, содержащую музыкальные альбомы и людей, каждый из которых имеет список своих любимых альбомов. Мы можем определить такие типы:

CREATE TYPE album_t AS (
Artist VARCHAR(50),
Title VARCHAR(50)
);

CREATE TYPE person_t AS (
FirstName VARCHAR(50),
LastName VARCHAR(50),
FavAlbums album_t ARRAY[5]
);

Теперь мы хотим создать таблицы следующих типов:

CREATE TABLE Person of person_t WITH OIDS;
CREATE TABLE Album of album_t WITH OIDS;

Теперь, когда я хочу сделать свою БД максимально объектно-реализационной, я не хочу вкладывать "объекты" альбома в строку FavAlbums таблицы Person, но я хочу "указать" на записи в таблицы Album, так что n Записи о персонале могут ссылаться на одну и ту же запись альбома, не дублируя ее снова и снова.

Я прочитал руководство, но, похоже, в нем отсутствуют некоторые жизненно важные примеры, поскольку объектно-реляционные функции используются не так часто. Я также знаком с практической моделью, но я хочу использовать дополнительные таблицы для отношений.

Заранее спасибо! das_weezul

Ответы [ 3 ]

4 голосов
/ 15 июля 2011

Почему вы создаете новый тип в postgresql, чтобы делать то, что вам нужно?Почему вы не используете таблицы напрямую?

С отношением nn:

CREATE TABLE album (
  idalbum integer primary key,
  Artist VARCHAR(50),
  Title VARCHAR(50)
);
CREATE TABLE person (
  idperson integer primary key,
  FirstName VARCHAR(50),
  LastName VARCHAR(50)
);
CREATE TABLE person_album (
  person_id integer,
  album_id integer,
  primary key (person_id, album_id),
  FOREIGN KEY (person_id)
    REFERENCES person (idperson),
  FOREIGN KEY (album_id)
    REFERENCES album (idalbum));

Или с "чистым" отношением 1-n:

CREATE TABLE person (
  idperson integer primary key,
  FirstName VARCHAR(50),
  LastName VARCHAR(50)
); 
CREATE TABLE album (
  idalbum integer primary key,
  Artist VARCHAR(50),
  Title VARCHAR(50),
  person_id integer,
  FOREIGN KEY (person_id)
    REFERENCES person (idperson)
);

Я надеюсьчто я тебе помогу.

3 голосов
/ 15 июля 2011

Теперь, когда я хочу сделать свою БД настолько объектно-реалистичной, насколько это возможно, я не хочу вкладывать «объекты» альбома в строку FavAlbums таблицы Person, но я хочу «указать» на записи в Альбом таблицы, так что n записей Person могут ссылаться на одну и ту же запись альбома, не дублируя ее снова и снова.

Удалите столбец массива, добавьте столбец первичного ключа id (серийный тип) в каждую таблицу, удалите oids (обратите внимание, что руководство рекомендует не использовать их). И добавьте таблицу FavoriteAlbum с двумя столбцами (PersonId, AlbumId), последний из которых является первичным ключом. (Ваше отношение н-н, а не 1-н.)

0 голосов
/ 15 июля 2011

Извините, что ответил на мой собственный вопрос, но я просто хотел дать некоторую информацию, которую я получил, играя с этим примером.

Тип массива

Я обнаружил, что тип ARRAY в PostgreSQL полезен, если вы хотите связать переменное число значений с одним атрибутом, но только если вы можете жить с дублирующимися записями. Так что эта техника не подходит для ссылки на «объекты» по их идентичности.

Ссылки на объекты / записи по идентичности

Так что, если вы хотите, как в моем примере, создать таблицу альбомов и хотите иметь возможность ссылаться на один альбом более чем одним человеком, вам следует использовать отдельную таблицу для установления этих отношений (возможно, с использованием OID в качестве ключей).

Еще одна сумасшедшая вещь, которую можно сделать, - это ссылаться на альбомы, используя Массив OID в таблице person. Но это очень неудобно и действительно не улучшает классический стиль отношений.

...