Sqlite将数据库合并为一个,具有唯一值,保留foregin键关系

Sqlite将数据库合并为一个,具有唯一值,保留foregin键关系,sql,database,sqlite,merge,Sql,Database,Sqlite,Merge,提供了两种解决方案(请参见底部的链接),但这两种解决方案都失败了: 1.给定数据库中的表(相同)结构,例如: DB1 果 果汁 配方(连接表) ---------------------------- | id | juice_id | fruit_id | ---------------------------- | 1 | 1 | 1 | | 2 | 1 | 2 | | 3 | 2 | 1 | | 4

提供了两种解决方案(请参见底部的链接),但这两种解决方案都失败了:

1.给定数据库中的表(相同)结构,例如: DB1 果 果汁 配方(连接表)
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 2        |
| 3  | 2        | 1        |
| 4  | 2        | 3        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 3        |
| 3  | 2        | 2        |
| 4  | 2        | 4        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 3        |
| 2  | 1        | 2        |
| 3  | 2        | 3        |
| 4  | 2        | 1        |
++++++++++++++++++++++++++++
| 5  | 3        | 1        |
| 6  | 3        | 3        |
| 7  | 4        | 2        |
| 8  | 4        | 4        |
----------------------------
DB2 果 果汁 配方(连接表)
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 2        |
| 3  | 2        | 1        |
| 4  | 2        | 3        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 3        |
| 3  | 2        | 2        |
| 4  | 2        | 4        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 3        |
| 2  | 1        | 2        |
| 3  | 2        | 3        |
| 4  | 2        | 1        |
++++++++++++++++++++++++++++
| 5  | 3        | 1        |
| 6  | 3        | 3        |
| 7  | 4        | 2        |
| 8  | 4        | 4        |
----------------------------
2.将其转换为: DB3 果 果汁 配方(连接表)
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 2        |
| 3  | 2        | 1        |
| 4  | 2        | 3        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 1        |
| 2  | 1        | 3        |
| 3  | 2        | 2        |
| 4  | 2        | 4        |
----------------------------
----------------------------
| id | juice_id | fruit_id |
----------------------------
| 1  | 1        | 3        |
| 2  | 1        | 2        |
| 3  | 2        | 3        |
| 4  | 2        | 1        |
++++++++++++++++++++++++++++
| 5  | 3        | 1        |
| 6  | 3        | 3        |
| 7  | 4        | 2        |
| 8  | 4        | 4        |
----------------------------
请注意,水果id相应地发生了变化,尽管水果id发生了变化,但仍保留了关系。id是主整数自动递增键,Recipe包含两个foregin键(加上自己的主整数自动递增键)

3.只有两种建议的解决方案是: (a)

其他答案,例如,重复相同的模式。也许这是一个解决办法,但我说不出,这个问题的长度吓坏了我

此外,如前所述,没有gui比较和合并解决方案。至少除了2011 sqlitecompare,它可能在Windows中也能工作(我正在寻找Linux工具) 中的一些观点也证实,几乎没有任何用户友好的gui具有合并选项

所以,问题是。
如何在Linux中合并sqlite DB,保留关系,但不保留标记/注释中的重复值?我原以为保持有组织的结构是在数据库中保存东西的主要原因,但似乎我不明白,如果两个篮子合并,为什么我要在一个篮子中保存两个相同的水果。我的篮子里应该有独特的水果和饮料,我想吃猕猴桃:)

