您好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
的image.id_image
的我希望数据库的行为如下:
table1
删除id_table1 = 1
行,则必须删除具有id_image = 1
的图像行(对此图像没有其他引用)table2
删除id_table2 = 1
行,则不应删除任何图像(因为id_image = 2
行仍使用{{ 1}})table2
删除id_table2 = 2
行,则必须删除具有table2
的图像行(对此图像没有其他引用)id_table2 = 2
删除id_image = 2
行,则不应删除任何图像(因为table1
行仍使用{{ 1}})id_table1 = 2
删除id_image = 3
行,则必须删除具有table2
的图像行(对此图像没有其他引用)我已经通过反转外键(即包含id_table2 = 3
和table2
外键的id_table2 = 3
表来尝试级联删除),但是如果另外2个引用了图像表,删除一个引用的表条目也会删除图像,我不想发生这种情况。
我也尝试定义触发器,但是这种方法比我想象的要复杂:每次我必须检查id_image = 3
的所有外键中是否有另一个要删除的图像引用。该示例包含2个外键,但是我正在设计的数据库中将有10多个...
我觉得这个简单的问题有一个简单的解决方案,有人在这里帮助我吗?
谢谢!
答案 0 :(得分:0)
因为您的第一个要求,马上走
如果删除id_table1 = 1的table1行,则使用 id_image = 1必须删除(对此图像无其他引用)
我可以告诉您,您只能使用TRIGGER来完成此操作。原因是因为您要在从子表中删除一行时自动从父表中删除。
可以通过级联外键完成相反的操作(删除父级时删除子级),但不能这样做。
您将需要在两个子表上都放置触发器,以实施所需的逻辑。
答案 1 :(得分:0)
昨天我想出了一个更好的设计。它仍然使用触发器(如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
中的条目。我不知道这种设计是否最适合该问题,也不知道触发器的使用是否安全,这就是为什么如果有更好的答案或相关评论,我将密切关注这篇文章!