簡體   English   中英

如何在不丟失外鍵的情況下合並兩個sqlite數據庫?

[英]How to merge two sqlite databases without losing foreign keys?

我正在開發用於使用fluttersqflite軟件包學習外語的移動應用程序。 該應用程序具有sqlite數據庫,其中包含單詞表和某種類型的集合(多對多關系)。 此數據存儲在應用程序資產中,並在安裝應用程序時像在sqflite指南https://github.com/tekartik/sqflite/blob/master/sqflite/doc/opening_asset_db.md中一樣加載到移動數據庫目錄中
用戶可以添加自己的單詞和集合,也可以添加或更改我的單詞。 我曾經以為我可以使用sqlite upsert實現此目的,但是如果用戶添加的單詞與我在應用程序更新中添加的單詞相同,則會出現沖突。 如果我進行upsert則該單詞不會出現在我的單詞集中,因為它們受id約束;否則,如果我執行replace ,則單詞將從用戶的集合中消失。

我想我需要在sqlite insert or replace某種級聯ID更新,但是沒有這種功能。

有什么想法嗎?

我認為我需要在sqlite插入或替換中進行某種級聯ID更新,但是沒有這種功能。

有這樣的功能; 您可以將ON UPDATE CASCADE指定為FOREIGN KEY定義/條款的一部分。 您還可以編碼ON DELETE CASCADE SQLite外鍵支持-4.3。 ON DELETE和ON UPDATE操作

由於這被編碼為子表的一部分,因此您不能使用ALTER TABLE COLUMN更改列的屬性(除了重命名列之外)。 你不得不 :-

  1. 重命名子表。
  2. 使用原來的名字與變化創建替換表,然后使用INSERT INTO replacement_table_with_original_name SELECT * FROM renamed_table (明顯改變replacement_table_with_original_namerenamed_table)實際名稱。
  3. 當高興時,DROP重命名表。

例如,考慮場景的以下表示形式(從可用信息中得出),這將在保留現有數據的同時添加ON UPDATE CASCADEON DELETE CASCADE ,它另外刪除無沖突的行,並且還更新引用的值而無沖突或丟失:-

-- Create the original tables and load some test data
CREATE TABLE IF NOT EXISTS word_table (id INTEGER PRIMARY KEY, other_column TEXT);
INSERT INTO word_table VALUES (null,'WA'),(null,'WB'),(null,'WC');
CREATE TABLE IF NOT EXISTS collection_table (id INTEGER PRIMARY KEY, other_column TEXT);
INSERT INTO collection_table VALUES (null,'CA'),(null,'CB'),(null,'CC');
CREATE TABLE IF NOT EXISTS word_collection_map (
    word_reference INTEGER NOT NULL REFERENCES word_table(id), 
    collection_reference  INTEGER NOT NULL REFERENCES collection_table(id), 
    PRIMARY KEY (word_reference,collection_reference) ) WITHOUT ROWID;
INSERT INTO word_collection_map VALUES(1,1),(3,2),(3,3),(2,1),(2,2),(2,3);

-- show the result
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
;

-- ADDING CASCADE
ALTER TABLE word_collection_map RENAME TO old_word_collection_map;
CREATE TABLE IF NOT EXISTS word_collection_map (
    word_reference INTEGER NOT NULL REFERENCES word_table(id) ON UPDATE CASCADE ON DELETE CASCADE , 
    collection_reference  INTEGER NOT NULL REFERENCES collection_table(id)  ON UPDATE CASCADE ON DELETE CASCADE, 
    PRIMARY KEY (word_reference,collection_reference) ) WITHOUT ROWID;
INSERT INTO word_collection_map SELECT * FROM old_word_collection_map;
DROP TABLE IF EXISTS old_word_collection_map;
-- Show results (should match first)
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
;

-- DELETE a word no conflicts
DELETE FROM word_table WHERE other_column = 'WC';
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
;

-- UPDATE the FK parent no conflicts
UPDATE collection_table SET id = 10 WHERE id = 3;
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
;

結果:-

日志:-

-- Create the original tables and load some test data
CREATE TABLE IF NOT EXISTS word_table (id INTEGER PRIMARY KEY, other_column TEXT)
> OK
> Time: 0.118s


INSERT INTO word_table VALUES (null,'WA'),(null,'WB'),(null,'WC')
> Affected rows: 3
> Time: 0.104s


CREATE TABLE IF NOT EXISTS collection_table (id INTEGER PRIMARY KEY, other_column TEXT)
> OK
> Time: 0.097s


INSERT INTO collection_table VALUES (null,'CA'),(null,'CB'),(null,'CC')
> Affected rows: 3
> Time: 0.094s


CREATE TABLE IF NOT EXISTS word_collection_map (
    word_reference INTEGER NOT NULL REFERENCES word_table(id), 
    collection_reference  INTEGER NOT NULL REFERENCES collection_table(id), 
    PRIMARY KEY (word_reference,collection_reference) ) WITHOUT ROWID
> OK
> Time: 0.097s


INSERT INTO word_collection_map VALUES(1,1),(3,2),(3,3),(2,1),(2,2),(2,3)
> Affected rows: 6
> Time: 0.105s


-- show the result
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
> OK
> Time: 0.001s


-- ADDING CASCADE
ALTER TABLE word_collection_map RENAME TO old_word_collection_map
> OK
> Time: 0.108s


CREATE TABLE IF NOT EXISTS word_collection_map (
    word_reference INTEGER NOT NULL REFERENCES word_table(id) ON UPDATE CASCADE ON DELETE CASCADE , 
    collection_reference  INTEGER NOT NULL REFERENCES collection_table(id)  ON UPDATE CASCADE ON DELETE CASCADE, 
    PRIMARY KEY (word_reference,collection_reference) ) WITHOUT ROWID
> OK
> Time: 0.096s


INSERT INTO word_collection_map SELECT * FROM old_word_collection_map
> Affected rows: 6
> Time: 0.094s


DROP TABLE IF EXISTS old_word_collection_map
> OK
> Time: 0.081s


-- Show results (should match first)
SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
> OK
> Time: 0s


-- DELETE a word no conflicts
DELETE FROM word_table WHERE other_column = 'WC'
> Affected rows: 1
> Time: 0.086s


SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
> OK
> Time: 0.001s


-- UPDATE the FK parent no conflicts
UPDATE collection_table SET id = 10 WHERE id = 3
> Affected rows: 1
> Time: 0.089s


SELECT word_table.other_column, collection_table.other_column 
FROM word_collection_map 
    JOIN word_table ON word_table.id = word_reference
    JOIN collection_table ON collection_table.id = collection_reference
> OK
> Time: 0s

結果1(基礎數據)

在此處輸入圖片說明

結果2(架構更改后)

在此處輸入圖片說明

結果3(刪除后)

在此處輸入圖片說明

結果4(更新后)

在此處輸入圖片說明

暫無
暫無

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

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