当前位置:  开发笔记 > 数据库 > 正文

SQL数据库表中的多态性?

如何解决《SQL数据库表中的多态性?》经验,为你挑选了2个好方法。

我目前在我的数据库中有多个表,它们包含相同的"基本字段",如:

name character varying(100),
description text,
url character varying(255)

但我有一个基本的表,这是例子的多个专业化tv_series有田season,episode,airing,而movies表中有release_date,budget等等.

现在起初这不是问题,但我想创建第二个表,linkgroups使用这些专用表的外键调用.这意味着我会以某种方式将其自身标准化.

我听说过解决这个问题的一种方法是使用key-value-pair-table 对其进行规范化,但我不喜欢这个想法,因为它是一种"数据库中的数据库"方案,我没有办法要求某些键/字段也不需要特殊类型,以后获取和排序数据将是一个巨大的痛苦.

所以我现在正在寻找一种方法来在多个表之间"共享"主键,甚至更好:通过使用通用表和多个专用表来规范化它.



1> Bill Karwin..:

是的,问题是您只希望一个子类型的一个对象引用父类的任何给定行.从@Jay S给出的示例开始,试试这个:

create table media_types (
  media_type     int primary key,
  media_name     varchar(20)
);
insert into media_types (media_type, media_name) values
  (2, 'TV series'),
  (3, 'movie');

create table media (
  media_id       int not null,
  media_type     not null,
  name           varchar(100),
  description    text,
  url            varchar(255),
  primary key (media_id, media_type),
  foreign key (media_type) 
    references media_types (media_type)
);

create table tv_series (
  media_id       int primary key,
  media_type     int check (media_type = 2),
  season         int,
  episode        int,
  airing         date,
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

create table movies (
  media_id       int primary key,
  media_type     int check (media_type = 3),
  release_date   date,
  budget         numeric(9,2),
  foreign key (media_id, media_type) 
    references media (media_id, media_type)
);

这是@mike g 提到的不相交亚型的一个例子.


评论@Countably Infinite和@Peter:

INSERT到两个表将需要两个插入语句.但是,只要你有子表,这在SQL中也是如此.这是一件普通的事情.

UPDATE可能需要两个语句,但某些品牌的RDBMS支持带有JOIN语法的多表UPDATE,因此您可以在一个语句中执行此操作.

查询数据时,media如果只需要有关公共列的信息,只需查询表即可完成:

SELECT name, url FROM media WHERE media_id = ?

如果您知道要查询电影,则可以通过单个连接获取电影特定信息:

SELECT m.name, v.release_date
FROM media AS m
INNER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?

如果您需要给定媒体条目的信息,并且您不知道它是什么类型,则必须加入所有子类型表,知道只有一个这样的子类型表匹配:

SELECT m.name, t.episode, v.release_date
FROM media AS m
LEFT OUTER JOIN tv_series AS t USING (media_id)
LEFT OUTER JOIN movies AS v USING (media_id)
WHERE m.media_id = ?

如果给定媒体是电影,则所有列都t.*将为NULL.



2> Jay S..:

考虑使用一个主要的基本数据表,其中表格带有专门的信息.

防爆.

basic_data
id int,
name character varying(100),
description text,
url character varying(255)


tv_series
id int,
BDID int, --foreign key to basic_data
season,
episode
airing


movies
id int,
BDID int, --foreign key to basic_data
release_data
budget

推荐阅读
kikokikolove
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有