簡體   English   中英

MySQL innoDB外鍵從三個表中刪除級聯

[英]MySQL innoDB foreign key delete cascade from three tables

我有一個MySQL數據庫,有幾個表,連接表連接。 我的問題是DELETE語句非常復雜。 因此,為了使它們更簡單,我嘗試使用級聯刪除設置外鍵。

這是我的表格結構

--------------
-n_size_class-
--------------
-s_id        -
-s_name      -
--------------

-------------
-n_size_rows-
-------------
-sr_id      -
-sr_name    -
-sr_value   -
-------------

----------------
-n_size_columns-
----------------
-sc_id         -
-sc_name       -
-sc_value      -
----------------

-----------------
-n_size_row_link-
-----------------
-srl_id         -
-srl_size       -
-srl_row        -
-----------------

-----------------
-n_size_col_link-
-----------------
-scl_id         -
-scl_size       -
-scl_col        -
-----------------

我們的想法是n_size_class表是主要對象(大小類),然后行和列是size類的子對象。 然后使用鏈接表將行和列綁定到size類。 以前,我的插入工作正常,刪除是一個問題。 現在我嘗試設置刪除級聯,我的插入被破壞(但我的刪除工作正常)。 我的目標是使插入正常工作,插入size_class,然后對於每一行,它插入到size_row中,然后也插入到size_row_link中,對於列也是如此。 然后,當您只刪除size_class時,也會刪除所有鏈接,行和列。

外鍵/級聯這些表的正確方法是什么? 現在,當我嘗試在列或行表中插入任何內容時,我收到外鍵約束錯誤。

根據請求,create語句:

CREATE TABLE `n_size_class` (
  `s_id` int(11) NOT NULL auto_increment,
  `s_name` text NOT NULL,
  PRIMARY KEY  (`s_id`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE `n_size_columns` (
  `sc_id` int(11) NOT NULL auto_increment,
  `sc_name` text NOT NULL,
  `sc_value` text NOT NULL,
  PRIMARY KEY  (`sc_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE `n_size_rows` (
  `sr_id` int(11) NOT NULL auto_increment,
  `sr_name` text NOT NULL,
  `sr_value` text NOT NULL,
  PRIMARY KEY  (`sr_id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE `n_size_row_link` (
  `srl_id` int(11) NOT NULL auto_increment,
  `srl_size` int(11) NOT NULL,
  `srl_row` int(11) NOT NULL,
  PRIMARY KEY  (`srl_id`),
  KEY `srl_row` (`srl_row`),
  KEY `srl_size` (`srl_size`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

CREATE TABLE `n_size_col_link` (
  `scl_id` int(11) NOT NULL auto_increment,
  `scl_size` int(11) NOT NULL,
  `scl_col` int(11) NOT NULL,
  PRIMARY KEY  (`scl_id`),
  KEY `scl_col` (`scl_col`),
  KEY `scl_size` (`scl_size`)
) ENGINE=InnoDB  DEFAULT CHARSET=utf8 AUTO_INCREMENT=1;

我看到它的方式你有3個對象:大小,行和列。

我假設:

  • 鏈接表是因為可以將大小分配給許多行/列,並且行/列可以具有許多大小。
  • 當刪除大小時,應刪除分配,而不刪除行/列。
  • 刪除行/列時,應刪除分配,而不是Sizes本身。

所以:

CREATE TABLE sizes (
  size_id INTEGER UNSIGNED AUTO_INCREMENT,
  size_name VARCHAR(255),
  ...
  PRIMARY KEY(size_id)
);

CREATE TABLE rows (
  row_id INTEGER UNSIGNED AUTO_INCREMENT,
  ...
  PRIMARY KEY(row_id)
);

CREATE TABLE columns (
  col_id INTEGER UNSIGNED AUTO_INCREMENT,
  ...
  PRIMARY KEY(col_id)
);

CREATE TABLE l_row_size (
  row_id INTEGER UNSIGNED,
  size_id INTEGER UNSIGNED,
  PRIMARY KEY(row_id, size_id),
  CONSTRAINT FOREIGN KEY l_row_size-row_id (row_id) REFERENCES rows (row_id) ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT FOREIGN KEY l_row_size-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE
);


CREATE TABLE l_col_size (
  col_id INTEGER UNSIGNED,
  size_id INTEGER UNSIGNED,
  PRIMARY KEY(col_id, size_id),
  CONSTRAINT FOREIGN KEY l_col_size-row_id (col_id) REFERENCES rows (col_id) ON UPDATE CASCADE ON DELETE CASCADE,
  CONSTRAINT FOREIGN KEY l_col_size-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE
);

然后:

foreach( $sizes as $size ) {
  $dbh->query("INSERT INTO sizes (size_name) VALUES ('{$size['name']}')");
  $size_id = $dbh->last_insert_id();

  foreach( $rows as $row ) {
    $dbh->query("INSERT INTO l_row_size (size_id, row_id) VALUES ($size_id, {$row['id']})");
  }

  foreach( $cols as $col ) {
    $dbh->query("INSERT INTO l_col_size (size_id, col_id) VALUES ($size_id, {$col['id']})");
  }
}

編輯

Sharf評論說:

每個Size Class可以包含許多行和多列,但每個行和列只能屬於一個size類。

那么你只需要3個表:

CREATE TABLE sizes (
  size_id INTEGER UNSIGNED AUTO_INCREMENT,
  ...
  PRIMARY KEY(size_id)
);

CREATE TABLE rows (
  row_id INTEGER UNSIGNED AUTO_INCREMENT,
  size_id INTEGER UNSIGNED,
  ...
  PRIMARY KEY(row_id)
  CONSTRAINT FOREIGN KEY rows-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE,
);

CREATE TABLE columns (
  col_id INTEGER UNSIGNED AUTO_INCREMENT,
  size_id INTEGER UNSIGNED,
  ...
  PRIMARY KEY(col_id),
  CONSTRAINT FOREIGN KEY cols-size_id (size_id) REFERENCES sizes (size_id) ON UPDATE CASCADE ON DELETE CASCADE,
);

鏈接表僅在n:m關系的情況下才真正有用,這是兩個1:n關系的情況。 每個Row / Column對象只需要存儲對它們所屬的Size的引用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM