首先我要说我正在使用 MySQL(不是事务型)并且这是无法更改的。另外,为了简洁和清晰起见,我简化了此处的表格。
在此示例中,“课程”由其内部属性和外部属性及其自己的属性“阅读”组成。 “阅读”有其自己的关键依赖属性和三个不同的外部属性(阅读源)。
我想避免这里出现的多态关联,但我无法理解它。在此示例中,表“Reading”中的“sourceId”将包含来自三个表“ExternalURL”、“InternalURL”和“Book”之一的 ID。此外,字段“polytable”将包含上述“id”来自的表名称。
有人可以花点时间解释一下如何解决这个维护 RI 的问题吗?还是为了提高效率,应该保留它?
感谢您的时间和考虑,
Tim
-------------
| ExternalURL |
-------------
| id |
| badlink |
| url |
| |
| |
-------------
|
|
|
/ \
------------ ------------- -------------
| Lesson |-------<| Reading |>-------| InternalURL |
------------ ------------- -------------
| id | | id | | id |
| label | | lessonId | | url |
| summary | | sourceId | | |
| lessonOrder| | polytable | | |
| active | | label | | |
------------ ------------- -------------
\ /
|
|
------------
| Book |
------------
| id |
| label |
| summary |
| lessonOrder|
| active |
------------
您至少有几个选项来保留 RI:
-
添加几个可为空的 FK 列Reading
,每种阅读类型一个。其中只有一项应该是非空的。
CREATE TABLE Reading (
id INT AUTO_INCREMENT PRIMARY KEY,
lessonId INT NOT NULL,
bookId INT NULL,
externalUrlId INT NULL,
internalUrlId INT NULL,
FOREIGN KEY (bookId) REFERENCES Book(id),
FOREIGN KEY (externalUrlId) REFERENCES ExternalUrl(id),
FOREIGN KEY (internalUrlId) REFERENCES InternalUrl(id)
);
强制外键列之一不为空是一项任务trigger https://dev.mysql.com/doc/refman/5.5/en/triggers.html,否则您必须在应用程序代码中执行此操作。但至少你可以定义外键。
-
添加超级表Readable
它是每个其他特定可读类型的父级。
CREATE TABLE Readable (
id INT AUTO_INCREMENT PRIMARY KEY,
readable_type CHAR(1) NOT NULL,
UNIQUE KEY (id, readable_type)
);
CREATE TABLE Book (
id INT PRIMARY KEY, -- not AUTO_INCREMENT
readable_type CHAR(1) NOT NULL, -- must be 'B'
FOREIGN KEY (id, readable_type) REFERENCES Readable(id, readable_type)
);
... similar tables for ExternalUrl and InternalUrl...
然后使 Reading 也引用 Readable。
CREATE TABLE Reading (
id INT AUTO_INCREMENT PRIMARY KEY,
lessonId INT NOT NULL,
sourceId INT NOT NULL,
FOREIGN KEY (sourceId) REFERENCES Readable(id)
);
我在回答中更详细地描述了这个解决方案为什么多态关联中不能有外键? https://stackoverflow.com/questions/922184/why-can-you-not-have-a-foreign-key-in-a-polymorphic-association/922341#922341.
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)