Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/database/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Database 在SQLite数据库列中存储对象列表是一个好主意吗?_Database_Sqlite - Fatal编程技术网

Database 在SQLite数据库列中存储对象列表是一个好主意吗?

Database 在SQLite数据库列中存储对象列表是一个好主意吗?,database,sqlite,Database,Sqlite,我试图在数据库中存储大量资产。将这些存储在SQLite DB列中的列表中是一个好主意吗?任何列表都可能包含一个集合下的数百个资产,该表如下所示: 身份证件 集合名称 签名 资产 1. 宾格斯收集 hY3u [资产1、资产2、资产3] 2. 皇家铸币厂 8xQ2 [资产1、资产2、资产3] 我这样做会失去任何功能吗 是(至少在简单性方面,如果忽略复杂性,可能不会) 我可以在数据库中查询列表并搜索特定项目吗 是的,但也许没有那么有效 将这些存储在SQLite DB列中的列表中是一个好主意吗? 我认为

我试图在数据库中存储大量资产。将这些存储在SQLite DB列中的列表中是一个好主意吗?任何列表都可能包含一个集合下的数百个资产,该表如下所示:

身份证件 集合名称 签名 资产 1. 宾格斯收集 hY3u [资产1、资产2、资产3] 2. 皇家铸币厂 8xQ2 [资产1、资产2、资产3] 我这样做会失去任何功能吗

是(至少在简单性方面,如果忽略复杂性,可能不会)

我可以在数据库中查询列表并搜索特定项目吗

是的,但也许没有那么有效

将这些存储在SQLite DB列中的列表中是一个好主意吗? 我认为可能不会,因为事情可能很容易变得复杂,有些人会指出数据没有正常化

我是否应该放弃这种方法,尝试其他方法

<> P>而不是说你应该,也许考虑规范化,从而利用SQLite的关系方面。下面的示例显示了如何对数据进行规范化,这可能有助于减少存储资源,而且即使使用关系可能看起来更复杂,但管理列中列表的复杂性很容易会变得更复杂

正如您所拥有的,您可以将单个表定义为:-

CREATE TABLE IF NOT EXISTS collection1 (id INTEGER PRIMARY KEY, collection_name TEXT, signature TEXT, assets TEXT);
INSERT INTO collection1 VALUES
    (1, 'BingusCollection','hY3u','[asset1, asset2, asset3]')
    ,(2,'RoyalMintBrilliant','8xQ2','[asset1, asset2, asset3]')
    ,(3,'Another','4ZUT','[asset4]')
    ,(4,'AndAnother','1af3','[asset4],[asset5]')
    ,(5,'somethingelse','gb2v','[asset1asset2asset3asset4asset5]')
;
SELECT * FROM collection1;
SELECT * FROM collection1 
    WHERE instr(assets,'asset5') /* would find asset50 etc */ 
    OR instr(assets,'asset1') /* would find asset10 etc */;
第一个查询很好,显示:-

然而,第二个查询(我是否能够查询数据库中的列表并搜索特定项目?)显示了一个复杂度逐渐增加的问题。i、 e.您正在资产列表中搜索包含asset1或asset5的行,但您得到的somethingelse集合包含资产asset1asset2asset3asset4asset5(即,在资产名称中包含asset1和asset5)。可以进行分离列表,但其复杂程度如下:-

现在考虑引入关系并将数据库拆分为更小的组件。CollectionName显然属于该集合。它有一个名称,我猜签名也有。但是,一个资产是一个单独的东西,所以它是另一个表的候选对象,特别是当一个资产(例如asset1)似乎能够在多个集合中,并且一个集合可以有多个资产时。因此,存在着许多关系

你可以把关系比作一本有书页、章节等的书,如果你被告知要看第x页,你可以很容易地找到那一页。您已经遇到了唯一标识行的Id。这些可以像页码一样使用

因此,一个关系可以是一个id到另一个id,这非常适合一个一个关系(如果需要的话)和一个多个关系。多对多可以使用id,但也可以使用另一个表(映射表、关联表、参考表……)。这样的表每行有两个id,一个指向关系的一个表,另一个指向另一个表

因此,也许更好的解决方案(如您所见)是为集合创建一个表,为资产创建一个表,并为集合和资产之间的许多关系创建一个映射表

因此,请考虑下面的三个表:-< /P>

CREATE TABLE IF NOT EXISTS collection2 (id INTEGER PRIMARY KEY, collection_name TEXT, signature TEXT);
CREATE TABLE IF NOT EXISTS asset (id INTEGER PRIMARY KEY, assetdetails);
CREATE TABLE IF NOT EXISTS collection2_asset_map (
    collection2id REFERENCES collection2(id) ON DELETE CASCADE ON UPDATE CASCADE,
    assetid REFERENCES asset(id) ON DELETE CASCADE ON UPDATE CASCADE, PRIMARY KEY(collection2id, assetid)
    ) WITHOUT ROWID;
  • 外键(“引用”)定义了表示关系必须有效(引用完整性)的规则。也就是说,存储在子项列中的值必须是父项中存在的值(在删除时,如果删除父项,级联将删除子项(ren)(可以使生活更轻松))

    • 外键不是必需的
要加载加载到单个表中的等效数据,可以使用以下方法:-

/* Add the same collections as above*/
INSERT INTO collection2 VALUES
    (1,'BingusCollection','hY3u')
    ,(2,'RoyalMintBrilliant','8xQ2')
    ,(3,'Another','4ZUT')
    ,(4,'AndAnother','1af3')
    ,(5,'somethingelse','gb2v')
;

/* add the same assets as above just once per asset */
INSERT INTO asset VALUES(1,'asset1'),(2,'asset2'),(3,'asset3'),(4,'asset4'),(5,'asset5')
    ,(6,'asset1asset2asset3asset4asset5')
    ;
    
/* build the mapping table linking the collections and assets */
INSERT INTO collection2_asset_map VALUES
    (1,1),(1,3),(1,2) /* the 3 assets for the BingusCollection */
    ,(2,3),(2,2),(2,1)
    ,(3,4)
    ,(4,4),(4,5)
    ,(5,6)
;
这里有3个查询,它们使用JOIN从相关表中获取数据

/* Do the equivalent of the first query i.e. get all rows (more rows) but doesn't turn out like the first */
SELECT * FROM collection2 
    JOIN collection2_asset_map ON collection2.id = collection2_asset_map.collection2id 
    JOIN asset ON asset.id = collection2_asset_map.assetid
;
这导致:-

  • i、 e.每个集合资产组合的一行,这可能会令人困惑。但是,下一个查询更类似于第一个查询(但显示每个集合有多少资产(如果没有关系,则不太容易))
:-

现在只搜索asset5和asset1

/* Search this time the somethingelse collection is not incorrectly included */
SELECT collection_name, signature, assetdetails FROM asset
    JOIN collection2_asset_map ON asset.id = collection2_asset_map.assetid 
    JOIN collection2 ON collection2_asset_map.collection2id = collection2.id
WHERE asset.assetdetails IN('asset5','asset1')
)

/* Search this time the somethingelse collection is not incorrectly included */
SELECT collection_name, signature, assetdetails FROM asset
    JOIN collection2_asset_map ON asset.id = collection2_asset_map.assetid 
    JOIN collection2 ON collection2_asset_map.collection2id = collection2.id
WHERE asset.assetdetails IN('asset5','asset1')