鉴于需要存储4位随机唯一整数,我将如何高效地插入大量高质量的新数字。
如果这些值是在sqlite外部创建的,则有可能该值已经存在于数据库中
完成这项任务的最佳方法是什么?
答案 0 :(得分:0)
您可以使要存储数字的列唯一,并在具有多个值的单插入中使用INSERT或IGNORE(以提高效率)。例如:-
INSERT OR IGNORE INTO rndm_id VALUES
('0001'),('0027'),('9999'),('0412'),('2108'),
('0001'), -- duplicate will be skipped
('3085') -- and so on
;
注释值已包含在引号中,以维护4个数字。该表是使用:-
定义的CREATE TABLE IF NOT EXISTS rndm_id (myid TEXT UNIQUE);
如果您考虑大量值,则可能需要考虑:-
SQL语句的最大长度
SQL语句文本中的最大字节数受到限制 设置为SQLITE_MAX_SQL_LENGTH,默认值为1000000。您可以重新定义 此限制与SQLITE_MAX_LENGTH中的较小者一样大,并且 1073741824。
如果SQL语句的长度限制为一百万个字节,则 显然,您将无法通过插入几百万个字节的字符串 将它们作为文字嵌入INSERT语句中。但是你应该 无论如何不要这样做。对数据使用主机参数。准备短片 这样的SQL语句:
INSERT INTO tab1 VALUES(?,?,?);然后使用sqlite3_bind_XXXX() 函数将大字符串值绑定到SQL语句。的 使用绑定消除了在转义符中转义引号字符的需要 字符串,降低SQL注入攻击的风险。它也运行 更快,因为不需要将大字符串解析或复制为 很多。
SQL语句的最大长度可以在运行时降低 使用sqlite3_limit(db,SQLITE_LIMIT_SQL_LENGTH,size)接口。 Limits In SQLite
考虑评论
有没有办法我可以选择一组新值呢? 可以使用,然后稍后插入?
因此,假设您需要1000个4位数的唯一随机值,则以下内容就足够了:-
DROP TABLE IF EXISTS save_for_later; -- Drop the table
CREATE TEMP TABLE IF NOT EXISTS save_for_later (four_digit_random_value UNIQUE); -- Create a temporary table
-- Create a table with 1500 random rows
WITH RECURSIVE cte1 AS (
SELECT CAST((abs(random() % 10)||abs(random() % 10)||abs(random() % 10)||abs(random() % 10)) AS TEXT)
UNION ALL SELECT CAST((abs(random() % 10)||abs(random() % 10)||abs(random() % 10)||abs(random() % 10)) AS TEXT)
FROM cte1 LIMIT 1500
)
INSERT OR IGNORE INTO save_for_later SELECT * FROM cte1;
-- Later on extract the 1000 required rows.
SELECT * FROM save_for_later LIMIT 1000;
如果问题是 我如何才能将具有随机数据的一组固定数量(300)4个数字唯一值插入到具有现有数据的表(主数据)中,新值也应与现有值
然后,以下方法可以做到这一点(请参阅注释限制):-
DROP TABLE IF EXISTS master; --
CREATE TABLE IF NOT EXISTS master (random_value TEXT UNIQUE);
-- Master (existing) Table populated with some values
INSERT OR IGNORE INTO master VALUES
('0001'),('0027'),('9999'),('0412'),('2108'),
('0001'), -- duplicate will be skipped
('3085') -- and so on
;
SELECT * FROM master; -- Result 1 show what's in the master table
-- Create a table to save the values for later
DROP TABLE IF EXISTS save_for_later; -- Drop the table
CREATE TEMP TABLE IF NOT EXISTS save_for_later (four_digit_random_value UNIQUE); -- Create a temporary table
-- Populate the vales to be saved for later excluding any values that already exist
-- 1500 rows perhaps excessive but very likely to result in 300 unique values
WITH RECURSIVE cte1(rndm) AS (
SELECT
CAST((abs(random() % 10)||abs(random() % 10)||abs(random() % 10)||abs(random() % 10)) AS TEXT)
UNION ALL
SELECT
CAST((abs(random() % 10)||abs(random() % 10)||abs(random() % 10)||abs(random() % 10)) AS TEXT)
FROM cte1
LIMIT 1500 --<<<<<< LIMIT important otherwise would be infinite
)
INSERT OR IGNORE INTO save_for_later
SELECT * FROM cte1
WHERE rndm NOT IN(SELECT * FROM master)
;
-- Later on extract the required rows (300 here) and insert them.
INSERT INTO master
SELECT * FROM save_for_later
LIMIT 300;
SELECT * FROM master; -- Should be 6 original/existing rows + 300 so 306 rows (although perhaps a chance that 300 weren't generated)
以上将导致:-
第一个结果是生成新值之前的主表:-
添加新值(原始6行+新300行)后的结果:-