SQL数据库表中的多态性?
目前,我的数据库中有多个表,其中包含相同的“基本字段”,例如:
name character varying(100),
description text,
url character varying(255)
但我对该基本表有多个专业化,例如 tv_series
具有字段 season< /code>、
剧集
、airing
,而 movies
表有 release_date
、budget
> 等等。
现在一开始这不是问题,但我想创建第二个表,名为 linkgroups
,并带有这些专用表的外键。 这意味着我必须以某种方式使其自身正常化。
我听说过的解决这个问题的一种方法是使用键值对表对其进行规范化,但我不喜欢这个想法,因为它是一种“数据库内的数据库”数据库的方案,我没有办法要求某些键/字段,也不需要特殊的类型,并且稍后获取和排序数据将是一个巨大的痛苦。
因此,我现在正在寻找一种在多个表之间“共享”主键的方法,甚至更好:一种通过拥有通用表和多个专用表来规范化主键的方法。
I currently have multiple tables in my database which consist of the same 'basic fields' like:
name character varying(100),
description text,
url character varying(255)
But I have multiple specializations of that basic table, which is for example that tv_series
has the fields season
, episode
, airing
, while the movies
table has release_date
, budget
etc.
Now at first this is not a problem, but I want to create a second table, called linkgroups
with a Foreign Key to these specialized tables. That means I would somehow have to normalize it within itself.
One way of solving this I have heard of is to normalize it with a key-value
-pair-table, but I do not like that idea since it is kind of a 'database-within-a-database' scheme, I do not have a way to require certain keys/fields nor require a special type, and it would be a huge pain to fetch and order the data later.
So I am looking for a way now to 'share' a Primary Key between multiple tables or even better: a way to normalize it by having a general table and multiple specialized tables.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
是的,问题是您只希望一种子类型的一个对象引用父类的任何给定行。 从 @Jay S 给出的 示例 开始,试试这个
:是 @mike g提到的不相交子类型的示例。
@Countically Infinite 和 @Peter 的评论:
INSERT 到两个表将需要两个插入语句。 但在 SQL 中,只要有子表,情况也是如此。 这是一件很平常的事情。
UPDATE可能需要两条语句,但某些品牌的RDBMS支持使用JOIN语法的多表UPDATE,因此您可以在一条语句中完成。
查询数据时,如果您只需要有关公共列的信息,则可以简单地通过查询
media
表来完成:如果您知道自己正在查询一部电影,则可以使用单个字段获取特定于电影的信息join:
如果您想要给定媒体条目的信息,并且不知道它是什么类型,则必须连接到所有子类型表,并知道只有一个这样的子类型表会匹配:
如果给定媒体是电影,那么
t.*
中的所有列都将为 NULL。Right, the problem is you want only one object of one sub-type to reference any given row of the parent class. Starting from the example given by @Jay S, try this:
This is an example of the disjoint subtypes mentioned by @mike g.
Re comments by @Countably Infinite and @Peter:
INSERT to two tables would require two insert statements. But that's also true in SQL any time you have child tables. It's an ordinary thing to do.
UPDATE may require two statements, but some brands of RDBMS support multi-table UPDATE with JOIN syntax, so you can do it in one statement.
When querying data, you can do it simply by querying the
media
table if you only need information about the common columns:If you know you are querying a movie, you can get movie-specific information with a single join:
If you want information for a given media entry, and you don't know what type it is, you'd have to join to all your subtype tables, knowing that only one such subtype table will match:
If the given media is a movie,then all columns in
t.*
will be NULL.考虑使用一个主要的基本数据表,以及从该表延伸出来的带有专门信息的表。
前任。
Consider using a main basic data table with tables extending off of it with specialized information.
Ex.
您正在寻找的东西在关系世界中被称为“不相交的子类型”。 它们在语言级别的 sql 中不受支持,但或多或少在 sql 之上实现。
What you are looking for is called 'disjoint subtypes' in the relational world. They are not supported in sql at the language level, but can be more or less implemented on top of sql.
您可以创建一个包含主字段和 uid 的表,然后针对每种特定情况创建具有相同 uid 的扩展表。 要像单独的表一样查询这些,您可以创建视图。
You could create one table with the main fields plus a uid then extension tables with the same uid for each specific case. To query these like separate tables you could create views.
使用 Bill Karwin 建议的不相交子类型方法,如何在不必分两步进行的情况下执行插入和更新?
获取数据,我可以引入一个基于特定 media_type 连接和选择的视图,但据我所知,我无法更新或插入该视图,因为它会影响多个表(我在这里谈论 MS SQL Server)。 是否可以在不执行两个操作的情况下完成此操作 - 当然也无需存储过程。
谢谢
Using the disjoint subtype approach suggested by Bill Karwin, how would you do INSERTs and UPDATEs without having to do it in two steps?
Getting data, I can introduce a View that joins and selects based on specific media_type but AFAIK I cant update or insert into that view because it affects multiple tables (I am talking MS SQL Server here). Can this be done without doing two operations - and without a stored procedure, natually.
Thanks
问题很老了,但对于现代 postresql 版本,也值得考虑使用 json/jsonb/hstore 类型。
例如:
Question is quite old but for modern postresql versions it's also worth considering using json/jsonb/hstore type.
For example: