我正在使用这个SQLite Plugin作为移动应用程序,受益于“无限”存储限制。基本上我有 base64 imagedata
并且需要将其存储在数据库中。
此外,我还有一些其他表和一个主数据,其中存储主键以及一些附加信息,例如 albumName
。
使用外键的关系设置
为了处理数据库的关系方面,我最初使用外键声明并创建如下表(为简单起见,仅显示两个表):
// Master Data
$cordovaSQLite.execute(db,
"CREATE TABLE IF NOT EXISTS \
Masterdata(\
id TEXT primary key, \
albumName TEXT, \
favorite INTEGER\
)"
)
// Images
$cordovaSQLite.execute(db,
"CREATE TABLE IF NOT EXISTS \
ImagesData(\
id TEXT, \
data BLOB, \
FOREIGN KEY(id) REFERENCES Masterdata(id)\
)"
)
然后,当我只想加载特定相册的图像时,我运行查询:
SELECT Masterdata.id, ImagesData.data FROM ImagesData, Masterdata WHERE Masterdata.album = (?) ["Some album name"]
这工作得很好(一切都按预期加载),但是我立即注意到在处理大型数据集时它会变慢。这是有道理的,因为 base64 字符串的存储空间很大。
将 Blob 存储在单独的表中
所以我读了这个post ,如果您的数据包含 BLOB,建议考虑将每个 BLOB 存储在单独的表中。
我的编码如下:
// tableName in the form of 'id'_imagesData
// 'id' is stored also in Masterdata
$cordovaSQLite.execute(db,
"CREATE TABLE IF NOT EXISTS "
+ tableName + "(id integer, data BLOB)"
);
然后我使用查询将数据插入到该表中:
"INSERT INTO " + tableName + " (id, data) VALUES (?,?)", parameters
// parameters = [0, base64_imageData_Str]
结果
结果是,我注意到加载时间显着增加,即使存储了多个图像(因此具有多个表)。在我看来,这是有道理的,因为我们可以使用主数据来过滤掉所选相册的id
,然后只加载一张表中的图像。
我的问题是:
- 这是一个坏的、好的还是好的做法?
- 拥有大量表格是否有缺点(例如,如果我有 1000 张图像,则采用此设置我将拥有 1000 个表格)
- 如果这是不好的做法,更好的推荐方法是什么?
最佳答案
将每个 blob 存储在自己的表中绝对是不的方法。我认为这篇文章推荐您的第一种方法,这应该没问题,只是您的查询是错误的。
SELECT Masterdata.id, ImagesData.data
FROM ImagesData, Masterdata
WHERE Masterdata.album = 'some name'
这会将 Masterdata
中的一行与 ImagesData
中的每一行连接起来,即使 ImageData
没有属于主数据
。您需要添加连接条件:
...
WHERE Masterdata.album = 'some name' AND ImageData.id = Masterdata.id
或者更好的是,使用显式连接语法:
SELECT Masterdata.id, ImagesData.data
FROM Masterdata
INNER JOIN ImagesData ON ImagesData.id = Masterdata.id
WHERE Masterdata.album = 'some name'
还要确保 Masterdata.id
和 ImagesData.id
具有索引。
关于javascript - 使用 SQLite 将 Blob 存储在单独的表中?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29494315/