考虑到需要存储 4 位随机唯一整数,我将如何有效插入高质量的新数字。
如果这些值是在 sqlite 之外创建的,则该值可能已经存在于数据库中
执行此类任务的最佳方法是什么?
您可以将存储数字的列设为唯一,并在具有多个值的 SINGLE INSERT 上使用 INSERT OR 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 语句:
插入 tab1 值(?,?,?);然后使用 sqlite3_bind_XXXX() 函数将大字符串值绑定到 SQL 语句。绑定的使用避免了对字符串中的引号字符进行转义的需要,从而降低了 SQL 注入攻击的风险。由于不需要分析或复制大字符串,因此运行速度也更快。
可以在运行时使用 sqlite3_limit(db,SQLITE_LIMIT_SQL_LENGTH,size) 接口降低 SQL 语句的最大长度。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 行):-
本文收集自互联网,转载请注明来源。
如有侵权,请联系[email protected] 删除。
我来说两句