在postgreSQL中实现1:N关系(对象关系)

发布于 2024-11-23 20:29:27 字数 663 浏览 5 评论 0原文

我正在与 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 个 Person 记录可以引用相同的专辑记录,而无需一遍又一遍地重复它。

我阅读了该手册,但似乎缺少一些重要的示例,因为对象关系功能并未经常使用。我也熟悉关系模型,但我想使用额外的表来表示关系。

I'm struggling with postgreSQL, as I don't know how to link one instance of type A to a set of instances of type B. I'll give a brief example:

Let's say we want to set up a DB containing music albums and people, each having a list of their favorite albums. We could define the types like that:

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]
);

Now we want to create tables of those types:

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

Now as I want to make my DB as object-realational as it gets, I don't want to nest album "objects" in the row FavAlbums of the table Person, but I want to "point" to the entries in the table Album, so that n Person records can refer to the same Album record without duplicating it over and over.

I read the manual, but it seems that it lacks some vital examples as object-relational features aren't being used that often. I'm also familiar with the realational model, but I want to use extra tables for the relations.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

不醒的梦 2024-11-30 20:29:27

为什么要在 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)
);

我希望对您有所帮助。

Why you create a new type in postgresql to do what you need?
Why you don't use tables directly?

With n-n relation:

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));

Or with a "pure" 1-n relation:

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)
);

I hope that I help you.

心不设防 2024-11-30 20:29:27

现在,当我想让我的数据库成为对象关系型数据库时,我不想将专辑“对象”嵌套在表 Person 的 FavAlbums 行中,但我想“指向”中的条目表Album,以便n条Person记录可以引用同一个Album记录,而无需一遍又一遍地重复。

删除数组列,向每个表添加一个 id 主键列(序列类型),删除 oid(请注意,手册建议不要使用它们)。并添加一个包含两列(PersonId、AlbumId)的FavoriteAlbum 表,后者是主键。 (你的关系是 nn,而不是 1-n。)

Now as I want to make my DB as object-realational as it gets, I don't want to nest album "objects" in the row FavAlbums of the table Person, but I want to "point" to the entries in the table Album, so that n Person records can refer to the same Album record without duplicating it over and over.

Drop the array column, add an id primary key column (serial type) to each table, drop the oids (note that the manual recommends against using them). And add a FavoriteAlbum table with two columns (PersonId, AlbumId), the latter of which are a primary key. (Your relation is n-n, not 1-n.)

巾帼英雄 2024-11-30 20:29:27

很抱歉回答我自己的问题,但我只是想提供一些我通过玩弄这个例子而获得的信息。

ARRAY 类型

我发现,如果您想将可变数量的值与一个属性相关联,但仅当您可以接受重复条目时,PostgreSQL 中的 ARRAY 类型非常有用。因此该技术不适合通过身份引用“对象”。

按身份引用对象/记录

因此,如果您想(如我的示例中所示)创建一个相册表并希望能够由多个人引用一个相册,则应该使用单独的表来建立这些关系(也许通过使用 OID 作为键)。

另一件疯狂的事情是通过在 person 表中使用 OID 数组来引用相册。但这非常尴尬,并且确实没有改善经典的关系风格。

Sorry for answering my own question, but I just wanted to give some pieces of information I gained by toying around with that example.

ARRAY Type

I found out that the ARRAY Type in PostgreSQL is useful if you want to associate a variable number of values with one attribute, but only if you can live with duplicate entries. So that technique is not suitable for referencing "objects" by their identity.

References to Objects/Records by identity

So if you want to, as in my example, create a table of albums and want to be able to reference one album by more than one person, you should use a separate table to establish these relationships (Maybe by using the OIDs as keys).

Another crazy thing one could do is referencing albums by using an ARRAY of OIDs in the person table. But that is very awkward and really does not improve on the classic relational style.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文