Database 在SQLite数据库列中存储对象列表是一个好主意吗?
我试图在数据库中存储大量资产。将这些存储在SQLite DB列中的列表中是一个好主意吗?任何列表都可能包含一个集合下的数百个资产,该表如下所示: 身份证件 集合名称 签名 资产 1. 宾格斯收集 hY3u [资产1、资产2、资产3] 2. 皇家铸币厂 8xQ2 [资产1、资产2、资产3] 我这样做会失去任何功能吗 是(至少在简单性方面,如果忽略复杂性,可能不会) 我可以在数据库中查询列表并搜索特定项目吗 是的,但也许没有那么有效 将这些存储在SQLite DB列中的列表中是一个好主意吗? 我认为可能不会,因为事情可能很容易变得复杂,有些人会指出数据没有正常化 我是否应该放弃这种方法,尝试其他方法 <> P>而不是说你应该,也许考虑规范化,从而利用SQLite的关系方面。下面的示例显示了如何对数据进行规范化,这可能有助于减少存储资源,而且即使使用关系可能看起来更复杂,但管理列中列表的复杂性很容易会变得更复杂 正如您所拥有的,您可以将单个表定义为:-Database 在SQLite数据库列中存储对象列表是一个好主意吗?,database,sqlite,Database,Sqlite,我试图在数据库中存储大量资产。将这些存储在SQLite DB列中的列表中是一个好主意吗?任何列表都可能包含一个集合下的数百个资产,该表如下所示: 身份证件 集合名称 签名 资产 1. 宾格斯收集 hY3u [资产1、资产2、资产3] 2. 皇家铸币厂 8xQ2 [资产1、资产2、资产3] 我这样做会失去任何功能吗 是(至少在简单性方面,如果忽略复杂性,可能不会) 我可以在数据库中查询列表并搜索特定项目吗 是的,但也许没有那么有效 将这些存储在SQLite DB列中的列表中是一个好主意吗? 我认为
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.每个集合资产组合的一行,这可能会令人困惑。但是,下一个查询更类似于第一个查询(但显示每个集合有多少资产(如果没有关系,则不太容易))
/* 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')