删除操作 - 具有多对多关系的多个表

时间:2014-07-15 11:24:21

标签: mysql sql database database-design many-to-many

我有四个表和三个联结表来表示多对多关系。 这是通过一般信息创建的,项目二进制文件将包含多个应用程序二进制文件,每个应用程序二进制文件可以由多个归档,共享对象,对象,二进制文件等构建。每个归档或共享对象或二进制文件可以由多个源文件构建(.c ,.cpp,.hpp,.h,sh,.java)。

问题如下。


这个设计足够好吗?或者有更好的方法来做到这一点 2.如果我需要删除一个项目二进制文件,那么sql查询是什么 3.如果我只需要从BinaryList_table中删除一些二进制文件,那么sql查询及其对其他表的影响可能是多对多关系。

ProjectList_table
-----
ProjectBinaryId ProjectBinary   VersionInfo etc.    Market
1               NTG5_App          1.2               Japan
2               NTG5_App          1.3               Europe

------
AppList_table
-------
Appld   ApplicationBinary   VersionInfo
1       CarFU   
2       NavHU               1.1
3       MediaHU 
4       Connectivity    
5       QNX binaries    
6       NavHU               1.2
-------

ProjectBinary_AppJunctionTable  
-------
ProjectBinaryId AppId
1               1
1               2
1               3
1               4
1               5
2               5
2               4
2               6
------------------


BInaryList_Table    
--------------  
BinaryId    BinaryFileName  LicenseDetails
1           .so 
2           .a  
3           .so 
4           binary  
5           .a  
6           .a  
7           .so 
8           .o  
9           .a  
10          .so 
11          .so 
12          .a  
13          binary (shell command wo extn)  
-------------------------

App_BinaryJunctionTable 
---------------------
AppId   BinaryId
1        1
1        2
1        3
1        4
2        5
2        3
3        7
3        8
4        1
4        10
5        11
5        12
5        13
-----------

SourceInfo_Table
--------        
SourceId    Source file            License Details
1           .c, .cpp, .h,.sh .etc   
2           .c, .cpp, .h,.sh .etc   
3           .c, .cpp, .h,.sh .etc   
4           .c, .cpp, .h,.sh .etc   
5           .c, .cpp, .h,.sh .etc   
6           .c, .cpp, .h,.sh .etc   
7           .c, .cpp, .h,.sh .etc   
8           .c, .cpp, .h,.sh .etc   
9           .c, .cpp, .h,.sh .etc   
10          .c, .cpp, .h,.sh .etc   
11          .c, .cpp, .h,.sh .etc   
12          .c, .cpp, .h,.sh .etc   
13          .c, .cpp, .h,.sh .etc   
------------

Binary_SourceJunctionTable
-------------
BinaryId    SourceId
1           1
1           2
1           3
1           4
2           5
2           3
2           6
2           7
4           1
4           2
4           8
4           9
-------------

嗨凯文

首先,我创建了所有项目,应用和源信息表。然后我成功创建了projectbinary_AppJunctionTable,但是当我尝试创建app_binaryJunction表时。我在下面粘贴了错误 -

-ERROR 1022: Can't write; duplicate key in table 'appid_objid_junctiontable'
SQL Statement:
CREATE TABLE `trial`.`appid_objid_junctiontable` (
  `Id` INT NOT NULL,
  `app_id` INT NULL,
  `obj_id` INT NULL,
  PRIMARY KEY (`Id`),
  INDEX `app_id_idx` (`app_id` ASC),
  INDEX `obj_id_idx` (`obj_id` ASC),
  CONSTRAINT `app_id_fk`
    FOREIGN KEY (`app_id`)
    REFERENCES `trial`.`applisttable` (`Appld`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION,
  CONSTRAINT `obj_id_fk`
    FOREIGN KEY (`obj_id`)
    REFERENCES `trial`.`objectlist_table` (`ObjectId`)
    ON DELETE NO ACTION
    ON UPDATE NO ACTION)

- 请帮忙。

7月21日编辑

嗨Kevin,感谢您的sql查询。我试图在projectbinary table和applisttable之间创建联结表,但它失败如下。

CREATE TABLE trial.projid_appid_junctiontable ( 
  proj_id INT NOT NULL, 
  app_id INT NOT NULL, 
  PRIMARY KEY (proj_id, app_id), 
  FOREIGN KEY (proj_id) REFERENCES trial.projectlisttable (ProjectBinaryId) ON DELETE NO     ACTION ON UPDATE NO ACTION, 
  FOREIGN KEY (app_id) REFERENCES trial.applisttable (AppId) ON DELETE NO ACTION
);
Error code: 1215 Cannot add foreign key constraint.

1 个答案:

答案 0 :(得分:0)

设计适用于您提供的尽可能多的信息。我唯一的抱怨是“SourceInfo_Table”不是平的,这意味着它具有多个值的列“源文件”。你应该建立另一个联结表。称之为“sourceInfo_fileTypes”或任何你想要的东西。放入sourceID和文件类型,每种文件类型一条记录。理想情况下,您还可以使用另一个名为fileTypes的表,而是使用外键链接到它们。

至于删除项目二进制文件的SQL。您必须记住它们具有外键依赖关系(假设您设置了约束)。有很多方法可以解决这个问题。同样,理想情况下,您应该在每个外键上使用ON DELETE CASCADE。这意味着当您从项目列表中删除某些内容时,它会自动在其他位置删除。如果您没有打开并且已经设置了约束,那么您希望删除下面的约束,然后使用该子句添加它。

DROP CONSTRAINT :(每个人都这样做)

ALTER TABLE ProjectBinary_AppJunctionTable
DROP CONSTRAINT ProjectBinaryId; 

在DELETE CASCADE上添加约束:(为每一个做一次)

ALTER TABLE ProjectBinary_AppJunctionTable
ADD FOREIGN KEY (ProjectBinaryId)
REFERENCES ProjectList_table(ProjectBinaryId) ON DELETE CASCADE

此外,要从其中一个表中删除某些内容,请使用下面的通用代码。此外,如果您为每个表设置正确的代码,上面的代码应该处理任何依赖项。

DELETE FROM one_of_your_tables
WHERE on_of_you_columns=some_value_in_the_column;

编辑7月18日: 你不需要说约束,如果它是一个外键,它自动成为约束,只有说约束的理由是命名键。您不需要在此处对其进行索引,因为它已被索引为另一个表中的主键。您不需要另一个ID作为主键,它是无用的。您需要做的就是说app_id结合obj_id创建一个主键,这意味着这两个列在另一行上永远不会相同。请尝试以下代码,看看它是如何进行的。

CREATE TABLE trial.appid_objid_junctiontable ( 
app_id INT NOT NULL, 
obj_id INT NOT NULL, 
PRIMARY KEY (app_id, obj), 
FOREIGN KEY (app_id) REFERENCES trial.applisttable (Appld) ON DELETE NO ACTION ON UPDATE NO ACTION, 
FOREIGN KEY (obj_id) REFERENCES trial.objectlist_table (ObjectId) ON DELETE NO ACTION
)