跳转到内容

结构化查询语言/示例数据库数据

来自维基教科书,开放世界中的开放书籍



rDBMS 提供了将数据放入其存储的不同方式:来自 CSV 文件、Excel 文件、特定产品的二进制文件,通过几个 API 或通往其他数据库的特殊网关,以及其他一些技术。因此,将数据引入我们系统的方法有很多种,但并不标准。由于我们谈论的是 SQL,因此我们使用标准化的 INSERT 命令来完成此工作。它在所有系统上都可用。

我们只使用少量数据,因为我们想让事情变得简单。有时需要大量行来进行性能测试。为此,我们在本页末尾展示了一个特殊的 INSERT 命令,它会使您的表指数级增长。

--
-- After we have done a lot of tests we may want to reset the data to its original version.
-- To do so, use the DELETE command. But be aware of Foreign Keys: you may be forced to delete
-- persons at the very end - with DELETE it's just the opposite sequence of tables in comparison to INSERTs.
-- Be careful and don't confuse DELETE with DROP !!
--
-- DELETE FROM person_hobby;
-- DELETE FROM hobby;
-- DELETE FROM contact;
-- DELETE FROM person;
-- COMMIT;

INSERT INTO person VALUES (1,  'Larry',  'Goldstein', DATE'1970-11-20', 'Dallas',        '078-05-1120', 95);
INSERT INTO person VALUES (2,  'Tom',    'Burton',    DATE'1977-01-22', 'Birmingham',    '078-05-1121', 75);
INSERT INTO person VALUES (3,  'Lisa',   'Hamilton',  DATE'1975-12-23', 'Richland',      '078-05-1122', 56);
INSERT INTO person VALUES (4,  'Kim',    'Goldstein', DATE'2011-06-01', 'Shanghai',      '078-05-1123', 11);
INSERT INTO person VALUES (5,  'James',  'de Winter', DATE'1975-12-23', 'San Francisco', '078-05-1124', 75);
INSERT INTO person VALUES (6,  'Elias',  'Baker',     DATE'1939-10-03', 'San Francisco', '078-05-1125', 55);
INSERT INTO person VALUES (7,  'Yorgos', 'Stefanos',  DATE'1975-12-23', 'Athens',        '078-05-1126', 64);
INSERT INTO person VALUES (8,  'John',   'de Winter', DATE'1977-01-22', 'San Francisco', '078-05-1127', 77);
INSERT INTO person VALUES (9,  'Richie', 'Rich',      DATE'1975-12-23', 'Richland',      '078-05-1128', 90);
INSERT INTO person VALUES (10, 'Victor', 'de Winter', DATE'1979-02-28', 'San Francisco', '078-05-1129', 78);
COMMIT;

请注意,DATE 的格式可能取决于您的本地环境。此外,SQLite 对字符串到 DATE 的隐式转换使用不同的语法。

-- SQLite syntax
INSERT INTO person VALUES (1,  'Larry',  'Goldstein', DATE('1970-11-20'), 'Dallas',      '078-05-1120', 95);
...
-- DELETE FROM contact;
-- COMMIT;

INSERT INTO contact VALUES (1,  1,  'fixed line', '555-0100');
INSERT INTO contact VALUES (2,  1,  'email',      '[email protected]');
INSERT INTO contact VALUES (3,  1,  'email',      'lg@my_company.xx');
INSERT INTO contact VALUES (4,  1,  'icq',        '12111');
INSERT INTO contact VALUES (5,  4,  'fixed line', '5550101');
INSERT INTO contact VALUES (6,  4,  'mobile',     '10123444444');
INSERT INTO contact VALUES (7,  5,  'email',      '[email protected]');
INSERT INTO contact VALUES (8,  7,  'fixed line', '+30000000000000');
INSERT INTO contact VALUES (9,  7,  'mobile',     '+30695100000000');
COMMIT;
-- DELETE FROM hobby;
-- COMMIT;

