【发布时间】:2018-09-06 14:04:10
【问题描述】:
您好 stackoverflow 数据库设计专家!
我在我的数据库中遇到了一个设计问题,我在 Stackoverflow 中没有发现任何类似的问题,因此提出了这个问题。
我有一个图像表,其中包含图像数据和它的主键。在我的设计中,可以跨多个表多次引用每个图像。
这是数据库的表示:
-------------------- -------------------------------------------
| image | | table1 |
|--------------------| |-------------------------------------------|
| id_image | data | | id_table1 | id_image | data |
|----------|---------| |-----------|----------|--------------------|
| 1 | Image 1 | | 1 | 1 | References image 1 |
| 2 | Image 2 | | 2 | 3 | References image 3 |
| 3 | Image 3 | -------------------------------------------
--------------------
-------------------------------------------
| table2 |
|-------------------------------------------|
| id_table2 | id_image | data |
|-----------|----------|--------------------|
| 1 | 2 | References image 2 |
| 2 | 2 | References image 2 |
| 3 | 3 | References image 3 |
-------------------------------------------
以下是表格详情:
-
图片表
- id_image 自增主键
- 数据图片数据
-
table1 表格
- id_table1 自增主键
-
id_image 外键引用
image.id_image - 数据 table1 数据
-
table2 表格
- id_table2 自增主键
-
id_image 外键引用
image.id_image - 数据 table2 数据
我希望我的数据库表现如下:
- 如果我删除带有
id_table1 = 1的table1行,则必须删除带有id_image = 1的图像行(没有其他对该图像的引用) - 如果我随后删除带有
id_table2 = 1的table2行,则不应删除任何图像(因为带有id_image = 2的图像仍被带有id_table2 = 2的table2行引用) - 如果我随后删除带有
id_table2 = 2的table2行,则必须删除带有id_image = 2的图像行(没有其他对该图像的引用) - 如果我随后删除带有
id_table1 = 2的table1行,则不应删除任何图像(因为带有id_image = 3的图像仍被带有id_table2 = 3的table2行引用) - 如果我随后删除带有
id_table2 = 3的table2行,则必须删除带有id_image = 3的图像行(没有其他对该图像的引用)
我已经尝试了一些级联删除,通过反转外键(即包含 id_table1 和 id_table2 外键的 image 表),但如果在其他 2 个表中引用图像,则删除一个引用表条目还会删除图像,这是我不希望发生的。
我也尝试定义触发器,但这种方法比我想象的要复杂:每次我都必须检查id_image 的所有外键,看看是否有另一个要删除的图像引用。此示例包含 2 个外键,但在我正在设计的数据库中将有超过 10 个...
我觉得这个简单的问题有一个简单的解决方案,有人来帮助我吗?
谢谢!
【问题讨论】:
-
当其他两个表中的任何一个都没有 id 时,您想从图像中删除(通过触发器)。用它们和图像之间的 id 并集制作一个表格。
-
刚写完我的回答,看了你的评论,感觉我找到的解决方案和你的建议很接近!
-
不需要代理列。 (通常情况下,id_tableN 映射到只映射回它的代理。请注意,不仅代理是表 1 和表 2 中的 FK,而且 (idN,proxy) 是 FK。不需要代理。) (你为什么把它们放进去?你认为每张桌子都需要一个替代品吗?)删除它们给出了我的建议。 FK 说,子行值必须以 PK 或 UNIQUE NOT NULL 的形式出现在另一个特定位置。这就是正在发生的一切。 PS 你有两个 子类型 图像,1 和 2。Google re sql/database subtying/inheritance。这是常见问题解答,尽管您是在询问更新算法。
-
这个代理表是为了简化我的触发器。没有它,我必须检查所有引用图像的表,看看是否仍然存在对受删除影响的图像的引用。如果我添加另一个引用图像的表,我必须更新所有现有触发器以检查这个新表......也许我在这里遗漏了一些东西,请随时在答案中详细说明您的建议!
标签: sql-server database database-design triggers foreign-keys