您好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 |
-------------------------------------------
这是表格详细信息:
image.id_image
数据表1数据image.id_image
数据表2数据我希望我的数据库行为如下:
table1
删除id_table1 = 1
行,则必须删除带有id_image = 1
的图像行(没有其他对此图像的引用)table2
删除id_table2 = 1
行,则不应删除任何图像(因为带有id_image = 2
的图像仍被table2
行引用id_table2 = 2
)table2
删除id_table2 = 2
行,则必须删除带有id_image = 2
的图像行(没有其他对此图像的引用)table1
删除id_table1 = 2
行,则不应删除任何图像(因为带有id_image = 3
的图像仍被table2
行引用id_table2 = 3
)table2
删除id_table2 = 3
行,则必须删除带有id_image = 3
的图像行(没有其他对此图像的引用)我已经尝试了一些级联删除,通过反转外键(即包含image
和id_table1
外键的id_table2
表),但如果在其他2个表中引用了一个图像,删除一个引用的表条目也会删除图像,我这样做不想发生。
我也尝试定义触发器,但这种方法比我想象的更复杂:每次我必须检查id_image
的所有外键,看看是否有另一个要删除的图像引用。这个示例包含2个外键,但在我设计的数据库中将有超过10个...
我觉得这个简单的问题有一个简单的解决方案,有人在这帮助我吗?
谢谢!
马上因为你的第一个要求:
如果我删除id_table1 = 1的table1行,则必须删除id_image = 1的图像行(没有其他对此图像的引用)
我可以告诉你,你只能用TRIGGER完成这个任务。原因是,当您从Child表中删除行时,您希望从Parent表中自动删除。
反向(删除父项时删除子项)可以使用级联外键完成,但不能这样做。
您需要在两个子表上放置触发器以强制执行所需的逻辑。
我昨天想出了一个更好的设计。它仍然使用触发器(如Tab Alleman said),但定义更简单:
-------------------- ---------------------------
| image | | image_proxy |
|--------------------| |---------------------------|
| id_image | data | | id_image_proxy | id_image |
|----------|---------| |----------------|----------|
| 1 | Image 1 | | 1 | 1 |
| 2 | Image 2 | | 2 | 3 |
| 3 | Image 3 | | 3 | 2 |
-------------------- | 4 | 2 |
| 5 | 3 |
---------------------------
-------------------------------------------------
| table1 |
|-------------------------------------------------|
| id_table1 | id_image_proxy | data |
|-----------|----------------|--------------------|
| 1 | 1 | References image 1 |
| 3 | 2 | References image 3 |
-------------------------------------------------
-------------------------------------------------
| table2 |
|-------------------------------------------------|
| id_table2 | id_image_proxy | data |
|-----------|----------------|--------------------|
| 1 | 3 | References image 2 |
| 2 | 4 | References image 2 |
| 3 | 5 | References image 3 |
-------------------------------------------------
正如您在上面的架构中所看到的,我引入了一个新表:image_proxy
:
image.id_image
此外,table1
和table2
现在引用image_proxy
条目而不是image
条目。
通过这种设计,触发器现在是:
table1
中的条目后,删除image_proxy
中的相应条目。table2
中的条目后,删除image_proxy
中的相应条目。image_proxy
中的条目后,删除image
中未在image_proxy
中引用的条目。我不知道这个设计是否是这个问题的最佳选择,也不知道触发器使用是否安全,这就是为什么如果有更好的答案或相关评论,我会留意这篇文章!