INSERT INTO hobby VALUES (1,  'Painting',
                              'Applying paint, pigment, color or other medium to a surface.');
INSERT INTO hobby VALUES (2,  'Fishing',
                              'Catching fishes.');
INSERT INTO hobby VALUES (3,  'Underwater Diving',
                              'Going underwater with or without breathing apparatus (scuba diving / breath-holding).');
INSERT INTO hobby VALUES (4,  'Chess',
                              'Two players have 16 figures each. They move them on an eight-by-eight grid according to special rules.');
INSERT INTO hobby VALUES (5,  'Literature', 'Reading books.');
INSERT INTO hobby VALUES (6,  'Yoga',
                              'A physical, mental, and spiritual practices which originated in ancient India.');
INSERT INTO hobby VALUES (7,  'Stamp collecting',
                              'Collecting of post stamps and related objects.');
INSERT INTO hobby VALUES (8,  'Astronomy',
                              'Observing astronomical objects such as moons, planets, stars, nebulae, and galaxies.');
INSERT INTO hobby VALUES (9,  'Microscopy',
                              'Observing very small objects using a microscope.');
COMMIT;

person_hobby

[编辑 | 编辑源代码]
-- DELETE FROM person_hobby;
-- COMMIT;

INSERT INTO person_hobby VALUES (1, 1, 1);
INSERT INTO person_hobby VALUES (2, 1, 4);
INSERT INTO person_hobby VALUES (3, 1, 5);
INSERT INTO person_hobby VALUES (4, 5, 2);
INSERT INTO person_hobby VALUES (5, 5, 3);
INSERT INTO person_hobby VALUES (6, 7, 8);
INSERT INTO person_hobby VALUES (7, 4, 4);
INSERT INTO person_hobby VALUES (8, 9, 8);
INSERT INTO person_hobby VALUES (9, 9, 9);
COMMIT;

对于现实的性能测试,我们需要大量的数据。我们示例数据库中的几行数据无法满足此标准。我们如何生成测试数据并将其存储在表中?有不同的可能性:存储过程中的 FOR 循环、(伪)递归调用、以系统特定方式导入外部数据等等。

由于我们正在处理 SQL,因此我们引入了一个 INSERT 命令,它可以移植到所有 rDBMS。尽管它语法简单,但功能强大。每次执行时,它都会将行数加倍。假设表中有一行。执行完第一个命令后,表中就会有第二行。乍一看,这听起来很无聊。但是执行 10 次后,就会有超过一千行,执行 20 次后就会有超过一百万行,我们怀疑只有少数安装可以执行超过 30 次。

INSERT INTO person (id,                                firstname, lastname, weight)
SELECT              id + (select max(id) from person), firstname, lastname, weight
FROM        person;
COMMIT;

该命令是一个 INSERT 命令,与一个(子)SELECT 命令结合使用。SELECT 命令检索表的全部行,因为它没有 WHERE 子句。这就是行数加倍的原因。强制列 firstnamelastname 保持不变。我们忽略可选列。只有主键 id 被计算。新值是旧值加上执行命令时可用的最大 id 的总和。

一些额外的说明

  • max(id) 每执行一次只确定一次!这说明了 rDBMS 的一个重要方面:在概念层面上,数据库在执行命令之前有一个特定的状态,在执行命令之后有一个新的状态。命令是将数据库从一种状态转移到另一种状态的原子操作 - 它们要么全部执行,要么完全不执行!SELECT 和带有 max(id) 的内部 SELECT 都作用于初始状态。它们永远不会看到 INSERT 的结果或中间结果。否则,INSERT 永远不会结束。
  • 如果我们希望观察增长的过程,可以在表中添加一列,以存储每次迭代时的 max(id)。
  • 如果 DBMS 支持 AUTOINCREMENT 列,则可以省略新 id 的计算。
  • 对于性能测试,将一些随机数据存储在一列或多列中可能会有所帮助。


华夏公益教科书