需要通用Sqlite外键说明

时间:2018-08-04 16:01:13

标签: sqlite

这可能是一个非常愚蠢的问题,所以请忍受:)

在过去的两周中,我一直在学习和实现Sqlite的某些项目数据。我喜欢按键的概念,但是有一件事我无法绕开我的头。

在数据库中插入大数据集时,如何引用外键?病给你一个例子:

我要插入300行数据,每行包含(“ a”,“ b”,“ c”,“ d”,“ e”,“ f”,“ g”)。一切都进入同一个表(原始表)。

现在我在数据库中存储了数据,我想为值“ c”创建另一个表(secondary_table)。然后,我自然希望original_table具有链接到secondary_tables主键的外键。

我知道您可以在插入之前创建外键,然后在插入之前用相应的整数替换“ c”。但是,这似乎效率很低,因为在插入之前必须替换大量数据。

所以我的问题是如何让外键替换已经创建的表中的文本?

欢呼

1 个答案:

答案 0 :(得分:1)

  

所以我的问题是如何让外键替换其中的文本   一个已经创建的表?

是/否

也就是说,您可以将C列替换为对辅助表的引用(除了添加新建议的列之外,还可以像下面那样进行操作) 不能的表重新定义了列的属性,因此使其具有 INTEGER 的类型相似性(实际上不是问题)或指定其具有 FOREIGN KEY 约束。

对于300行来说,批量更新可能不是问题(甚至没有在这里完成事务)。

  

如何在插入大数据集时引用外键   数据库?

这是有关如何执行此操作的SQL,但不要尝试使用C列,而是添加一个新列,该列实际上使C列多余。但是,新列将具有INTEGER类型的关联性,并且还将应用FOREIGN KEY约束。

300行什么都不是,示例代码使用3000行,尽管C列仅包含短文本值。

:-

-- Create the original table with column c having a finite number of values (0-25)
DROP TABLE IF EXISTS original_table;
CREATE TABLE IF NOT EXISTS original_table (A TEXT, B TEXT, C TEXT, D TEXT, E TEXT, F TEXT, G TEXT);

-- Load the original table with some data
WITH RECURSIVE counter(cola,colb,colc,cold,cole,colf,colg) AS (
    SELECT random() % 26 AS cola, random() % 26 AS colb,abs(random() % 26) AS colc,random() % 26 AS cold,random() % 26 AS cole,random() % 26 AS colf,random() % 26 AS colg 
    UNION ALL 
    SELECT random() % 26 AS cola, random() % 26 AS colb,abs(random()) % 26 AS colc,random() % 26 AS cold,random() % 26 AS cole,random() % 26 AS colf,random() % 26 AS colg 
    FROM counter LIMIT 3000
)
INSERT INTO original_table SELECT * FROM counter;
SELECT * FROM original_table ORDER BY C ASC; -- Query 1 the original original_table

-- Create the secondary table by extracting values from the C column of the original table
DROP TABLE IF EXISTS secondary_table;
CREATE TABLE IF NOT EXISTS secondary_table (id INTEGER PRIMARY KEY, c_value TEXT);
INSERT INTO secondary_table (c_value) SELECT DISTINCT C FROM original_table ORDER BY C ASC;
SELECT * FROM secondary_table; -- Query 2 the new secondary table

-- Add the new column as a Foreign key to reference the new secondary_table
ALTER TABLE original_table ADD COLUMN secondary_table_reference INTEGER REFERENCES secondary_table(id);
SELECT * FROM original_table; -- Query 3 the altered original_table but without any references

-- Update the original table to apply the references to the secondary_table
UPDATE original_table 
    SET secondary_table_reference = (SELECT id FROM secondary_table WHERE c_value = C)
    -- >>>>>>>>>> NOTE USE ONLY 1 OR NONE OF THE FOLLOWING 2 LINES <<<<<<<<<< 
    , C = null; -- OPTIONAL TO CLEAR COLUMN C
    -- , C = (SELECT id FROM secondary_table WHERE c_value = C) -- ANOTHER OPTION SET C TO REFERENCE SECONDARY TABLE
;
SELECT * FROM original_table; -- Query 4 the final original table i.e. with references applied (column C now not needed)
  • 希望评论可以解释。

结果:-

查询1没有辅助表的原始表:-

enter image description here

查询2从原始表生成的辅助表:-

enter image description here

查询3更改后的original_table,但未应用引用:-

enter image description here

查询4应用引用后的原始表(应用于新列和旧C列):-

enter image description here

时间 (显然取决于许多因素):-

-- Create the original table with column c having a finite number of values (0-25)
DROP TABLE IF EXISTS original_table
> OK
> Time: 0.94s


CREATE TABLE IF NOT EXISTS original_table (A TEXT, B TEXT, C TEXT, D TEXT, E TEXT, F TEXT, G TEXT)
> OK
> Time: 0.353s


-- Load the original table with some data
WITH RECURSIVE counter(cola,colb,colc,cold,cole,colf,colg) AS (
    SELECT random() % 26 AS cola, random() % 26 AS colb,abs(random() % 26) AS colc,random() % 26 AS cold,random() % 26 AS cole,random() % 26 AS colf,random() % 26 AS colg 
    UNION ALL 
    SELECT random() % 26 AS cola, random() % 26 AS colb,abs(random()) % 26 AS colc,random() % 26 AS cold,random() % 26 AS cole,random() % 26 AS colf,random() % 26 AS colg 
    FROM counter LIMIT 3000
)
INSERT INTO original_table SELECT * FROM counter
> Affected rows: 3000
> Time: 0.67s


SELECT * FROM original_table ORDER BY C ASC
> OK
> Time: 0.012s


-- Query 1 the original original_table

-- Create the secondary table by extracting values from the C column of the original table
DROP TABLE IF EXISTS secondary_table
> OK
> Time: 0.328s


CREATE TABLE IF NOT EXISTS secondary_table (id INTEGER PRIMARY KEY, c_value TEXT)
> OK
> Time: 0.317s


INSERT INTO secondary_table (c_value) SELECT DISTINCT C FROM original_table ORDER BY C ASC
> Affected rows: 26
> Time: 0.24s


SELECT * FROM secondary_table
> OK
> Time: 0s


-- Query 2 the new secondary table

-- Add the new column as a Foreign key to reference the new secondary_table
ALTER TABLE original_table ADD COLUMN secondary_table_reference INTEGER REFERENCES secondary_table(id)
> OK
> Time: 0.31s


SELECT * FROM original_table
> OK
> Time: 0.01s


-- Query 3 the altered original_table but without any references

-- Update the original table to apply the references to the secondary_table
UPDATE original_table 
    SET secondary_table_reference = (SELECT id FROM secondary_table WHERE c_value = C)
    -- , C = null; -- OPTIONAL TO CLEAR COLUMN C
    , C = (SELECT id FROM secondary_table WHERE c_value = C)
> Affected rows: 3000
> Time: 0.743s


SELECT * FROM original_table
> OK
> Time: 0.01s


-- Query 4 the final original table i.e. with references applied (column C now not needed)
> not an error
> Time: 0s

补充查询

以下查询使用组合表:-

SELECT A,B,D,E,F,G, secondary_table.c_value FROM original_table JOIN secondary_table ON secondary_table_reference = secondary_table.id; 

得出结果:-

enter image description here

  • 注意 数据将与以前的结果不相关,因为它是作为单独的运行运行的,并且数据是随机生成的。 < / li>