Sql server 数据库设计-从多个表多次引用一个表
嗨,stackoverflow数据库设计专家 我在数据库中遇到了一个设计问题,我在Stackoverflow中没有发现任何类似的问题,因此我提出了这个问题 我有一个图像表,包含图像数据和它的主键。在我的设计中,每个图像可以在多个表中多次引用 以下是数据库的表示形式:Sql server 数据库设计-从多个表多次引用一个表,sql-server,database,database-design,triggers,foreign-keys,Sql Server,Database,Database Design,Triggers,Foreign Keys,嗨,stackoverflow数据库设计专家 我在数据库中遇到了一个设计问题,我在Stackoverflow中没有发现任何类似的问题,因此我提出了这个问题 我有一个图像表,包含图像数据和它的主键。在我的设计中,每个图像可以在多个表中多次引用 以下是数据库的表示形式: -------------------- ------------------------------------------- | image | | table1
-------------------- -------------------------------------------
| 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\u图像自动递增主键
- 数据图像数据
- 表1表
- id\u表1自动递增主键
- id\u image外键引用
image.id\u image
- 数据表1数据
- 表2表
- id_表2自动递增主键
- id\u image外键引用
image.id\u image
- 数据表2数据
- 如果我删除带有
的id\u table1=1
行,则必须删除带有table1
的图像行(此图像没有其他引用)id\u image=1
- 如果我随后删除了
的id\u table2=1
行,则不应删除任何图像(因为table2
的id\u image=2
行仍然引用了table2
)id\u table2=2
- 如果我随后删除
的id\u table2=2
行,则必须删除table2
的图像行(此图像没有其他引用)id\u image=2
- 如果我随后删除带有
的id\u table1=2
行,则不应删除任何图像(因为带有table1
的图像仍被带有id\u image=3
的id\u table2=3
行引用)table2
- 如果随后删除
的id\u table2=3
行,则必须删除table2
的图像行(此图像没有其他引用)id\u image=3
id\u table1
和id\u table2
外键的image
表),但是如果一个图像在其他两个表中引用,删除一个引用的表项也会删除该图像,这是我不希望发生的
我也尝试过定义触发器,但这种方法比我想象的要复杂:每次我都必须检查id\u image
的所有外键,以查看是否还有另一个要删除的图像引用。此示例包含2个外键,但在我正在设计的数据库中,将有10多个外键
我觉得这个简单的问题有一个简单的解决方案,有人来帮我吗
谢谢 由于您的第一个要求,请立即: 如果我删除id_table1=1的table1行,则 必须删除id_image=1(没有其他对此映像的引用) 我可以告诉你,你只能用扳机来完成这项任务。原因是您希望在从子表中删除行时自动从父表中删除 相反(删除父项时删除子项)可以通过级联外键来完成,但不是这样
您需要在两个子表上都放置触发器,以强制执行所需的逻辑。我昨天提出了一个更好的设计。它仍然使用触发器(as),但这些触发器的定义要简单得多:
-------------------- ---------------------------
| 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\u proxy
:
- id\u image\u代理自动递增主键
- id\u image外键引用
image.id\u image
table1
和table2
现在引用的是image\u proxy
条目,而不是image
条目
使用这种设计,触发器现在是:
- 删除
表1中的条目后,删除
图像\u代理中的相应条目
- 删除
表2中的条目后,删除
中的相应条目image\u proxy
- 删除
中的条目后,删除image\u proxy
中不再引用的条目image
我不知道这个设计是否最适合这个问题,也不知道触发器的使用是否安全,这就是为什么如果有更好的答案或相关评论,我会关注这篇文章的原因 是的,但是这种设计很难定义触发器,正如我在问题中所说的。我宁愿使用其他设计,但我想不出更好的设计…不幸的是,我没有告诉你触发器是一种选择。我告诉你,他们是你唯一的选择。当然,它们需要一些复杂的编码,但这是您需求的代价,抱歉。当其他两个表中都没有id时,您希望从映像中删除(通过触发器)。用他们的ID在他们和图像之间的联合做一个表格。我在写了我的答案后刚刚读了你的评论,我觉得我找到的解决方案接近你的建议!不需要代理列。(通常情况下,一个id_tableN映射到一个只映射回它的代理。请注意,表1和表2中不仅proxys是FKs,而且(idN,proxy)是FK。不需要代理。)(为什么要将它们放入?您认为每个表都需要代理吗?)删除它们给出了我的建议。FK表示,子程序值必须以PK或UNIQUE NOT NULL的形式出现在另一个特定位置。就这么回事。PS您有两个子类型的图像,1和2。googlere-sql/数据库子处理/继承。这是常见问题,尽管你问的是更新算法