将数组存储在另一个表中引用的SQLite中

时间:2014-05-02 18:46:55

标签: arrays sqlite reference foreign-keys primary-key

我试图在SQLite数据库中存储数据的数组(或向量),但是我在尝试找到一个合适的方法时遇到了问题。我在StackOverflow上发现了一些其他帖子,我似乎无法找到它,它提到将数据存储在如下表中:

CREATE TABLE array_of_points
(
    id integer NOT NULL,
    position integer NOT NULL,
    x integer NOT NULL,
    y integer NOT NULL,
    PRIMARY KEY (id, position)
);

因此,要存储单个数组的所有数据,您可以在相同的ID下插入每个项目,然后只增加位置。因此,例如,要插入具有三个值的数组,它将类似于:

INSERT INTO array_of_points VALUES (0, 0, 1, 1);
INSERT INTO array_of_points VALUES (0, 1, 2, 2);
INSERT INTO array_of_points VALUES (0, 2, 3, 3);

然后要检索值,您将选择具有相同ID的所有内容并按位置排序:

SELECT x,y FROM array_of_points WHERE id = 0 ORDER BY position;

这一切都很棒并且效果非常好,但我现在遇到的问题是我不知道如何在不同的表中引用数组。例如,我想做类似以下的事情:

CREATE TABLE foo
(
    id integer NOT NULL,
    array_id integer NOT NULL,
    PRIMARY KEY (id),
    FOREIGN KEY (array_id) REFERENCES array_of_points (id)
);

这将创建表格,但是一旦您尝试对其执行查询,外键约束就会引发错误,因为它必须引用{{1}的idposition } table,因为它们是复合主键的一部分。

我目前唯一的解决方案就是从array_of_points表中删除外键,但这不是一个好的解决方案,因为它意味着它现在可以保留任何值,即使它实际上并不是映射到foo表中的数组。

有什么方法可以解决这个问题吗?或者可能还有其他一些方法来存储数据以便这可能吗?

正如一个FYI,请不要建议我将数据存储在某种逗号/分号/任何分隔列表中,因为这是一个更糟糕的选择,我不会考虑。对于将要存储在数据库中的一些更复杂的对象也是不可能的。

1 个答案:

答案 0 :(得分:2)

此架构无法处理一种特殊情况:无法存储大小为零的数组。 这在实践中可能不是一个问题,但它表明数据库没有完全标准化。

外键始终引用单个父记录。 因此,缺少的是每个数组都有一条记录的表。 实现这个将导致这样的模式:

CREATE TABLE array
(
    id integer PRIMARY KEY
    -- no other properties
);
CREATE TABLE array_points
(
    array_id integer REFERENCES array(id),
    position integer,
    x, y, [...],
    PRIMARY KEY (array_id, position)
) WITHOUT ROWID; -- see http://www.sqlite.org/withoutrowid.html
CREATE TABLE foo
(
    [...],
    array_id integer REFERENCES array(id)
);

附加表需要更多的管理工作,但现在您可以通过自动增量生成数组ID。