我还没有读完所有的8个答案,你的答案本身就是一个史诗般的TL;不过,我有一个建议。为水果和果汁创建新表时,添加db2id和db2id列。在insert过程中,分别从db1和db2填充列(将填充一个或两个,或者两者都填充)。按原样将数据从db1和db2分别复制到recipe1和recipe2。现在,您需要使用一个简单的语句将数据插入到配方表中,您可以在几秒钟内(当所有表格都在眼前时)将其写入@CL仔细阅读。那篇帖子没有提到不丢弃重复的内容。没错,但我认为良好的描述有希望减少人们对同样东西的需求。模块化问题/答案浮现在脑海中。事实上,我确实读了9个以上的相关问题,因为,CL哪里又错了,这不是家庭作业,我关心的是解决方案。所以我会检查一下josepn的,并接受它是否有效。我很乐意接受这个答案,只要它有效,因为它最接近于完整的解决方案(尽管令人遗憾的是粗糙=iter)。当然,它是原始sql,但可能比编程解决方案更快,有些人甚至更喜欢这种方式。我想知道两件事:当已经存在非均匀VAL时fks的问题。。。既然我也有关于foregin键的索引,我想我需要重新创建它们,以确保上述答案的完整性?嗯,还有最后一件事。从db1中插入到配方中。为什么还要使用id,让sqlite重新使用不是更好吗?所以它基本上是有效的——我的意思是,如果任何东西不起作用,那都是我的错,因为我需要将它调整到我的模式。我还有什么其他的绊脚石——这可能是给其他人的教训?实际上,如果您不将任何参数传递给sqlite3,它将在内存上运行,这可能会/可能不会更快,但要“保存”到文件,您需要在脚本末尾执行.backup filename。此外,您可以将此脚本作为“整体”传递,也可以执行“.read scriptname”,反正我学到了很多。谢谢@josepn@user3264463-这是第一个数据库的精确副本。如果这不是很重要,那么最好允许不断增长的sqlite id
$sqlite3 database1.db '.dump' >> tmp
$sqlite3 database2.db '.dump' >> tmp
$sqlite3 database3.db '.import tmp'
$ #sometimes sqlite3 database3.db < 'tmp' instead of last row
$ sqlite3 newdb
attach 'b.db' as toMerge;   
BEGIN; 
insert into newdb select * from toMerge.sometable; 
COMMIT;
PRAGMA foreign_keys = on;

ATTACH DATABASE 'db1.sqlite' AS db1;

ATTACH DATABASE 'db2.sqlite' AS db2;

BEGIN;

CREATE TABLE Fruit      (
                          id            INTEGER PRIMARY KEY NOT NULL,
                          name          TEXT    UNIQUE ON CONFLICT IGNORE
                          )
                          ;

CREATE TABLE Juice      (
                          id            INTEGER PRIMARY KEY NOT NULL,
                          name          TEXT    UNIQUE ON CONFLICT IGNORE
                        )
                        ;

CREATE TABLE Recipe     (
                          id            INTEGER PRIMARY KEY NOT NULL,
                          juice_id      INTEGER NOT NULL,
                          fruit_id      INTEGER NOT NULL,
                          FOREIGN KEY   ( juice_id ) REFERENCES Juice ( id )
                                        ON UPDATE CASCADE
                                        ON DELETE CASCADE,
                          FOREIGN KEY   ( fruit_id ) REFERENCES Fruit ( id )
                                        ON UPDATE CASCADE
                                        ON DELETE CASCADE
                        )
                        ;


INSERT INTO Fruit  ( id, name )               SELECT id, name FROM db1.Fruit;
INSERT INTO Juice  ( id, name )               SELECT id, name FROM db1.Juice;
INSERT INTO Recipe ( id, juice_id, fruit_id ) SELECT id, juice_id, fruit_id FROM db1.Recipe;

INSERT INTO Fruit ( name ) SELECT name FROM db2.Fruit;
INSERT INTO Juice ( name ) SELECT name FROM db2.Juice;

CREATE TEMPORARY TABLE Recipe_tmp AS
                                    SELECT Juice.name AS j_name, Fruit.name AS f_name
                                      FROM db2.Recipe, db2.Fruit, db2.Juice
                                        WHERE db2.Recipe.juice_id = db2.Juice.id AND db2.Recipe.fruit_id = db2.Fruit.id
;

INSERT INTO Recipe ( juice_id, fruit_id ) SELECT j.id, f.id
                                            FROM Recipe_tmp AS r, Juice AS j, Fruit AS f
                                              WHERE r.j_name = j.name AND r.f_name = f.name
;


DROP TABLE Recipe_tmp;

COMMIT;

DETACH DATABASE db1;
DETACH DATABASE db2;