SQLite Restrict/Update/cascade
SQLite Restrict/Update/cascade
"should not be able delete movie if there are any linked data present",
async done => {
const movieId = 100;
const query =
`DELETE FROM ${MOVIES}
WHERE id = ${movieId}`;
"should be able to delete movie",
async done => {
const movieId = 5915;
const query = `DELETE FROM ${MOVIES}
WHERE id = ${movieId}`;
所以我有这两行,但我想在第二个删除而不是在第一个删除,我知道它与更新、级联、删除、限制有关,但我无法弄清楚或找到更多信息现在...后端看起来像
const CREATE_MOVIE_GENRES_TABLE = `
CREATE TABLE ${MOVIE_GENRES} (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
)`;
超过一部电影 tables
我知道我从电影中删除的部分肯定是错误的...而且我也想不出创建 table 部分的正确方法
简而言之,你所拥有的似乎没问题。
假设 100 通过 [=77 映射 到一种或多种流派=] table(第一个)并且 5915 未映射 通过movies_genres table 然后:-
- 由于外键约束冲突,第一个
DELETE FROM movies WHERE id=100
将失败 。
- 第二个
DELETE FROM movies WHERE id=5915
将删除电影。
- 正在更新 100,将 ID 设置为 999,例如
UPDATE movies SET id=999 WHERE id=100
将工作 并且更新将传播到 movies_genres movie_id 为 100 的行将其设置为 999.
- 正在更新 5915,将 ID 设置为 55555,例如
UPDATE movies SET id=55555 WHERE id=5915
会工作 ,movies_genres 中没有行 movie_id 为 5195。
但是,如果 5915 有映射并且您想强制删除它,那么您必须从 movie_genres table 中删除映射,然后删除 5915 例如
DELETE FROM movie_genres WHERE movie_id=5915;
其次是
DELETE FROM movies WHERE id=5915;
演示
为了证明以上内容(注意 updates/deletions 的顺序适合单个 运行):-
DROP TABLE IF EXISTS movie_genres;
DROP TABLE IF EXISTS movies;
DROP TABLE IF EXISTS genres;
CREATE TABLE IF NOT EXISTS movies (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS genres (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE movie_genres (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
);
INSERT INTO movies VALUES (100,'Movie100'),(5915,'Movie5915'),(10,'Movie10');
INSERT INTO genres VALUES (1,'Genre1'),(2,'Genre2'),(3,'Genre3');
INSERT INTO movie_genres VALUES /* map movie 100 genre 1*/ (100,1), /* extras */(10,1),(10,2),(10,3);
UPDATE movies SET id = 55555 WHERE id = 5915;
UPDATE movies SET id = 999 WHERE id = 100;
/* reset id's */
UPDATE movies SET id=5915 WHERE id=5555;
UPDATE movies SET id=100 WHERE id=999;
/* Will delete as 5915 has no genres */
DELETE FROM movies WHERE id = 5915;
/* Reapply 5915 that was deleted and add mapppings to genres */
INSERT INTO movies VALUES (5915,'Movie5915');
INSERT INTO movie_genres VALUES /* map movie 5915 genre 1,2 and 3*/ (5915,1),(5915,2),(5915,3);
/* Force delete 5915 by-passing FK conflict i.e. doing the equivalent of cascade before deletion */
DELETE FROM movie_genres WHERE movie_id=5915;
DELETE FROM movies WHERE id= 5915;
/* DELETE WILL FAIL due to FK conflict */
DELETE FROM movies WHERE id = 100;
运行 以上消息日志:-
DROP TABLE IF EXISTS movie_genres
> OK
> Time: 0.186s
DROP TABLE IF EXISTS movies
> OK
> Time: 0.12s
DROP TABLE IF EXISTS genres
> OK
> Time: 0.074s
CREATE TABLE IF NOT EXISTS movies (id INTEGER PRIMARY KEY, name TEXT)
> OK
> Time: 0.084s
CREATE TABLE IF NOT EXISTS genres (id INTEGER PRIMARY KEY, name TEXT)
> OK
> Time: 0.122s
CREATE TABLE movie_genres (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
)
> OK
> Time: 0.169s
INSERT INTO movies VALUES (100,'Movie100'),(5915,'Movie5915'),(10,'Movie10')
> Affected rows: 3
> Time: 0.084s
INSERT INTO genres VALUES (1,'Genre1'),(2,'Genre2'),(3,'Genre3')
> Affected rows: 3
> Time: 0.084s
INSERT INTO movie_genres VALUES /* map movie 100 genre 1*/ (100,1), /* extras */(10,1),(10,2),(10,3)
> Affected rows: 4
> Time: 0.084s
UPDATE movies SET id = 55555 WHERE id = 5915
> Affected rows: 1
> Time: 0.084s
UPDATE movies SET id = 999 WHERE id = 100
> Affected rows: 1
> Time: 0.096s
/* reset id's */
UPDATE movies SET id=5915 WHERE id=5555
> Affected rows: 0
> Time: 0s
UPDATE movies SET id=100 WHERE id=999
> Affected rows: 1
> Time: 0.096s
/* Will delete as 5915 has no genres */
DELETE FROM movies WHERE id = 5915
> Affected rows: 0
> Time: 0s
/* Reapply 5915 */
INSERT INTO movies VALUES (5915,'Movie5915')
> Affected rows: 1
> Time: 0.083s
INSERT INTO movie_genres VALUES /* map movie 5915 genre 1,2 and 3*/ (5915,1),(5915,2),(5915,3)
> Affected rows: 3
> Time: 0.096s
/* Force delete 5915 by-passing FK conflict i.e. doing the equivalent of cascade before deletion */
DELETE FROM movie_genres WHERE movie_id=5915
> Affected rows: 3
> Time: 0.107s
DELETE FROM movies WHERE id= 5915
> Affected rows: 1
> Time: 0.084s
/* Nothing to delete due to id change */
DELETE FROM movies WHERE id = 100
> FOREIGN KEY constraint failed
> Time: 0.003s
"should not be able delete movie if there are any linked data present",
async done => {
const movieId = 100;
const query =
`DELETE FROM ${MOVIES}
WHERE id = ${movieId}`;
"should be able to delete movie",
async done => {
const movieId = 5915;
const query = `DELETE FROM ${MOVIES}
WHERE id = ${movieId}`;
所以我有这两行,但我想在第二个删除而不是在第一个删除,我知道它与更新、级联、删除、限制有关,但我无法弄清楚或找到更多信息现在...后端看起来像
const CREATE_MOVIE_GENRES_TABLE = `
CREATE TABLE ${MOVIE_GENRES} (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
)`;
超过一部电影 tables
我知道我从电影中删除的部分肯定是错误的...而且我也想不出创建 table 部分的正确方法
简而言之,你所拥有的似乎没问题。
假设 100 通过 [=77 映射 到一种或多种流派=] table(第一个)并且 5915 未映射 通过movies_genres table 然后:-
- 由于外键约束冲突,第一个
DELETE FROM movies WHERE id=100
将失败 。 - 第二个
DELETE FROM movies WHERE id=5915
将删除电影。 - 正在更新 100,将 ID 设置为 999,例如
UPDATE movies SET id=999 WHERE id=100
将工作 并且更新将传播到 movies_genres movie_id 为 100 的行将其设置为 999. - 正在更新 5915,将 ID 设置为 55555,例如
UPDATE movies SET id=55555 WHERE id=5915
会工作 ,movies_genres 中没有行 movie_id 为 5195。
但是,如果 5915 有映射并且您想强制删除它,那么您必须从 movie_genres table 中删除映射,然后删除 5915 例如
DELETE FROM movie_genres WHERE movie_id=5915;
其次是
DELETE FROM movies WHERE id=5915;
演示
为了证明以上内容(注意 updates/deletions 的顺序适合单个 运行):-
DROP TABLE IF EXISTS movie_genres;
DROP TABLE IF EXISTS movies;
DROP TABLE IF EXISTS genres;
CREATE TABLE IF NOT EXISTS movies (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE IF NOT EXISTS genres (id INTEGER PRIMARY KEY, name TEXT);
CREATE TABLE movie_genres (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
);
INSERT INTO movies VALUES (100,'Movie100'),(5915,'Movie5915'),(10,'Movie10');
INSERT INTO genres VALUES (1,'Genre1'),(2,'Genre2'),(3,'Genre3');
INSERT INTO movie_genres VALUES /* map movie 100 genre 1*/ (100,1), /* extras */(10,1),(10,2),(10,3);
UPDATE movies SET id = 55555 WHERE id = 5915;
UPDATE movies SET id = 999 WHERE id = 100;
/* reset id's */
UPDATE movies SET id=5915 WHERE id=5555;
UPDATE movies SET id=100 WHERE id=999;
/* Will delete as 5915 has no genres */
DELETE FROM movies WHERE id = 5915;
/* Reapply 5915 that was deleted and add mapppings to genres */
INSERT INTO movies VALUES (5915,'Movie5915');
INSERT INTO movie_genres VALUES /* map movie 5915 genre 1,2 and 3*/ (5915,1),(5915,2),(5915,3);
/* Force delete 5915 by-passing FK conflict i.e. doing the equivalent of cascade before deletion */
DELETE FROM movie_genres WHERE movie_id=5915;
DELETE FROM movies WHERE id= 5915;
/* DELETE WILL FAIL due to FK conflict */
DELETE FROM movies WHERE id = 100;
运行 以上消息日志:-
DROP TABLE IF EXISTS movie_genres
> OK
> Time: 0.186s
DROP TABLE IF EXISTS movies
> OK
> Time: 0.12s
DROP TABLE IF EXISTS genres
> OK
> Time: 0.074s
CREATE TABLE IF NOT EXISTS movies (id INTEGER PRIMARY KEY, name TEXT)
> OK
> Time: 0.084s
CREATE TABLE IF NOT EXISTS genres (id INTEGER PRIMARY KEY, name TEXT)
> OK
> Time: 0.122s
CREATE TABLE movie_genres (
movie_id integer NOT NULL REFERENCES movies(id) ON DELETE RESTRICT ON UPDATE CASCADE,
genre_id integer NOT NULL REFERENCES genres(id) ON DELETE RESTRICT,
Primary key (movie_id, genre_id)
)
> OK
> Time: 0.169s
INSERT INTO movies VALUES (100,'Movie100'),(5915,'Movie5915'),(10,'Movie10')
> Affected rows: 3
> Time: 0.084s
INSERT INTO genres VALUES (1,'Genre1'),(2,'Genre2'),(3,'Genre3')
> Affected rows: 3
> Time: 0.084s
INSERT INTO movie_genres VALUES /* map movie 100 genre 1*/ (100,1), /* extras */(10,1),(10,2),(10,3)
> Affected rows: 4
> Time: 0.084s
UPDATE movies SET id = 55555 WHERE id = 5915
> Affected rows: 1
> Time: 0.084s
UPDATE movies SET id = 999 WHERE id = 100
> Affected rows: 1
> Time: 0.096s
/* reset id's */
UPDATE movies SET id=5915 WHERE id=5555
> Affected rows: 0
> Time: 0s
UPDATE movies SET id=100 WHERE id=999
> Affected rows: 1
> Time: 0.096s
/* Will delete as 5915 has no genres */
DELETE FROM movies WHERE id = 5915
> Affected rows: 0
> Time: 0s
/* Reapply 5915 */
INSERT INTO movies VALUES (5915,'Movie5915')
> Affected rows: 1
> Time: 0.083s
INSERT INTO movie_genres VALUES /* map movie 5915 genre 1,2 and 3*/ (5915,1),(5915,2),(5915,3)
> Affected rows: 3
> Time: 0.096s
/* Force delete 5915 by-passing FK conflict i.e. doing the equivalent of cascade before deletion */
DELETE FROM movie_genres WHERE movie_id=5915
> Affected rows: 3
> Time: 0.107s
DELETE FROM movies WHERE id= 5915
> Affected rows: 1
> Time: 0.084s
/* Nothing to delete due to id change */
DELETE FROM movies WHERE id = 100
> FOREIGN KEY constraint failed
> Time: 0.003s